跳到主要内容

混合检索与重排序

为什么需要混合检索?​

  • 稠密检索的盲区: 懂语义但可能漏掉关键词——搜“HTTP-403”可能返回“服务器错误”的泛泛讨论;
  • 稀疏检索的盲区: 精确匹配但读不懂同义词——搜“kitty”找不到只写了“cat”的文档;
  • 思路: 两个引擎都跑,结果合并;
  • 难点: 两组得分的分布迥异,需要把不可比的分数整合成一个有意义的排序;

混合检索流水线分哪三个阶段?​

  • 第一阶段 并行检索: 系统同时向稠密和稀疏两个引擎发送查询,各自召回一部分候选文档;
  • 第二阶段 结果融合: 把两路结果合成一个统一的候选池;
  • 第三阶段 神经重排序(Neural Reranking): 对候选池中排名靠前的 N 个候选(如前 50 个)逐一精确打分,产生最终排序;
  • 分工: 重排序并不替代融合——融合负责产生统一候选池,重排序负责在候选池上精排;

RRF 如何融合两路结果?​

  • 难点: 稠密检索的余弦相似度得分通常为 0 到 1,稀疏检索的 BM25 得分可能是 0 到几十的任意值,尺度和分布完全不同,不可直接比较;
  • 方法: 倒数排名融合(Reciprocal Rank Fusion, RRF)完全抛开原始得分、只看排名;
  • 公式: 每个文档的综合得分是它在各路结果中排名的平滑倒数之和,得分 = Σ 1/(k + rank);
  • 参数 k: 平滑常数,常取 60,用于压低排名最靠前几个位置之间的得分差距;
  • 取舍: 简单且稳健,但只利用排名信息,丢失了原始得分中蕴含的丰富相关性信号;

重排序为什么值得单独加?​

  • 理由: 它不是为了“补救 RRF 丢掉的得分”才存在;无论前一步用哪种方式融合,重排序都值得加,因为它换用了一种更强的匹配范式;
  • 做法: 让跨编码器对查询和文档做深度交互匹配,精度远高于检索阶段“双编码器各自独立编码、再靠向量运算比相似度”的做法;
  • 效果: 能把被单一方法低估但实际高度相关的文档提升到顶端;

双编码器与跨编码器有什么区别?​

  • 双编码器(Bi-Encoder): 为查询和文档独立生成向量,通过向量运算计算相似度,速度极快,但无法捕捉深层匹配关系,适合从海量数据中做初步筛选;
  • 跨编码器(Cross-Encoder): 把查询和候选文档拼接成一段完整文字送入模型,让模型逐词比对、输出综合相关性得分,慢得多但判断更准确;
  • 类比: 求职者把简历交给猎头快速筛选是双编码器;面试官与每位候选人深谈是跨编码器;
  • 常用模型: BAAI/bge-reranker-v2-m3 采用跨编码器架构;

检索质量如何度量?​

指标直觉解释
recall@k(召回率@k)包含正确答案的文档出现在前 k 个检索结果中的查询比例——回答“该找的找到了吗”,是最贴近 RAG 需求的指标
MRR(Mean Reciprocal Rank,平均倒数排名)每个查询取第一个相关文档排名的倒数,再对所有查询取平均——回答“找到得够不够靠前”,排第 1 得 1 分、排第 10 只得 0.1 分
nDCG(归一化折损累积增益)综合考虑所有相关文档的排名与相关程度,排名越靠后的相关文档折扣越大——回答“整个排序列表的质量如何”
  • 口径提醒: 本书定义的“recall@k”实为命中率(hit rate,也叫 success@k);学术上标准的 recall@k 指相关文档被召回的比例,当一个查询有多篇相关文档时两者并不相等;
  • 口径来源: 本书沿用简化口径是为了与 Anthropic “Contextual Retrieval” 的报告口径保持一致,跨来源比较时需留意各自定义;
  • 工业界口径: 检索失败率——正确信息未出现在 top-20 检索结果中的查询比例;

混合检索实验的关键结论是什么?​

  • 观察面: 测试案例覆盖语义相似(“kitty”对“feline/cat”)、精确名称、多语言查询、技术代码等挑战,可直接对比稠密与稀疏两路在每类查询下各自的胜负;
  • 重排序的作用: 系统展示每个文档在原始稠密、稀疏检索中的排名与重排序后的变化,可看到重排序器如何纠正单一方法的漏判;
  • 结论: 没有哪种单一检索策略在所有场景下都可靠,把稠密、稀疏与重排序组合起来才是构建生产级 RAG 系统的正确做法;