Chroma 向量数据库实战:RAG 知识库存储选型

Chroma 向量数据库是 RAG(检索增强生成)知识库最常被选型的轻量级向量存储引擎。当你的应用需要把上万篇文档做语义检索再喂给大模型时,Chroma 向量数据库凭借嵌入式、零运维的特性成为首选。本文用真实可跑的代码,带你从安装到生产选型走完一遍。

为什么 RAG 需要专门的向量数据库

传统关系型数据库擅长精确匹配(WHERE id = 1),却算不了”语义相似”。RAG 的核心是先根据用户问题,从知识库里召回最相关的片段。这种”按意思找内容”的能力依赖向量嵌入(embedding)与近似最近邻检索(ANN),正是向量数据库的专长。关于 RAG 的整体链路,可回顾我们的Dify+Ollama 本地知识库搭建与RAG 混合检索与重排序优化两篇。

Chroma 是什么:轻量级嵌入式向量库

Chroma 的定位是”开发者身边的向量库”。它既可以以纯 Python 进程内运行(Embedded),也能以客户端/服务端模式部署。核心抽象只有三个:

  • Collection:一组向量文档的容器,相当于一张表。
  • Embedding:把文本转成高维向量的函数,默认内置 Sentence-Transformers 模型。
  • Metadata:挂在每条文档上的结构化字段,用于检索时过滤。

十分钟上手:安装与基础 CRUD

安装只需一行 pip。下面演示用持久化客户端(数据落盘到 ./chroma_db),保证重启不丢:

pip install chromadb

import chromadb

# 持久化客户端:数据保存到本地目录
client = chromadb.PersistentClient(path="./chroma_db")

# 获取或创建集合
collection = client.get_or_create_collection(
    name="kb_docs",
    metadata={"hnsw:space": "cosine"}  # 余弦相似度
)

# 写入文档(自动完成嵌入)
collection.add(
    documents=[
        "忘记密码后可通过邮箱重置链接找回账户。",
        "会员套餐每月自动续费,可在设置中关闭。",
        "API 限流为每用户每秒 10 次请求。"
    ],
    ids=["doc_1", "doc_2", "doc_3"],
    metadatas=[{"source": "faq"}, {"source": "faq"}, {"source": "api_doc"}]
)
print("当前文档数:", collection.count())

文本切分与嵌入:RAG 检索质量的关键

直接把整篇长文塞进一条 document 会让嵌入”平均化”、召回变糊。生产环境务必先做语义切分,再批量写入。下面用递归字符切分器把 Markdown 切成 500 字左右的块:

from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=80,      # 重叠避免切断语义
    separators=["\n## ", "\n", "。", ""]
)

chunks = splitter.split_text(long_markdown)
collection.add(
    documents=chunks,
    ids=[f"chunk_{i}" for i in range(len(chunks))],
    metadatas=[{"doc": "handbook", "idx": i} for i in range(len(chunks))]
)

相似度检索与 Metadata 过滤

查询时传入自然语言问题即可,Chroma 会自动嵌入并召回最相似的片段。where 参数支持按 metadata 精确过滤,where_document 则支持文档内容关键字过滤:

results = collection.query(
    query_texts=["怎么重置密码?"],
    n_results=3,
    where={"source": "faq"},          # 只在 FAQ 中检索
    include=["documents", "distances", "metadatas"]
)

for doc, dist, meta in zip(
    results["documents"][0],
    results["distances"][0],
    results["metadatas"][0]
):
    print(f"相似度={1-dist:.3f} | 来源={meta['source']} | {doc}")

存储选型对比:Chroma vs pgvector vs Milvus vs Qdrant

向量方案没有”最好”,只有”最合适”。下面是四种主流方案在 RAG 场景下的横向对比:

方案部署形态运维成本适合规模RAG 适配度
Chroma嵌入式 / 轻服务极低百万级以内★★★★★ 原型与中小知识库首选
pgvectorPostgreSQL 插件低(复用现有 PG)百万~千万★★★★ 已有 PG 栈团队
Milvus分布式集群高十亿级★★★★ 超大规模生产
QdrantRust 服务中千万级★★★★ 高并发 + 强过滤

生产落地建议

  • 中小知识库 / 快速验证:直接用 Chroma 嵌入式,几天就能跑通 RAG,参考大模型 Function Calling 工具调用把检索结果喂给 Agent。
  • 已用 PostgreSQL:优先 pgvector,省去一套独立存储的运维心智。
  • 亿级文档 / 多租户:上 Milvus 或 Qdrant,配合前文提到的重排序提升精度。
  • 永远做切分与过滤:chunk_size 控制在 300–800 字,metadata 过滤能显著降低噪声。

总结

Chroma 向量数据库以”开箱即用、零运维”降低了 RAG 知识库的入门门槛,是绝大多数团队做语义检索的第一站。当数据规模或并发要求超过它的承载能力,再平滑迁移到 pgvector / Milvus / Qdrant 即可。记住:向量库只是 RAG 的一环,切分策略、嵌入模型与重排序共同决定了最终效果。

上一篇 Java 并发实战:线程池调优与异步编排
下一篇 Nginx 限流防刷实战:漏桶算法与 WAF 基础配置
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]