生产级检索技术栈:为什么纯向量搜索会失败以及应对策略
大多数 RAG 系统在部署时都配备了向量数据库、几千个 embeddings,并假设语义相似度已经足够接近正确性。事实并非如此。这种“语义相似”与“实际正确”之间的差距,正是 73% 的 RAG 系统在生产环境中失败的原因,而且几乎所有这些失败都发生在检索阶段 —— 甚至在 LLM 生成任何文字之前。
“对文档进行嵌入、使用余弦相似度查询、将 top-k 传递给 LLM”的 standard playbook 在演示中有效,是因为演示查询是经过设计的。生产环境的查询则不然。用户搜索的是产品 ID、发票号码、监管代码、拼错的竞争对手名称,以及单个 embedding 向量在几何上无法满足的多重约束问题。稠密向量搜索并没有错 —— 只是它并不完整。构建一个在生产环境中真正起作用的检索栈,需要理解其中的原因,并层层加入能够弥补这些缺陷的组件。
为什么稠密嵌入在生产环境中会失效
稠密嵌入(Dense embedding)将文档压缩成固定大小的向量。这种压缩在设计上就是有损的。对于语义相似性任务 —— 寻找关于相同话题的文档、改写、概念聚类 —— 这种压缩没问题。但对于精确查找任务 —— 寻找包含特定代码、专有名词或精确标识符的文档 —— 这种压缩会丢弃你实际需要的信息。
Google DeepMind 最近的一项研究将其公式化为一个几何约束:将查询映射到文档的分数矩阵的秩受限于嵌入维度。当语料库规模超过一定限度时,单向量模型根本无法划分文档空间来满足复杂的查询。在实践中,这意味着 512 维的模型在处理约 500,000 份文档时会可靠地失效,甚至大型的 4,096 维模型在 2.5 亿份文档时也会崩溃。这些并不是极端情况 —— 大多数生产级知识库都会触及这些限制。
一旦你开始留意,这些失败模式就是可以预见的:
- 精确关键词查询:搜索 “Error 221” 会自信地返回关于 “Error 222” 的文档,因为这些 embeddings 在语义上是相邻的。
- 罕见术语和标识符:产品 SKU、法律代码和词汇表之外的专有名词在稠密向量空间中表现不佳。
- 组合约束:“蓝色越野跑鞋,10 码,100 美元以下”包含三个正交约束。单个向量会平均化搜索意图,而不是满足每个组成部分。
- 特定领域词汇:在金融、医疗或工业领域,缩写词和专业术语的含义在通用 embeddings 中的编码并不一致。
检索返回了“足够接近”的文档。随后,LLM 根据这些文档生成一个听起来很自信的回答 。最终,用户得到了一个语气极其笃定的错误答案。
2026 年重提 BM25 的理由
BM25 (Best Match 25) 是一种基于词频的排名算法,源自 20 世纪 90 年代。按照深度学习发展的逻辑,它现在理应被取代了。但它并没有,BEIR 基准测试解释了原因。
在对 18 个不同数据集的评估中,BM25 仍然是一种极具竞争力的零样本(zero-shot)方法。在论点检索任务中,BM25 的 nDCG@10 达到了 0.367,目前还没有测试过的神经模型能超过它。在没有针对特定领域进行微调的情况下,BM25 在 8–10 个数据集的分布外场景中表现优于稠密检索。它的索引大小仅为稠密编码的 10%,并且可以使用运维团队已经熟知的标准分片模式进行水平扩展。
BM25 擅长的正是稠密嵌入失效的地方:精确术语匹配、罕见 Token、专有名词和标识符。它通过逆文档频率(IDF)为罕见术语赋予更高的权重 —— 仅在少数文档中出现的术语比无处不在的术语更具诊断性。稠密模型往往会在嵌入压缩过程中冲淡这种信号。
像 SPLADE 这样的现代稀疏方法比 BM25 更进一步。SPLADE 使用 BERT 注意力机制来识别关键 Token 并执行学到的术语扩展 —— 在索引期间将“汽车”映射并激活“汽车”和“车辆”,同时不失稀疏检索的精确性。SPLADE++ 在推理时实现了仅针对文档的扩展,在降低延迟的同时保留了大部分质量提升。
实践总结:BM25 不是过时的备选方案。它是一个一流的检索组件,能捕捉到稠密嵌入系统性遗漏的信号。
