向量数据库随着 LLM 热潮从冷门变成无处不在,因为它回答了关键词搜索答不了的问题:"帮我找含义相同的东西,而不只是用词相同的"。它存储高维 embedding,并快速找出离查询向量最近的那些,这正是 RAG(检索增强生成)的检索那一半——大多数生产级 LLM 应用背后的模式,也包括我们在 harness 工程 和 用 LLM API 构建 里讲的上下文组装。
- Embedding 把含义变成几何——模型把文本/图像映射到向量,语义相近的东西落得也近。
- 搜索 = 找最近邻——把查询 embedding 出来,再按余弦/点积相似度找最近的存储向量。
- 精确 kNN 在大规模下太慢(O(n·d)),所以向量库用近似最近邻(ANN)——用一点点召回率换巨大的速度。
- HNSW 和 IVF 是主流 ANN 索引;量化(PQ)压缩向量以省内存。
- 向量库在裸 ANN 库之上多了元数据过滤、持久化、CRUD 和扩展(Pinecone、Weaviate、Milvus、pgvector、Qdrant)。
- RAG 是杀手级用途——按相似度检索相关片段,塞进 LLM 的上下文窗口。
- 混合搜索(语义 + 词法)通常比单用任一种更好。
一个 embedding 模型把文本/图像转成向量,使得距离 ≈ 语义相似度。向量数据库存这些向量,回答"离这个查询向量最近的是哪些?"因为精确最近邻是 O(n·d),它用近似算法(HNSW、IVF)在很小的成本下拿到约 99% 的召回率。在索引之上它再加过滤、持久化和扩展。最主要的应用是 RAG:把查询 embedding 出来,检索最相似的片段,作为上下文喂给 LLM。
Embedding:把含义变成几何
一个 embedding 是模型从一段内容产出的定长向量(比如 768 或 1536 个数)。模型经过训练,使得语义相似的输入映射到邻近的向量:"dog" 和 "puppy" 落得很近;"dog" 和 "tax form" 落得很远。这跨模态有效——文本、图像、音频——也正是它让你能按含义而非精确词搜索。向量本身是不透明的(没有哪一维"表示"人类可读的东西),但向量之间的距离是有意义的,而搜索需要的就这些。
相似度度量
"最近"需要一个距离度量。常见的有:
| 度量 | 衡量 | 说明 |
|---|---|---|
| 余弦相似度 | 向量间的夹角 | 忽略模长;文本 embedding 的默认 |
| 点积 | 夹角 & 模长 | 快;向量归一化后等价于余弦 |
| 欧氏距离(L2) | 直线距离 | 对模长敏感;某些模型用 |
多数文本场景里向量是归一化的,余弦和点积基本等价。面试要点:相似度搜索按其中一种度量排序,返回最近的 k 个向量。
核心问题:近似最近邻
找最近向量的朴素办法是算查询到每个存储向量的距离再取 top k——O(n·d),n 是向量数、d 是维度。在百万乃至十亿级向量、d 上百时,这对交互式搜索太慢了。所以向量数据库用近似最近邻(ANN)算法,在亚线性时间里找出差不多是真正最近的那些。取舍是召回率(recall)(你实际返回了真实 top-k 的多大比例)换速度——调好的 ANN 在快几个数量级的同时能达到约 95–99% 召回。
向量搜索本质是召回率 vs 延迟 vs 内存。精确搜索 100% 召回但慢;ANN 牺牲一丝召回换巨大提速,调索引(和量化)又在内存与两者之间权衡。"你能接受多近似?"是定义性的设计问题。
ANN 算法:HNSW 与 IVF
两大流派主导:
- HNSW(层次可导航小世界图)——构建一个多层图,每个向量连到它的近邻。搜索从稀疏的顶层开始,"贪心"地朝查询跳,逐层下降细化。召回和速度都很好,是多数向量库的默认;代价是更高的内存和构建时间。
- IVF(倒排文件索引)——把向量聚类(如用 k-means)成桶;查询只搜索离它最近的几个桶,而不是全部。内存更省、召回略低,可通过探查多少个桶来调。
第 2 层(稀疏): ●───────────● 从这开始,朝查询跳
│ │
第 1 层: ●──●──●─────●───●──● 下降,细化
│ │ │ │ │ │
第 0 层(全部): ●●●●●●●●●●●●●●●●●●●●● 最细的近邻 → top-k
每步:移动到离查询向量最近的那个邻居
→ 用约 O(log n) 次跳跃找到近似最近邻,而非 O(n)
为省内存,向量常被量化——如乘积量化(PQ)把每个向量压成紧凑编码,用稍多的召回损失换大幅内存下降。真实系统会组合用(IVF + PQ,或 HNSW + PQ)。
向量数据库多了什么
你可以在进程内跑一个 ANN 库(FAISS、hnswlib),那为什么还要数据库?因为生产需要的不止索引:
- 元数据过滤——"最近的向量且 tenant = X 且 date > Y"。把过滤和 ANN 正确结合并不简单,是向量库的核心能力。
- 持久化 & CRUD——持久地存、改、删向量(变更时重建索引),而不只是一个静态的内存索引。
- 扩展 & 高可用——跨节点分片、复制、横向扩展。
- 运维——备份、监控、访问控制。
选择从专用系统(Pinecone、Weaviate、Milvus、Qdrant)到现有数据库的扩展(给 PostgreSQL 的 pgvector、Elasticsearch/Redis 里的向量搜索)都有——后者在你不想引入新数据存储时很有吸引力。
RAG:杀手级用途
检索增强生成是向量库爆火的原因。LLM 的上下文窗口固定、也不知道你的私有数据,所以 RAG 检索相关片段并放到模型面前:
建索引(离线):
文档 → 切块 → 每块做 embedding → 存向量 + 元数据
查询(在线):
用户问题 → embedding → ANN 搜索 → top-k 相关片段
→ 把片段塞进 LLM 提示作为上下文
→ LLM 基于检索到的文本作答
这正是 harness 工程 里的"上下文组装":向量库就是 harness 找到正确片段、放进有限上下文窗口的方式。切块策略和检索质量与模型同等重要。
混合搜索,以及对比 Elasticsearch
纯语义搜索可能错过词法搜索能精确命中的精确匹配(某个商品编码、罕见人名),反之亦然。混合搜索(hybrid search)把向量相似度和关键词(BM25)打分结合、融合排名,通常比单用任一种都好。这正是向量库和 Elasticsearch 汇合之处:经典 Elasticsearch 是词法的,向量库是语义的,而两者都在补上对方,使得混合正成为常态。
| 方面 | 向量库(语义) | Elasticsearch(词法) |
|---|---|---|
| 匹配依据 | 含义(embedding) | 词项(倒排索引) |
| 擅长 | 同义改写、概念、跨语言 | 精确词项、编码、名字 |
| 弱点 | 精确/罕见 token | 同义词、意图 |
| 结合最佳 | 混合搜索融合语义 + 词法排名 | |
常见坑
- 召回调参——ANN 参数在召回与速度/内存间取舍;默认值不一定符合你的精度需求。
- embedding 一致性——查询和文档必须用同一个 embedding 模型;换模型意味着把所有东西重新 embedding。
- 成本 & 维度——大规模高维向量很吃内存;量化和维度选择很关键。
- 新鲜度 & 删除——像 HNSW 这样的图索引对删除/更新处理得别扭;高频变更可能需要周期性重建。
向量数据库就是"按含义搜索":把内容 embedding 成向量,再用近似最近邻索引(HNSW/IVF)找最近的——用一丝召回换巨大速度。在索引之上它加了过滤、持久化和扩展。它的定义性用途是 RAG——为 LLM 检索正确的上下文——实践中混合(语义 + 词法)搜索最优。
什么是 embedding?模型产出的向量,距离 ≈ 语义相似度,所以相近含义是邻近的点。
为什么用近似最近邻?精确 kNN 是 O(n·d)——百万级向量太慢;ANN(HNSW/IVF)用一点点精度换快得多的速度,拿到约 99% 召回。
HNSW 对比 IVF?HNSW = 可导航小世界图,召回/速度高、内存多;IVF = 聚成桶、只探查几个,更便宜但召回略低。
向量库比裸库多了什么?元数据过滤、持久化/CRUD、扩展和运维——不只是裸 ANN 索引。
什么是 RAG?把查询 embedding 出来、检索最相似的片段,喂进 LLM 上下文,让答案立足于你的数据。