多路分数不可比,直接加权会被某一通道主导,或同一段重复占满 Top-k。根因是跨通道未校准。本方法用 RRF 或校准融合。它不增加新信号,前路都空则融合也空。
本文属于 RAG 工程框架中的「2 索引与召回」环节,聚焦「Fusion(融合召回)」方法。
定位
| 维度 | 内容 |
|---|---|
| 角色 | 多路结果的名次合并 |
| 输入 → 输出 | 多份 rank_list → 去重后的融合列表 |
| 默认组合 | Elasticsearch RRF;ranx / PyTerrier |
| 何时不用 | 只有一路检索;前路 Recall 已经是零 |
核心机制
$$
\mathrm{RRF}(d)=\sum_i \frac{1}{k+\mathrm{rank}_i(d)}
$$
未出现在该路的 $\mathrm{rank}_i$ 视为 $\infty$(该项为 0)。
实现路径与心智:吃入多路已排序列表,按排名倒数加权(RRF)或先校准再加,去重后截断。底层心智:可比的是名次不是原始分;融合不能变出任何一路都没召回的文档。前路都空,融合也空。
优缺点
- 优点:稳健、计算轻。
- 缺点:不创造新召回。
契约与走通样例
输入
1 | {"lists": {"bm25": ["C1", "C9", "C3"], "dense": ["C3", "C1", "C5"]}} |
中间量
$k=60$:C1 得 $1/61+1/62\approx0.0325$,C3 得 $1/63+1/61\approx0.0323$,C9 仅 $1/62$。C1 第一。
输出
1 | [{"doc_id": "C1", "rrf": 0.0325}, {"doc_id": "C3", "rrf": 0.0323}] |
社区实现
Elasticsearch RRF;离线评测用 ranx。风险:各路 top_k 差一个数量级时,短名单通道被饿死。
工程落地
最小可运行示例
复制为 .py 后直接运行(仅标准库)。生产可用 Elasticsearch rank_window_size 的 RRF 或 ranx。
1 | """多路排名按名次倒数融合;未出现在该路的文档该项为 0。""" |
参数
| 参数 | 起点 | 影响 |
|---|---|---|
| RRF $k$ | 60 | 标准平滑 |
| 每路长度 | 同量级 | 否则一路缺席 |
失效—信号—螺丝
- 加原始分:一路主导。螺丝:改 RRF。
- 未去重:同一 chunk 占两席。螺丝:按 id 合并。
- 前路空:融合也空。螺丝:回退查召回,不要调 $k$。
规模(100 篇生物学 PDF)
融合本身毫秒级。成本在各通道前序检索。