代码语言

知识点思维导图

30 个知识节点

RAG(13) - 向量数据库

读完后,你应能完成以下任务:

  • 绘制“RAG(19) - 向量数据库 / 与进阶篇的分工”的关键对象与数据流,解释“继续阅读 Milvus(01) - Schema、索引、过滤与版本 和 Milvus(02) - 电子书离线建库与引用问答;”,并用源码位置、日志或 Trace 标注证据。
  • 为“RAG(19) - 向量数据库 / 它存什么:向量 + 原文 + 元数据”设计正常与异常输入,验证“vector 是检索的依据,但它不可读,所以必须连原文一起存;”,输出首个偏差位置与回归测试结果。
  • 实现“RAG(19) - 向量数据库 / 它做什么:add 和 search 两个核心操作”的最小代码或配置,检验“所以真实向量库不这么干。”,输出命令、结果与 Diff,并说明不适用边界。

一句话目标:读完你能讲清向量数据库到底存什么、做什么,知道它和普通数据库的区别,并能说出它内部「检索」是怎么回事。

一、与进阶篇的分工

本篇只负责讲清向量、原文、元数据和 ANN 在 RAG 中的职责。 需要落到专用向量库时, 继续阅读 Milvus(01) - Schema、索引、过滤与版本Milvus(02) - 电子书离线建库与引用问答; RAG 主线不再复制同一套 Milvus 配置。

二、向量数据库的真实应用场景

知识库入库后,你手里有了几万个 chunk,每个都转成了一个 1536 维的向量。 用户来了个问题,也转成向量。 现在的任务是:从这几万个向量里,快速找出和问题向量最接近的那几个。

你可能想:存进 MySQL 不就行了? 问题是, 普通数据库擅长的是「精确匹配」——WHERE id = 5WHERE name = '张三'。 但向量检索要的是「最接近」——没有哪两个向量会完全相等,你要的是夹角最小的 topK。 MySQL 没有为这种「相似度排序」优化,几万条逐个算还能扛,几百万条就慢得没法用了。

向量数据库(Chroma、Milvus、pgvector 等)就是专门干这件事的:存海量向量, 并能很快地找出和查询向量最相近的若干个。

三、它存什么:向量 + 原文 + 元数据

一条向量库记录通常包含三部分,缺一不可:

{
  "vector":   [0.21, -0.07, ...],        # 向量,用来算相似度
  "text":     "报销需在 30 天内提交",     # 原文,检索到后要拼进 prompt 给模型
  "metadata": {"source": "财务手册",     # 元数据,用来做引用来源和过滤
               "doc_id": 12, "dept": "finance"}
}
  • vector 是检索的依据,但它不可读,所以必须连原文一起存;
  • text 是检索命中后真正交给模型的内容;
  • metadata 有两个用途:一是生成引用来源(告诉用户答案来自《财务手册》),二是做过滤检索(比如「只在 finance 部门的文档里搜」)。

很多人只记得存向量,忘了元数据。 结果检索到了内容却说不出来自哪、也没法按权限过滤,这在企业知识库里是硬伤。

四、它做什么:add 和 search 两个核心操作

向量库的接口千变万化,核心就两个:

add(vector, text, metadata)    入库:把一条记录存进去
search(query_vector, top_k)    检索:找出和 query_vector 最相近的 top_k 条

search 是灵魂。 最朴素的实现叫「暴力检索」:拿查询向量和库里每一条都算一次相似度,排序取 topK。 逻辑简单,但数据量一大就慢——每次查询都要扫全库。

所以真实向量库不这么干。 它们用近似最近邻(ANN)索引, 典型的是 HNSW:预先把向量组织成一张「邻居图」, 查询时顺着图走几步就能逼近最相近的那批, 不用扫全库。 代价是结果是「近似最优」而非「绝对最优」,但换来的是百倍千倍的速度,这笔账在工程上很划算。

HNSW 的检索机制是在多层邻接图上从稀疏高层快速接近目标区域,再在稠密底层扩展候选。 搜索宽度越大,Recall@K 通常越高,但 CPU 与延迟也越高; 索引连边越多,构建和内存成本也会上升。 生产选型必须用标注查询同时压测召回、P95 延迟、过滤后候选量和内存,不能只比较单次查询速度。

五、工程上真正会踩的坑(本篇独有)

  • 以为换个向量库就能提升检索效果。向量库只负责「存得下、查得快」,检索准不准取决于 embedding 模型和切分质量。库选型解决的是性能和规模,不是召回质量。
  • 入库时不存原文,只存向量。向量不可读,检索到一个向量却拿不到对应文本,等于白存。原文必须随向量一起入库。
  • 忽视元数据过滤。企业场景里「A 部门的人不能搜到 B 部门的机密文档」,靠的就是 metadata 过滤 + 向量检索结合,不是纯向量检索。建库时就要规划好要按哪些字段过滤。
  • 拿暴力检索上生产。demo 的逐条遍历几万条还行,几百万条必须上 HNSW 这类索引,否则每次查询都扫全库,延迟爆炸。

六、一句话面试答法

向量数据库和普通数据库差在哪? 普通数据库做精确匹配,向量库做相似度检索——找出和查询向量夹角最小的 topK。它存的是「向量 + 原文 + 元数据」三件套:向量用来算相似度,原文用来喂给模型,元数据用来做引用和权限过滤。数据量大时它用 HNSW 这类近似最近邻索引避免扫全库,用一点精度换巨大的速度。Chroma、Milvus、pgvector 都是常见选择。

七、动手实践:23 向量数据库

dict + list 实现一个最小向量库 MiniVectorStore, 支持 add(入库)search(检索 topK), 把向量库的内核讲清楚。

7.1 在线运行

直接使用本文“可运行源码”中的沙盒执行; 源码、复制内容和实际运行入口保持一致。

零依赖,纯标准库。

7.2 预期输出

向量库已入库 3 条记录

查询:年会什么时候开
  相似度 0.099  [活动通知] 公司年会定在每年一月的第三个周五举办
--------------------------------------------------
查询:年假有几天
  相似度 0.139  [人事制度] 年假根据工龄计算,满一年享受五天
--------------------------------------------------

入库三条资料后,两个查询各自命中了最相关的那条,并带回了元数据里的来源。 注意「年会」和「年假」只差一字,但向量库靠整体词重叠把它们区分开了。

7.3 代码↔概念对应

概念 在 main.py 哪里
文本 → 向量(这里用词频近似) embed
稀疏向量余弦相似度 cosine
向量库(list 存记录) MiniVectorStore
add:向量 + 原文 + 元数据入库 MiniVectorStore.add
search:算相似度取 topK MiniVectorStore.search
入库时就算好向量 addembed(text)

7.4 和真实向量库的差距

这个 demo 是「暴力检索」:每次 search 都和库里每条比一遍,数据量一大就慢。 真实向量库(Chroma / Milvus / pgvector)会用 HNSW 等近似最近邻索引避免全量遍历, 还支持按元数据过滤、持久化和并发。 但它们的内核都是这里的「存向量 + 算相似度取 topK」。 embed 在真实项目里换成 embedding 模型输出的稠密向量。

7.5 可运行源码:向量数据库

下方代码就是在线沙盒实际执行的完整源码。

main.py

八、总结

  • 它存什么:向量 + 原文 + 元数据:vector 是检索的依据,但它不可读,所以必须连原文一起存;
  • 工程上真正会踩的坑(本篇独有):向量库只负责「存得下、查得快」,检索准不准取决于 embedding 模型和切分质量。
  • 一句话面试答法:它存的是「向量 + 原文 + 元数据」三件套:向量用来算相似度,原文用来喂给模型,元数据用来做引用和权限过滤。
  • 工程边界:生产选型必须用标注查询同时压测召回、P95 延迟、过滤后候选量和内存,不能只比较单次查询速度。
  • 实现机制:metadata 有两个用途:一是生成引用来源(告诉用户答案来自《财务手册》),二是做过滤检索(比如「只在 finance 部门的文档里搜」)。
  • 选型依据:Chroma、Milvus、pgvector 都是常见选择。

学完自测

选择所有正确答案;提交后逐项核对判断依据。

1在“向量数据库”中,需要同时满足“与进阶篇的分工”与“向量数据库的真实应用场景”。给定正文约束“本篇只负责讲清向量、原文、元数据和 ANN 在 RAG 中的职责。”,哪些判断保持了原有处理机制?多选
2“向量数据库”出现偏差:“在“向量数据库 / 它存什么:向量 + 原文 + 元数据”中,即使不满足“vector 是检索的依据,但它不可读,所以必须连原文一起存”,结果与副作用仍会保持不变。”已成为实际行为。围绕“它存什么:向量 + 原文 + 元数据”与“它做什么:add 和 search 两个核心操作”,哪些判断能定位被改变的职责或边界?多选
3评审“向量数据库”方案时,验收条件包含“向量数据库和普通数据库差在哪? 普通数据库做精确匹配,向量库做相似度检索——找出和查询向量夹角最小的 topK。”。关于“一句话面试答法”与“动手实践:23 向量数据库”的哪些决策符合正文机制?多选