📑 目录
- [🧠 核心思想与优势](#🧠 核心思想与优势)
- [⚙️ 具体过程与参数](#⚙️ 具体过程与参数)
- [1. 并行检索](#1. 并行检索)
- [2. 分配倒数排名分数](#2. 分配倒数排名分数)
- [3. 分配倒数排名分数包含w权重](#3. 分配倒数排名分数包含w权重)
- [4. 对比:不加权 vs 加权](#4. 对比:不加权 vs 加权)
- [5. 权重的两个要点](#5. 权重的两个要点)
- 🚀 进阶应用:融合后的重排序(#-进阶应用融合后的重排序RRF 在人工智能和搜索领域,通常指的是倒数排名融合(Reciprocal Rank Fusion, RRF) 。。它是一种用于混合搜索(Hybrid Search)**的算法,目的是将来自不同检索方法(如关键词搜索和向量搜索)的多个排序列表,合并成一个更优的统一排名。
🧠 核心思想与优势
RRF 的核心非常朴素:一个文档如果在多个检索列表中都排名靠前,那么它在最终结果中也应该排在前面。
它的主要优势在于:
- 无需分数归一化 :全文检索(如 BM25)的分数可能高达 100,而向量检索的余弦相似度分数在 0 到 1 之间。RRF 只关注"排名",完全绕开了不同算法分数尺度不一致的难题。
- 鲁棒性强:相比手动调整权重的线性融合,RRF 对检索结果中的噪声不那么敏感,在大多数场景下表现非常稳健。
⚙️ 具体过程与参数
RRF 的过程可以拆解为以下几个步骤,你提到的"参数"主要集中在计算环节。
1. 并行检索
系统会同时运行多种检索方法(例如,一个全文查询加一个向量查询),每种方法各自返回一个按相关度排序的文档列表。
2. 分配倒数排名分数
这是 RRF 的核心计算步骤。对于每一个列表中的每一个文档,根据它在列表中的排名(rank),计算一个分数。
- 公式 :
分数 = 1 / (k + rank) - 其中,
rank是文档在列表中的位置(第 1 名、第 2 名...),k是一个平滑常数。
关键参数 k
- 默认值 :通常设为 60(如 Azure AI Search、MongoDB 等平台的默认值)。
- 作用 :
k用于缓和排名衰减曲线 。如果不加k,排名第 1 和第 2 的分数差距巨大(1 vs 0.5)。加上k=60后,分数变为 1/61 和 1/62,差距变小。这能确保那些在多个列表中稳定排名靠前的文档,比仅在**某一个列表中排名第 1 的"异常值"**获得更高的总分。 - 调参 :
k值本身通常无需调整 ,经验值 60 适用于绝大多数场景。但在特定需求下可以微调:- 较小的
k(如 10):会更看重顶级结果; - 较大的
k(如 100+):会让排名靠后的结果权重更平均。
- 较小的
加权与求和
如果某些检索方法被认为更重要,可以为其分配一个权重 w。
- 加权后的分数 =
w * (1 / (k + rank))。 - 然后,系统会累加同一个文档在所有列表中的分数,得到最终总分。
- 注意 :权重在逻辑上是相对比例,不需要强制和为 1。例如设置
[3, 1]和[0.75, 0.25]的效果是一样的。
重新排序
最后,将所有文档按照计算出的 RRF 总分从高到低排序,这就是融合后的最终结果。
📊 计算示例
假设有两个列表(A 和 B),k 取默认值 60:
- 列表 A:文档 1,文档 2,文档 3
- 列表 B:文档 2,文档 1,文档 4
计算结果如下:
| 文档 | 列表 A 排名 | 列表 B 排名 | RRF 总分计算 | 总分 |
|---|---|---|---|---|
| 文档 1 | 1 | 2 | 1/(60+1) + 1/(60+2) |
≈ 0.03251 |
| 文档 2 | 2 | 1 | 1/(60+2) + 1/(60+1) |
≈ 0.03251 |
| 文档 3 | 3 | --- | 1/(60+3) |
≈ 0.01587 |
| 文档 4 | --- | 3 | 1/(60+3) |
≈ 0.01587 |
最终排名:文档 1 和文档 2 并列领先,因为它们在两个列表中表现都很好。文档 3 和 4 虽然各自在一个列表中进入了前 3,但总分较低,排在# 3. 分配倒数排名分数包含 w 权重包含w权重
| 符号 | 含义 |
|---|---|
w |
该检索方法的权重,表示它有多重要 |
k |
平滑常数,默认 60 |
rank |
文档在该列表中的排名(从 1 开始) |
核心逻辑 :先按 1 / (k + rank) 算出基础分,再乘以该方法自己的权重 w,最后把同一个文档在所有列表中的加权分数相加,得到最终总分。
举例说明
假设有两个检索列表:
- 列表 A(关键词检索 BM25) :权重
w = 3 - 列表 B(向量检索) :权重
w = 1 k取默认值 60
两个列表的返回结果:
- 列表 A:文档 1,文档 2,文档 3
- 列表 B:文档 2,文档 1,文档 4
逐步计算
文档 1
| 来源 | 排名 | 基础分 1/(k+rank) |
权重 w |
加权分 |
|---|---|---|---|---|
| 列表 A | 1 | 1/(60+1) ≈ 0.01639 |
3 | 3 × 0.01639 ≈ 0.04918 |
| 列表 B | 2 | 1/(60+2) ≈ 0.01613 |
1 | 1 × 0.01613 ≈ 0.01613 |
文档 1 总分 = 0.04918 + 0.01613 ≈ 0.06531
文档 2
| 来源 | 排名 | 基础分 1/(k+rank) |
权重 w |
加权分 |
|---|---|---|---|---|
| 列表 A | 2 | 1/(60+2) ≈ 0.01613 |
3 | 3 × 0.01613 ≈ 0.04839 |
| 列表 B | 1 | 1/(60+1) ≈ 0.01639 |
1 | 1 × 0.01639 ≈ 0.01639 |
文档 2 总分 = 0.04839 + 0.01639 ≈ 0.06478
文档 3
| 来源 | 排名 | 基础分 1/(k+rank) |
权重 w |
加权分 |
|---|---|---|---|---|
| 列表 A | 3 | 1/(60+3) ≈ 0.01587 |
3 | 3 × 0.01587 ≈ 0.04762 |
| 列表 B | --- | 未出现 | --- | 0 |
文档 3 总分 = 0.04762
文档 4
| 来源 | 排名 | 基础分 1/(k+rank) |
权重 w |
加权分 |
|---|---|---|---|---|
| 列表 A | --- | 未出现 | --- | 0 |
| 列表 B | 3 | 1/(60+3) ≈ 0.01587 |
1 | 1 × 0.01587 ≈ 0.01587 |
文档 4 总分 = 0.01587
汇总排名
| 文档 | 列表 A 加权分 | 列表 B 加权分 | 总分 | 排名 |
|---|---|---|---|---|
| 文档 1 | 0.04918 | 0.01613 | 0.06531 | 🥇 1 |
| 文档 2 | 0.04839 | 0.01639 | 0.06478 | 🥈 2 |
| 文档 3 | 0.04762 | 0 | 0.04762 | 🥉 3 |
| 文档 4 | 0 | 0.01587 | 0.01587 | 4 |
4.对比:不加权 vs 加权
如果不加权 (即 w 都为 1),文档 1 和文档 2 的总分会完全相同,并列第一。但加上 w = 3 后:
- 列表 A 的排名变得更重要;
- 文档 1 在列表 A 排第 1,所以总分略高于文档 2(文档 2 在列表 A 只排第 2);
- 最终文档 1 胜出。
这说明**权重 w 会放大某个检索方法的# 5. 权重的两个要点.权重的两个要点
-
权重是相对比例,不是绝对大小
[3, 1]和[0.75, 0.25]效果完全一样,因为比例都是 3:1。- 不需要强制让所有权重之和等于 1。
-
权重需要根据业务调
- 如果关键词匹配更关键(如法律、代码搜索),可以提高全文检索的
w; - 如果语义理解更关键(如问答、推荐),可以提高向量检索的
w; - 很多平台默认等权(都为 1),需要时再手动调。
- 如果关键词匹配更关键(如法律、代码搜索),可以提高全文检索的
🚀 进阶应用:融合后的重排序
RRF 融合通常只是混合搜索的一个中间步骤。在生产环境中,为了进一步提升精度,可以在 RRF 合并结果之后,再使用一个更强的交叉编码器(Cross-Encoder)模型(如 Google Vertex AI 的 VertexRanker)对前 N 个结果进行二次语义重打分。这样可以保持低延迟,同时获得更精准的排序。