我理解向量检索的核心,是把文本之间的“语义接近”变成向量空间里的“距离接近”。传统关键词检索看的是词有没有命中,比如用户问“怎么退款”,文档里写的是“退费流程”,关键词可能匹配不上;向量检索会先把两段文本编码成向量,只要语义相近,距离就会比较近,所以更适合问答、推荐、[[RAG]] 这类场景。
整个链路我一般按三段看:先[[向量化]],再建索引,最后算相似度并排序。
向量化就是用 Embedding 模型把 query 和文档块都转成固定维度的稠密向量。这里最关键的不是“转成多少维”,而是这个向量空间是否真的学到了业务里的语义关系。比如“退款”“退费”“售后申请”在客服场景里应该靠得很近,但“苹果”在水果场景和手机场景里可能对应完全不同的语义,所以 Embedding 模型的领域适配很重要。
有了向量以后,如果数据量很小,可以直接暴力算距离;但线上通常是百万、千万甚至更大规模,不可能每次查询都扫全库,所以要建[[近似最近邻]]索引,也就是 ANN。常见的 [[HNSW]] 是图结构,查询时先从高层快速靠近目标区域,再逐层下沉到更细的位置,优点是召回高、延迟稳,缺点是比较吃内存。[[IVF-PQ]] 更偏大规模压缩检索,能把存储和计算成本降下来,但会牺牲一部分精度。工程上选哪种,不是看哪个算法更高级,而是看数据规模、延迟要求、更新频率和硬件成本。
相似度计算通常用余弦、点积或者欧氏距离。文本 Embedding 里最常见的是余弦相似度,如果向量已经做了归一化,余弦和点积基本等价,线上常用点积是因为算得更快。这里我会特别注意一点:训练或评估 Embedding 时用的相似度口径,最好和线上检索保持一致,不然离线效果和线上排序会有偏差。
所以完整流程就是:文档先[[切块]],跑 Embedding,写入向量索引;用户问题进来后也转成向量,到索引里找 TopK 候选,再结合相似度、元数据过滤或者 reranker 做最后排序。
真正落地时,核心权衡是召回、延迟和成本。比如 HNSW 召回好但内存贵,IVF-PQ 成本低但精度有损;TopK 取大一点召回会好,但后面的[[重排]]和生成成本也会变高。
我还会补一句:很多人一开始会疯狂调索引参数,但实际排查下来,问题往往出在 Embedding 模型和文档切块上。向量空间本身没把语义学好,再好的索引也只是更快地找错东西。这个点在 RAG 项目里特别常见。