跳到主要内容

向量检索与向量库 — 「找最像的」怎么做到毫秒级

这一章讲三件事: 「这两段文字像不像」怎么变成一个算术题; 库里有一百万段文字时,怎么不算一百万次就找出最像的几段; 以及「向量库」为什么不只是「存向量的库」。 读完你就掌握了查询流的第一半——从问题到候选块。

1. 顶层全景:查询流的前半程

第 01 章的查询流,到这里可以展开前三站1:

用户问题

▼ (可选)改写查询 —— 第 06 章
▼ ① 嵌入:问题也过同一台嵌入模型,变成一串数字
▼ ② 相似搜索:在向量库里找「数字距离最近」的 k 块
▼ ③ (规模化时加)混合搜索与重排 —— 第 08 章

候选块交给生成模型 —— 第 06 章

图说:本章管 ①②。主走查沿用上一章的四个句子:
「happy / joyful / pessimistic / not optimistic」,
看它们入库之后,一次查询怎么把它们排出来。

2. 核心原理(一):「像不像」是一道算术题

上一章的嵌入把每段文字变成 384 个浮点数。「两段文字多像」现在就变成了 「两串数多接近」。怎么算接近?点积(dot product,也叫内积): 把两串数对应位置相乘再全部加起来。直觉是:两个向量在同样的方向上「分量」都大, 乘积就一项项地互相放大,总和就高——方向越一致,点积越大2

点积有个毛病:向量越长(不管方向)点积也会越大。于是先做个归一化—— 把每根向量的长度缩放到 1(向量的「长度」指各分量的平方和开根号,即它的模长)。 归一化之后的点积,就是你可能听说过的余弦相似度(cosine similarity): 几何上等于两根向量夹角的余弦,方向完全重合是 1,完全无关约 0,相反是 -13

GPU(图形显卡,擅长一次做大量乘加的芯片)恰好最擅长一次性算大批点积—— 所以「算相似度」这一步在硬件上是成熟的4

主走查第 ① 步:查询进来

查询:「I am feeling joyful today」

▼ 嵌入(all-MiniLM-L6-v2,与入库时同一台)
▼ 384 维向量 q
▼ 与库里 4 根向量各算一次点积(都归一化过,所以就是余弦相似度):
「I am happy」 0.81 ← 最高,尽管查询里没有 happy 这个词
「I am joyful」 0.79
「I am pessimistic」 0.41
「I am not optimistic」 0.38
▼ 取 top-k(k=2):happy、joyful 两句出库

图说:这些分数里 0.8151 来自上一章书里的实测矩阵,其余为演示编的近似值。
注意第一名的文字与查询没有字面重合——相似度是按意思算的。

3. 核心原理(二):一百万根向量时怎么办

暴力法的天花板

上面的做法——查询向量对库里每一根都算一次——叫暴力法, 计算量随库的大小成正比增长(记作 O(n):n 根向量就约 n 次计算)。 四根向量无所谓,一百万到十亿根时,每次查询算十亿次点积,谁也等不起5。 暴力法在工程上也有正式名字:ENN(exact nearest neighbor,精确最近邻——最近的向量)或 FlatIndex6

ANN:拿一点点精度换数量级的速度

ANN(approximate nearest neighbor,近似最近邻)是几乎所有向量库的答案。 「近似」的意思是:不保证找到数学上绝对最近的那根,只保证找到足够近的7

最著名的 ANN 算法(一套明确的计算步骤)是 HNSW(Hierarchical Navigable Small World, 分层可导航小世界)。它把向量组织成一张多层图:越上层的层越稀疏, 只留少数「地标」节点,给出粗略的全局视图;越下层越稠密,细节越全。 查询时从顶层进,每层做一次「贪心」:跳到当前层里离查询最近的那个节点, 然后下到更细的一层接着跳8

主走查第 ② 步:HNSW 的洛杉矶类比

书里用「在地图上找离某点最近的城市」把 HNSW 讲透了——不用逐个城市算距离, 而是一层层缩圈9:

目标:找离「硅谷某坐标」最近的城市

第 1 层(全国,只有几个地标):比 LA 和 NYC → LA 更近,下到西部
第 2 层(西部大城市):SF 最近 → 下到湾区
第 3 层(湾区):San Jose 最近 → 下到南湾
第 4 层(南湾诸城):在 Palo Alto / Mountain View / Sunnyvale / San Jose 里定最近者

图说:每层只算了少数几个距离,总共十几次比较——而不是把全国城市算一遍。

这个类比同时把 ANN 的「近似」暴露出来了:贪心可能进错区域。 如果查询点恰好在两大都市圈的分界线上,第一步跳错了方向, 后面几层就在错误的区域里越挖越细——返回一个「极近但非最近」的答案10。 工程上的交换是明确的:只检查数据集的极小部分,换来与精确搜索几乎无差别的精度。 最常用的开源(源码公开、可免费使用)实现是 Meta 的 FAISS(Facebook AI Similarity Search)11

4. 核心原理(三):向量库不只是存向量

它是一整套系统

向量数据库是管理、存储、查询高维(几百上千个分量的)嵌入的系统。「搜索」只是它的一项职责, 完整的职责清单还包括:持久化、更新、删除、元数据管理、过滤、扩展性、 与其他系统的集成12

专门做这件事的有 Pinecone、Milvus、Weaviate、Qdrant;而通用数据库也在长出向量能力 ——PostgreSQL 的 pgvector 扩展、sqlite-vec、MongoDB 的 Atlas Vector Search。 两条路线目前并存13

元数据过滤:先把库切小,再算相似

第 03 章的元数据,在这里变成真本事。书里的例子:你存了几十年全部上市公司的 季度财报。问「Apple 2023 年 Q3 的研发支出」时,先在元数据上按 「公司=Apple、时间=2023Q3」过滤,再对过滤后的小集合做向量搜索—— 比对全库做向量搜索便宜、也快得多14

过滤发生在搜索的之前、之中还是之后(pre/parallel/post-filtering)是个真问题: 先过滤可能错过候选,后过滤可能 top-k 全被滤掉一个都不剩; 像 ACORN 这样的算法把两者联合起来执行15

主走查第 ③ 步:pgvector 里它长什么样

书里用 PostgreSQL + pgvector 做了完整演示。三张关键语句,白话翻译如下16:

CREATE EXTENSION vector; -- 给 PostgreSQL 装上向量能力
CREATE TABLE sentence_embeddings(
sentence TEXT, embedding VECTOR(384)); -- 一张表:文字 + 384 维向量
CREATE INDEX ... USING hnsw (embedding vector_l2_ops)
WITH (m = 16, ef_construction = 64); -- 建 HNSW 索引

重点不在语法(语句的写法规则),在于:上一章那四个句子、384 维向量、HNSW 索引, 全部活在一张普通的数据库表里——「向量检索」不是外星科技, 它就是你的数据库多了一种列类型、多了一种索引

这张表也不是什么特种库,就是最常见的关系型数据库:以行列表存数据、用 SQL 查询的数据库。

5. 核心原理(四):两个要亲手调的旋钮

k:每次返回几块。 太小,真答案排在第 k+1 名就被漏掉;太大, 块塞爆模型的上下文窗口、带进噪声、还白加生成的成本和延迟17。 第 08 章会看到,生产上的答案不是「把 k 调对」,而是「k 故意取大, 再交给重排去精排」。

维度:存多长。 上一章的 MRL 在这里兑现:把向量截短一半,库存储直接减半、 搜索更快——但截太多会伤质量。同时记住向量库的硬上限(pgvector 32 位精度 上限 2,000 维)18

6. 作者的判断与证据

  • HNSW 的洛杉矶类比是作者的讲解创作,不是原始论文的讲法; 「贪心会进错区域」是算法性质的如实陈述。
  • 「过滤时机影响速度与质量」引用了 Pinecone 的博客与 ACORN 论文,属于 行业共识级内容。
  • pgvector 代码例可直接运行(书附 notebook),可信度高。

7. 边界与局限

  • ANN 的「近似」是概率(事件发生的可能性)上的。 精度参数(HNSW 的 m、ef 等)调得越保守越接近精确, 但也就越慢——这个旋钮本书没有给标准答案,只有方向。
  • 向量搜索只覆盖「语义像」这一种相关。 精确的错误码、型号、生僻专有名词, 向量搜索反而弱——这正是第 08 章混合搜索存在的理由。
  • 向量库选型高度依赖数据规模与更新频率。 第 07 章有一张「实时索引适配度」表, 到那章再评。
  • 书里没讲分片、副本、备份这些数据库常规话题——它们在第 09 章以「通用软件工程」 的面目回来。

8. 可带走的

  1. 相似度是算术:归一化向量的点积 = 余弦相似度;GPU 最擅长大批算它;
  2. 暴力法是 O(n),十亿级不可行;ANN 用「足够近」换「只检查极小部分」;
  3. HNSW = 分层图 + 每层贪心:LA→湾区→南湾一层层缩圈;贪心会进错区域,这就是「近似」;
  4. FAISS 是最常用的开源实现;pgvector 让普通 PostgreSQL 直接长出向量能力;
  5. 元数据过滤先切小库再算相似,时机(pre/post/联合)是个设计决策;
  6. k 与维度是两个亲手调的旋钮:k 管召回与成本的平衡,维度管存储与质量的平衡;
  7. 向量检索只认「意思像」——精确匹配交给词法搜索,第 08 章见。

9. 原文地图

主题原书章原文位置
点积=余弦相似度Understanding Vector-Based Similarity Searchtext/20-fm-understanding-vector-based-similarity-search.txt:4(搜「cosine」)
暴力法 O(n)、FlatIndexUnderstanding Vector-Based Similarity Searchtext/20-fm-understanding-vector-based-similarity-search.txt:7(搜「O(n)」) · :10(搜「FlatIndex」)
ANN 的「approximate」Approximate Nearest Neighbor Algorithmstext/21-fm-approximate-nearest-neighbor-algorithms.txt:4(搜「close enough」)
HNSW 分层与洛杉矶类比Approximate Nearest Neighbor Algorithmstext/21-fm-approximate-nearest-neighbor-algorithms.txt:7(搜「Hierarchical Navigable Small World」) · :76(搜「San Jose」)
贪心进错区域Approximate Nearest Neighbor Algorithmstext/21-fm-approximate-nearest-neighbor-algorithms.txt:117(搜「greedily」)
FAISSApproximate Nearest Neighbor Algorithmstext/21-fm-approximate-nearest-neighbor-algorithms.txt:123(搜「FAISS」)
向量库职责、专用 vs 通用Vector Databasestext/22-fm-vector-databases.txt:4(搜「vector database」) · :7(搜「pgvector」) · :10(搜「Pinecone」)
元数据过滤、财报例Vector Databasestext/22-fm-vector-databases.txt:13(搜「quarterly」)
过滤时机、ACORNVector Databasestext/22-fm-vector-databases.txt:16(搜「ACORN」)
k 的取舍Parameters to Consider When Using Vector Searchtext/23-fm-parameters-to-consider-when-using-vector-search.txt:4(搜「denoted as k」)
pgvector 建表与 HNSW 索引Code Example: …pgvectortext/24-fm-code-example-storing-and-retrieving-vectors-usin.txt:38(搜「CREATE EXTENSION」) · :46(搜「hnsw」)

Footnotes

  1. 出处:「The Query Flow」第 17-44 段(text/10-fm-the-query-flow.txt:17,搜「retrieval query」)。

  2. 出处:「The Query Flow」第 23 段(text/10-fm-the-query-flow.txt:23,搜「dot product」)。原文:点积=内积=标量积,三个名字一个东西。

  3. 出处:「The Query Flow」第 23 段(text/10-fm-the-query-flow.txt:23,搜「cosine similarity」)。归一化=把向量除以自身模长,使模长变成 1。

  4. 出处:「What Is (an) Embedding?」第 4 段(text/16-fm-what-is-an-embedding.txt:4,搜「GPU」)。

  5. 出处:「Understanding Vector-Based Similarity Search」第 7 段(text/20-fm-understanding-vector-based-similarity-search.txt:7,搜「O(n)」)。

  6. 出处:「Understanding Vector-Based Similarity Search」第 10 段(text/20-fm-understanding-vector-based-similarity-search.txt:10,搜「FlatIndex」)。

  7. 出处:「Approximate Nearest Neighbor Algorithms」第 4 段(text/21-fm-approximate-nearest-neighbor-algorithms.txt:4,搜「close enough」)。

  8. 出处:「Approximate Nearest Neighbor Algorithms」第 7 段(text/21-fm-approximate-nearest-neighbor-algorithms.txt:7,搜「Hierarchical Navigable Small World」)。

  9. 出处:「Approximate Nearest Neighbor Algorithms」第 13-111 段(text/21-fm-approximate-nearest-neighbor-algorithms.txt:76,搜「San Jose」)。

  10. 出处:「Approximate Nearest Neighbor Algorithms」第 117 段(text/21-fm-approximate-nearest-neighbor-algorithms.txt:117,搜「greedily」)。

  11. 出处:「Approximate Nearest Neighbor Algorithms」第 123 段(text/21-fm-approximate-nearest-neighbor-algorithms.txt:123,搜「FAISS」)。

  12. 出处:「Vector Databases」第 4 段(text/22-fm-vector-databases.txt:4,搜「vector database」)。

  13. 出处:「Vector Databases」第 7 段(text/22-fm-vector-databases.txt:7,搜「pgvector」)与第 10 段(同文件,搜「Pinecone」)。

  14. 出处:「Vector Databases」第 13 段(text/22-fm-vector-databases.txt:13,搜「quarterly」)。

  15. 出处:「Vector Databases」第 16 段(text/22-fm-vector-databases.txt:16,搜「ACORN」)。

  16. 出处:「Code Example: Storing and Retrieving Vectors Using pgvector」第 38 段(text/24-fm-code-example-storing-and-retrieving-vectors-usin.txt:38,搜「CREATE EXTENSION」)与第 46 段(同文件,搜「hnsw」)。m 与 ef_construction 是 HNSW 建索引时的两个精度/内存旋钮:数字越大,图越密、越准、越占内存。

  17. 出处:「Parameters to Consider When Using Vector Search」第 4 段(text/23-fm-parameters-to-consider-when-using-vector-search.txt:4,搜「denoted as k」)。

  18. 出处:「Parameters to Consider When Using Vector Search」第 7 段(text/23-fm-parameters-to-consider-when-using-vector-search.txt:7,搜「Matryoshka」)与「Practical Tips and Considerations」第 7 段(text/18-fm-practical-tips-and-considerations.txt:7,搜「2,000」)。