向量检索这件事,用起来很简单,调个 API 就能算相似度。但用对很难。同样一套向量检索,有人做出 90% 召回率的搜索,有人做出来全是噪音,差别不在 API,在对 Embedding、索引、相似度这三个底层的理解。
这篇把这三个东西拆开讲清楚。它们是 RAG 检索、语义搜索、推荐召回、去重这些场景的共同地基,搞懂了,所有上层应用都能受益。
Embedding,把语义编码成向量
图:向量检索的完整链路——文档经 Embedding 转成定维向量,用 HNSW 建索引,查询时算余弦相似度找 Top-K 最近邻,三环彼此关联。
向量检索的第一步,是把文本或者物品转成向量。这个转换靠 Embedding 模型,它的任务是把语义信息压缩进一个固定维度的浮点数组里。语义相近的内容,向量在空间里也相近。
这里最关键的认知是,Embedding 模型决定了向量检索的效果上限。后面所有的索引和相似度算法,都只是在「这个上限内」做优化。模型不行,工程再花哨也救不回来。
所以选 Embedding 模型这件事值得认真对待。通用模型(OpenAI 的 text-embedding、BGE 系列、gemini-embedding)对常见领域表现不错,榜单分数也好看。但榜单不代表你的场景。如果数据里有大量领域术语、内部黑话、中英混排,通用模型可能理解不了,检索就差。
正确的做法是,选型时拿自己的真实数据测召回率。准备一批 query 和标注好的相关文档,看不同模型能召回多少。比看榜单靠谱得多,因为榜单的数据分布和你的不会一样。
维度是另一个要锁死的决策。模型输出多少维就是多少维,比如 768 维、1024 维、1536 维。维度一旦定下来,存量向量就要按这个维度重新生成,否则维度漂移会导致检索结果全错。所以选模型的时候,维度是和模型绑定的决策,一次定死别频繁换。
索引,在海量向量里快速找相似的
图:三种索引结构的对比——Flat 精确但慢、HNSW 平衡精度与性能(默认选择)、IVF 最快但精度低,按数据量和精度需求选择。
存了几百万个向量,来了一个查询向量,怎么快速找到最相似的几个。暴力遍历算一遍相似度当然行,但百万级数据要算上百万次,太慢。索引就是来解决「快速找近似最近邻」这个问题的。
最常用的索引结构是 HNSW(分层可导航小世界图)。它的思路是,把向量组织成一个多层图结构,查询时从顶层粗粒度地跳到目标附近,再逐层下沉精细搜索。效果好、速度快,是多数向量库的默认选择。
HNSW 有几个参数值得理解。M 控制每个节点的连接数,越大精度越高但内存和构建时间增加。efConstruction 控制构建时的搜索宽度,影响索引质量。efSearch 控制查询时的搜索宽度,越大越准但越慢。这几个参数是精度和性能的旋钮,要在自己的数据上调一调找平衡。
另一个选择是 IVF(倒排文件索引)。它把向量空间聚成若干簇,查询时只在最相关的几个簇里搜。比 HNSW 快但精度低一些,适合数据量特别大、对精度要求不那么苛刻的场景。
还有一个维度是精确索引(flat),就是不算近似、老老实实算全部。百万以内数据用它完全没问题,精度最高。别迷信近似索引,数据量没到那个量级,暴力搜索又准又简单。
相似度,怎么衡量两个向量近不近
图:三种相似度算法的对比——余弦相似度看方向、点积同时看方向和模长、欧氏距离看空间距离,选择应与 Embedding 模型的训练方式一致。
把候选向量找出来了,要用一个分数衡量它们和查询向量的相似程度。主流有三种算法。
余弦相似度,衡量两个向量的方向是否一致,不管长度。最常用,尤其适合文本场景,因为我们关心的是语义方向一致,不是绝对数值。很多 Embedding 模型输出的向量已经做过归一化,这种情况下余弦相似度等价于点积。
点积(内积),不做归一化时,它同时考虑方向和长度。适合那些「向量的模长本身有信息」的场景,比如某些推荐系统里,模长代表热度或权重。
欧氏距离,衡量两个向量在空间里的直线距离。值越小越相似(和前两个相反,前两个是值越大越相似)。用得少一些,但在图像检索等场景里会用到。
选哪个,主要看 Embedding 模型的设计。模型训练时用的是哪种相似度,检索时就该用哪种,不然效果会打折。多数文本 Embedding 模型用的是余弦相似度或归一化点积,跟着模型走就行。
几个实战中容易踩的坑
归一化的问题。如果用余弦相似度但向量没归一化,结果就是错的。要么在写入时归一化,要么确保模型输出已归一化。这个坑很隐蔽,结果会「看起来能用但全是偏差」。
维度不匹配。换 Embedding 模型导致维度变了,存量向量和新向量维度不一致,检索会报错或者返回垃圾。换模型必须全库重新 embedding,这是个重活,所以前面说维度要一次定死。
距离和相似度的方向搞反。有的库返回距离(越小越相似),有的返回相似度(越大越相似),混用的时候一定要搞清楚方向,不然排序全是反的。
很多人上来就想搞混合检索、重排、多路召回这些高级玩法,结果基础没做好,向量没归一化、维度不一致、索引参数没调,再花哨的上层优化也救不回底层错误。先把 Embedding 选对、索引建对、相似度算对,这一层稳固了,上层的优化才有意义。向量检索的效果,七成取决于这几个基础做没做对。
一个完整的检索链路
把这三块串起来,一个完整的向量检索链路是这样的。文档经过 Embedding 模型转成 768 维向量(模型选定、维度定死),用 HNSW 建索引(参数按数据量调好),查询时把 query 也 embedding 成向量,用余弦相似度(向量已归一化)在 HNSW 索引里找 top K 个近似最近邻。
这条链路里,每一步的选择都影响最终效果,而且彼此关联。Embedding 模型变了维度就变,维度变了索引就得重建,相似度算法要跟着模型走。所以向量检索的选型和调优,要把它当一个整体来看,不能孤立地优化某一环。
理解了这三块底层,再去看任何向量库的文档、任何 RAG 系统的设计,都能看懂它在每一层做了什么选择、为什么这么选。这种底层认知,比记住某个 API 的用法值钱得多,因为工具会换,原理不变。








