←返回文章列表

向量数据库选型与实战:Milvus、Qdrant、Weaviate 和 Chroma 怎么选

RAG向量数据库AI 应用
18 分钟-阅读

从 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 系统常见字段包括:

  • source
  • doc_id
  • chunk_id
  • title_path
  • created_at
  • version
  • tenant_id
  • access_level
  • language

如果没有 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 不一定就准;但选型和数据设计做错了,后面再强的模型也只能在错误证据上写出流畅答案。

YL

我是姚磊

大模型应用开发者,关注 RAG、Agent 和产品化工程。沉淀实践中的判断、踩坑记录和可复用方法。联系我:yaolei_agent@163.com

LLM AppsRAGProductEngineering Notes