在构建基于大语言模型(LLM)的问答系统时,检索质量直接决定了答案的上限。很多开发者从纯向量检索起步,却在实际场景中频频碰壁。本文将深入剖析 RAG 检索链路的演进,从纯向量的局限,到 BM25 关键词检索的互补,再到混合检索与重排序的工程实践,帮你彻底吃透这一关键技术栈。无论你使用 Python、Go 还是 Java 构建服务,这些原理都同样适用。
一、纯向量检索的短板:语义有余,关键词不足
向量检索通过将文本映射为高维向量,能够出色地捕捉语义相似性。例如,查询“如何退货”可以匹配到“退款流程”相关文档。然而,它在处理精确匹配时往往力不从心,这并非模型不够好,而是其底层机制使然。
以下三类场景是纯向量检索的“重灾区”:
- 精确关键词丢失:当查询包含“iPhone 16 Pro Max 拆封后还能退吗”时,向量检索可能只关注“退货”意图,而忽略“拆封”这一关键限制条件,导致召回不相关的泛化文档。
- 专有名词与缩写:代码库中的函数名(如
getUserById)、医疗术语或公司缩写(如“RAG”),在向量空间中往往没有足够稠密的语义锚点,容易被误判为无关内容。 - 数字与编号:查询“2024 年财报第 12 页”时,向量检索很难区分“12”与其他数字的精确差异,容易返回包含“2023”或“第 2 页”的错误结果。
这些问题揭示了一个核心矛盾:语义理解与精确匹配是两种互补的能力。向量检索擅长“意会”,而关键词检索擅长“言传”。

二、关键词检索:BM25 算法的工程价值
BM25(Best Matching 25)是搜索引擎领域最经典的排序算法之一,也是 Elasticsearch 的默认算法。它不关心语义,只基于词频和文档稀有度打分。
其核心思想可拆解为三点:
- 词频(TF):关键词出现越多,文档越相关。但为了防止长文档刷词,它设置了非线性增长上限。
- 逆文档频率(IDF):越稀有的词(如“拆封”)权重越高,越常见的词(如“的”)权重趋近于零。
- 文档长度归一化:文档越长,词频的权重惩罚越重,避免长文档因篇幅优势而虚高排名。
BM25 与向量检索并非替代关系,而是互补关系。在 Milvus 2.5+ 版本中,官方已内置了 BM25 全文检索能力,允许开发者直接在 Collection 中指定 VarChar 字段进行关键词检索,无需额外维护 ES 集群。对于使用 Go 或 Java 开发微服务的团队,这能显著降低架构复杂度。

三、混合检索:取长补短的架构实践
混合检索(Hybrid Search)的核心思路是并行执行向量检索与关键词检索,再融合两路结果。这能同时保证语义覆盖率和关键词命中率。
在工程实现上,主要有两种架构选型:
方案一:Milvus 原生混合检索(推荐)
- ✅ 优点:架构简单,数据无需双写,API 原生支持 RRF 融合,运维成本低。
- ⚠️ 缺点:分词能力相对基础,查询语法不如 ES 丰富。
方案二:Elasticsearch + Milvus 双系统
- ✅ 优点:ES 提供强大的分词(如 IK 分词器)和复杂布尔查询能力。
- ⚠️ 缺点:需要维护两套系统,数据一致性难以保障,故障面扩大。
对于大多数中小团队,Milvus 原生方案是性价比最高的选择。它让你能用 TypeScript 或 Python 快速搭建起完整的 RAG 服务,而不用陷入 ES 的运维泥潭。

四、RRF 融合:最简单有效的排序策略
融合两路检索结果时,直接相加分数往往因量纲不同而失效。RRF(Reciprocal Rank Fusion)提供了一种优雅的解决方案:它不关注分数绝对值,只看排名位置。
其计算公式如下,对于某个文档块 d,其 RRF 分数为:
RRF(d) = Σ 1 / (k + rank_i(d))
其中,rank_i(d) 表示文档 d 在第 i 路检索中的排名(从 1 开始),k 是平滑常数(通常取 60),N 是检索路数。
这种基于排名的融合方式,天然免疫不同检索算法分数尺度不一致的问题。如果一个文档在两路检索中都排进前 10,它的 RRF 分数会远高于只在单路中排名第一的文档。
rank_i(d)kΣ五、重排序:决定答案质量的上限
混合检索解决了“召回”问题,但排序精度依然不足。给 LLM 的上下文窗口有限,如果 Top-3 里混入不相关内容,模型极易被误导。重排序(Reranking)正是为此而生。
5.1 Bi-Encoder vs Cross-Encoder
- Bi-Encoder(双编码器):将 query 和 chunk 分别编码成向量再算相似度。速度快,可预计算,但精度有限。
- Cross-Encoder(交叉编码器):将 query 和 chunk 拼接后一起输入模型,例如
[CLS] query [SEP] chunk,能捕捉细粒度交互,精度更高,但速度慢。
[CLS] query [SEP] chunk [SEP]重排序阶段通常采用 Cross-Encoder,因为候选集已缩小至 20-50 个,计算成本可控。为什么不直接用 Cross-Encoder 做全量检索?假设知识库有 100 万 chunk,逐个拼接推理需要百万次计算,延迟不可接受。因此工程上必须遵循“快召回 + 慢精排”的两阶段策略。

5.2 常用重排序模型对比
截至 2026 年初,主流的 Reranker 模型包括 BGE-Reranker、Cohere Rerank 以及英伟达的 NV-Rerank 系列。选择时需权衡精度与延迟,具体对比参数如下表所示:

六、完整链路与调优指南
将上述组件串联起来,一个生产级的 RAG 检索流程如下:用户提问 → 并行执行向量检索与 BM25 → RRF 融合 → 重排序 → 输出 Top-K 给 LLM。

6.1 策略选型决策表
针对不同业务场景,建议参考以下选型逻辑:

6.2 参数调优顺序(易忽略)
很多团队一上来就调 Reranker,却忽略了召回阶段的漏洞。正确的顺序是:
- 先调召回覆盖:检查 Recall@20,确保相关 chunk 未被漏掉。
- 再调排序精度:优化 MRR 和 nDCG@10。
- 最后看业务指标:如人工标注准确率、用户追问率。

6.3 线上观测指标建议
- 召回指标:Recall@20(Top-20 包含相关文档的比例)。
- 排序指标:MRR(第一个相关结果排名的倒数)、nDCG@10。
- 业务指标:答非所问率、用户反馈评分。

[AFFILIATE_SLOT_1]
七、总结与展望
RAG 检索的优化并非单一技术的堆砌,而是系统工程。记住这三句话:纯向量是基础,混合检索是生产标配,重排序决定答案质量上限。在完成检索链路后,下一步应聚焦生成阶段的 Prompt 设计与引用约束,构建端到端的可观测系统。
[AFFILIATE_SLOT_2]
浙公网安备 33010602011771号