向量数据库选型与实战:Milvus、Qdrant、Weaviate 和 Chroma 怎么选
从 RAG 检索链路出发,比较 Milvus、Qdrant、Weaviate 和 Chroma 的定位、适用场景、过滤能力、部署复杂度和实战选型思路。
向量数据库不是 RAG 的全部,但它通常是 RAG 系统里最先被工程化的一层。
文档切成 Chunk 之后,需要被转成向量;用户问题也需要转成向量;然后系统在向量空间里找出语义相近的片段,再交给大语言模型生成答案。这个“找相近片段”的过程,就是向量数据库最常见的用法。
如果只是做一个本地 Demo,几百段文本可以直接放在内存里算余弦相似度。但一旦文档量变大,或者需要元数据过滤、增量更新、权限控制、持久化、并发查询和监控,就需要专门的向量数据库。
2024 年 5 月,开源向量数据库里经常被拿来比较的有 Milvus、Qdrant、Weaviate 和 Chroma。它们都能做向量检索,但定位并不一样:Milvus 更偏大规模和工程化部署,Qdrant 强调向量搜索和 payload 过滤,Weaviate 把向量检索、对象存储和模块化能力放在一起,Chroma 更像是面向 LLM 应用开发者的轻量入口。
向量数据库在 RAG 里做什么
一个最小 RAG 检索链路通常长这样:
图 1:向量数据库在 RAG 中的位置
flowchart LR
subgraph 离线索引
direction TB
A[原始文档] --> B[解析清洗]
B --> C[Chunk 切分]
C --> D[Embedding 模型]
end
DB[(向量数据库)]
subgraph 在线查询
direction TB
Q[用户问题] --> F[问题向量化]
F --> G[Top-K 检索]
G --> H[重排 / 过滤 / 去重]
H --> I[组装上下文]
I --> J[LLM 生成答案]
end
D ==>|写入向量 + 文本 + Metadata| DB
DB ==>|相似度匹配 + 过滤| G
向量数据库主要负责四件事:
| 能力 | 含义 | RAG 中的例子 |
|---|---|---|
| 向量存储 | 保存 embedding 向量和原始文本引用 | 保存每个 Chunk 的向量 |
| 相似度检索 | 找出和查询向量最接近的 Top-K | 找到最相关的文档片段 |
| 元数据过滤 | 按来源、时间、权限、分类过滤 | 只查用户有权限的文档 |
| 增删改查 | 支持文档更新和索引维护 | 文档改版后更新对应 Chunk |
很多 RAG 问题看起来是“模型回答不准”,实际根因是检索层没把正确证据找出来。向量数据库选型时不能只看“能不能存向量”,还要看过滤、更新、扩展、部署和生态。
一个最小实战链路
先看一个不绑定具体数据库的流程。假设有三段文档:
doc1:企业版支持 SAML SSO,开通前需要联系客户成功经理。
doc2:标准版不支持 SSO,但可以使用邮箱验证码登录。
doc3:审计日志在企业版中保留 180 天,标准版保留 30 天。
离线写入时,需要把每段文本变成向量,并保存元数据:
items = [
{
"id": "doc1",
"text": "企业版支持 SAML SSO,开通前需要联系客户成功经理。",
"metadata": {"plan": "enterprise", "source": "auth-doc"},
},
{
"id": "doc2",
"text": "标准版不支持 SSO,但可以使用邮箱验证码登录。",
"metadata": {"plan": "standard", "source": "auth-doc"},
},
{
"id": "doc3",
"text": "审计日志在企业版中保留 180 天,标准版保留 30 天。",
"metadata": {"plan": "enterprise", "source": "audit-doc"},
},
]
在线查询时,用户问题也要向量化:
企业版怎么开通 SSO?
向量数据库返回最相近的片段,例如 doc1。如果系统还加了过滤条件:
{
"plan": "enterprise"
}
检索范围就会限制在企业版相关文档里。
这就是向量数据库实战里最常见的组合:向量相似度 + 元数据过滤。只做向量检索,容易召回语义相近但权限、版本或产品线不匹配的内容;只做关键词过滤,又容易错过同义表达。两者结合,才更接近生产系统需要的检索。
选型时先看六个问题
在比较具体产品前,先把需求说清楚。
| 问题 | 为什么重要 |
|---|---|
| 数据规模多大 | 几万、几百万、几亿向量对应不同架构 |
| 是否需要元数据过滤 | 权限、租户、时间、产品线都会影响检索 |
| 是否需要混合检索 | RAG 常需要向量检索配合关键词检索 |
| 部署环境是什么 | 本地、单机、Kubernetes、云服务复杂度不同 |
| 更新频率多高 | 文档是否频繁增删改,会影响索引维护 |
| 团队熟悉什么生态 | Python 原型、云原生部署、数据库运维经验都不同 |
如果只是一个本地知识库原型,选最轻的工具就够了。若是多租户企业知识库,选型重点就会变成过滤性能、权限边界、可观测性、备份恢复和横向扩展。
Milvus:偏大规模和工程化部署
Milvus 是专门面向向量检索的开源向量数据库,由 Zilliz 发起。它的特点是工程化能力比较完整,适合数据规模较大、部署要求较正式的场景。
Milvus 支持多种向量索引和相似度度量,也支持标量字段过滤。到 2024 年 5 月,Milvus 2.4 系列已经引入多向量和更完整的混合搜索框架,适合需要多个向量字段、多个检索路径组合的场景。
Milvus 适合这些情况:
- 向量规模较大,不只是几万条 Demo 数据。
- 团队能接受独立数据库的部署和运维。
- 需要更完整的索引、分区、集合和监控能力。
- 未来可能扩展到更高并发或更大数据量。
一个典型集合会包含向量字段和标量字段:
id: string
text: string
embedding: float_vector
source: string
created_at: int64
tenant_id: string
查询时既做向量相似度,也加过滤条件:
向量检索:找到与 query_embedding 最接近的 Top-K
过滤条件:tenant_id == "team_a" and source == "handbook"
Milvus 的代价是部署和理解成本更高。它更像一个正式数据库,而不是一个嵌入式开发库。对小团队的第一个 RAG 原型来说,Milvus 可能偏重;对长期要支撑大量向量数据的系统来说,这种重量反而是优势。
Qdrant:向量检索和 payload 过滤做得直接
Qdrant 是用 Rust 编写的向量数据库,使用体验相对直接。它把向量和 payload 放在一起,payload 可以理解为每条向量关联的结构化元数据。
在 RAG 中,payload 很重要。比如:
{
"source": "employee-handbook",
"department": "hr",
"version": "2024-05",
"access_level": "internal"
}
用户查询时,可以用 payload 条件限制召回范围。例如只查 HR 文档,只查某个版本,只查当前用户有权限访问的内容。
Qdrant 适合这些情况:
- 想要清晰的向量检索 API。
- 元数据过滤是核心需求。
- 希望部署比大型分布式数据库轻一些。
- 需要服务端模式,也希望本地开发足够顺手。
Qdrant 的过滤表达比较适合 RAG 常见场景。比如企业知识库里,用户问“年假怎么计算”,但系统必须只检索该用户所在地区、所属公司主体和当前生效版本的制度。这类场景不能只靠 embedding,因为 embedding 不知道权限和版本边界。
如果项目强调“向量 + 结构化条件”组合检索,Qdrant 通常是一个很自然的候选项。
Weaviate:向量数据库加模块化 AI 能力
Weaviate 的定位不只是“存向量并检索”。它把数据对象、向量检索、关键词检索、混合搜索和模块化能力放到同一个系统里。
Weaviate 很早就强调 hybrid search,也就是把关键词检索和向量检索结合起来。对 RAG 来说,这一点很实用。用户问题里经常同时包含语义意图和精确词:
ISO 27001 A.5 控制项怎么落地?
ISO 27001 和 A.5 是精确关键词,不能只靠语义相似;“怎么落地”又是语义意图,需要向量检索理解。混合检索比单纯向量检索更稳。
Weaviate 适合这些情况:
- 需要向量检索和关键词检索结合。
- 希望对象模型、schema 和检索能力放在一个系统里。
- 想用模块化方式接入向量化或生成能力。
- 团队接受 Weaviate 自身的数据建模方式。
Weaviate 的对象模型和 GraphQL 风格查询,对有些团队很顺手,对另一些团队则需要适应。它适合把 AI 检索作为系统核心能力来建模,而不是只把向量库当成一个简单索引。
Chroma:适合快速原型和本地 LLM 应用
Chroma 的定位更轻量,常被用于 LLM 应用原型、教程和本地开发。它和 LangChain、LlamaIndex 等框架经常一起出现。
如果你只是想快速验证一个 RAG 流程,Chroma 的使用门槛很低。你可以在本地创建 collection,写入文本、向量和 metadata,然后做相似度查询。
一个最小思路类似这样:
import chromadb
client = chromadb.PersistentClient(path="./chroma-data")
collection = client.get_or_create_collection("docs")
collection.add(
ids=["doc1"],
documents=["企业版支持 SAML SSO,开通前需要联系客户成功经理。"],
metadatas=[{"source": "auth-doc", "plan": "enterprise"}],
)
results = collection.query(
query_texts=["企业版怎么开通 SSO?"],
n_results=3,
where={"plan": "enterprise"},
)
Chroma 适合这些情况:
- 本地 Demo、教学、验证想法。
- 数据规模不大。
- 希望尽快和 LLM 应用框架接起来。
- 团队暂时不想引入复杂数据库运维。
它的优势是轻,代价也是轻。正式生产系统如果需要复杂权限、多租户、大规模扩展、严格备份恢复和高并发,需要更谨慎评估。
四个工具怎么选
可以先用一张表形成直觉:
| 选项 | 更适合 | 主要优势 | 主要代价 |
|---|---|---|---|
| Milvus | 大规模向量检索、正式工程部署 | 索引和扩展能力强,工程化成熟 | 部署和运维复杂度较高 |
| Qdrant | 向量检索 + 元数据过滤 | API 直接,payload 过滤清晰 | 复杂生态能力需自行组合 |
| Weaviate | 混合检索、对象建模、模块化 AI 能力 | 向量、关键词、对象模型结合紧密 | 建模方式需要适应 |
| Chroma | 本地原型、轻量 RAG Demo | 上手快,和 LLM 应用框架结合方便 | 大规模生产能力要谨慎评估 |
如果用一句话概括:
- 想做严肃的大规模向量检索,优先看 Milvus。
- 想要清晰的向量搜索和元数据过滤,优先看 Qdrant。
- 想把混合检索和对象模型放在一起,优先看 Weaviate。
- 想快速做本地 RAG 原型,优先看 Chroma。
图 2:选型路径
flowchart TD
Start([需要选向量数据库]) --> Q1{阶段}
Q1 -->|快速原型 / 教学 / 本地 Demo| Chroma[Chroma<br/>上手快, 和 LLM 框架结合方便]
Q1 -->|准备进生产| Q2{首要约束}
Q2 -->|千万级以上向量 + 集群运维| Milvus[Milvus<br/>索引和扩展能力强]
Q2 -->|混合检索 + 对象建模| Weaviate[Weaviate<br/>BM25 + 向量 + Schema 一体]
Q2 -->|强 Metadata 过滤 + 部署轻| Qdrant[Qdrant<br/>Rust, payload 过滤直接]
这张图不是绝对规则。实际选型还要看团队经验、云服务可用性、预算和已有架构。
实战里最容易忽略的不是数据库
向量数据库只是检索链路的一部分。很多失败案例不是数据库选错,而是前后环节没有做好。
Chunk 切分
如果文档切分太碎,检索结果会缺上下文;切分太大,向量表示会混杂多个主题。
例如这两句话最好不要切开:
企业版支持 SAML SSO。
开通前需要联系客户成功经理完成域名和证书确认。
用户问“企业版怎么开通 SSO”,如果只召回第一句,答案就不完整。
Embedding 模型
向量数据库只负责存储和检索向量,向量质量来自 embedding 模型。中文知识库如果使用中文效果较差的 embedding 模型,换数据库也很难救回来。
要用真实问题评测 embedding,而不是只看模型榜单。比如准备 50 个用户问题,标注每个问题应该命中的文档片段,再比较 Recall@5。
Metadata 设计
元数据不是附属品。RAG 系统常见字段包括:
sourcedoc_idchunk_idtitle_pathcreated_atversiontenant_idaccess_levellanguage
如果没有 tenant_id 和 access_level,后面再补权限过滤会很痛苦。如果没有 doc_id 和 chunk_id,更新和删除也会变麻烦。
Top-K 和重排
Top-K 不是越大越好。K 太小可能漏证据,K 太大会把无关内容塞进上下文。实战中常见做法是第一阶段多召回,再用 reranker 或规则重排,把更相关的片段放前面。
例如先召回 30 条,再重排选 5 条进入提示词。这样比直接拿向量 Top-5 更稳。
一个可落地的 RAG 检索架构
下面是一套比较稳妥的中小型 RAG 架构:
图 3:实战 RAG 检索架构
flowchart LR
subgraph S1[写入路径]
direction TB
W1[文档上传] --> W2[解析清洗 + Chunk]
W2 --> W3[Embedding]
end
subgraph S2[向量数据库 必备能力]
direction TB
Cap1[1 写入: 向量 + 文本 + Metadata]
Cap2[2 向量相似度检索 Top-K]
Cap3[3 Metadata 过滤<br/>租户 / 权限 / 版本]
Cap4[4 按 doc_id 删除 / 更新]
Cap5[5 返回 文本 + 来源 + 分数]
end
subgraph S3[查询路径]
direction TB
U[用户问题] --> Qr[问题改写 / 向量化]
Qr --> R[检索 + 过滤]
R --> Rk[重排 / 去重]
Rk --> Ctx[上下文组装]
Ctx --> L[LLM 生成]
L --> O[答案 + 引用]
end
M[文档改版 / 删除] -. 维护 .-> Cap4
W3 ==> Cap1
R ==> Cap2
R ==> Cap3
Cap5 ==> Rk
这套架构里,向量数据库需要支持:
- 写入向量、文本和元数据。
- 按向量相似度查询。
- 查询时加 metadata filter。
- 根据文档 ID 删除或更新旧 Chunk。
- 返回文本、来源和分数。
如果这些能力满足不了,后续生成质量很难稳定。
选型建议
个人项目或技术验证
先用 Chroma。它足够快,代码少,适合验证 chunk、embedding、检索和 prompt 的基本链路。
等到发现数据规模、并发、权限或部署变复杂,再迁移也不迟。早期不要为了“生产级”三个字牺牲迭代速度。
企业内部知识库
优先比较 Qdrant 和 Weaviate。
如果权限、部门、版本、文档类型过滤非常重要,Qdrant 的 payload 过滤会很直接。如果希望关键词检索、向量检索和对象 schema 更紧密地结合,可以看 Weaviate。
企业知识库通常不是纯语义检索。文档版本、可见范围、组织结构和精确术语都很重要。
大规模向量平台
重点看 Milvus。
如果目标是把向量数据库作为统一基础设施,为多个业务线提供检索能力,Milvus 的工程化能力更值得投入。它的部署复杂度需要运维能力支撑,但大规模场景本来也绕不开这些问题。
AI 应用 Demo 和教学
Chroma 或 Qdrant 都可以。
Chroma 更轻,适合教程和本地 Demo。Qdrant 更接近真实服务形态,适合从 Demo 过渡到小规模服务。
上线前检查表
向量数据库接入 RAG 前,可以用这张表检查:
| 检查项 | 问题 |
|---|---|
| 数据切分 | Chunk 是否包含完整语义和来源 |
| Embedding | 是否用真实问题测过 Recall@K |
| 元数据 | 是否包含权限、版本、来源、文档 ID |
| 过滤 | 查询时是否能限制租户和权限 |
| 更新 | 文档改版后旧 Chunk 是否能删除 |
| 去重 | Top-K 是否被相似重复片段占满 |
| 重排 | 是否需要 reranker 提升前排结果质量 |
| 监控 | 是否记录查询、召回分数、命中文档 |
| 备份 | 向量和原文映射是否可恢复 |
| 成本 | 存储、内存、CPU/GPU、云服务费用是否可控 |
这个检查表比单纯比较 benchmark 更实用。RAG 系统的检索质量,往往由这些细节共同决定。
小结
Milvus、Qdrant、Weaviate 和 Chroma 都能做向量检索,但适合的阶段和团队不一样。
Chroma 适合快速起步,Qdrant 适合清晰的向量检索和 metadata 过滤,Weaviate 适合把混合检索和对象模型结合起来,Milvus 适合更正式、更大规模的向量检索平台。
选型时不要只问“哪个向量数据库最好”。更具体的问题是:
- 数据量现在多大,半年后会多大?
- 是否需要按租户、权限、版本过滤?
- 是否要关键词检索和向量检索一起用?
- 团队能接受多少部署和运维复杂度?
- RAG 失败时,能不能定位是切分、embedding、过滤、召回还是生成的问题?
向量数据库选对了,RAG 不一定就准;但选型和数据设计做错了,后面再强的模型也只能在错误证据上写出流畅答案。
我是姚磊
大模型应用开发者,关注 RAG、Agent 和产品化工程。沉淀实践中的判断、踩坑记录和可复用方法。联系我:yaolei_agent@163.com



