Reciprocal Rank (RR) 详解
一句话解释
“第一个正确答案排在第几名?”
排得越靠前,分数越高;如果没找到,分数为 0。
核心公式
RR = ─────────────
排名位置
范围:0.0 ~ 1.0
第1名找到 → RR = 1/1 = 1.0
第2名找到 → RR = 1/2 = 0.5
第3名找到 → RR = 1/3 = 0.33
没找到 → RR = 0
直观理解
想象你在用搜索引擎搜问题,通常你只关心第一个出现的正确答案在第几页第几行。如果第一个正确答案排在第 1 位,体验最好;排在第 10 位,体验就很差。
1. [相关] ✅ → RR = 1.0 (太好了,一眼就看到)
2. [无关]
3. [无关]
4. [相关] ✅ → RR = 0.25 (找了半天才在第4个看到)
5. [无关]
在 RAG 中的演进:MRR vs RRF
在实际的 AI 检索中,单独的 RR 通常演化为两个重要应用:
MRR (Mean Reciprocal Rank):用于评估检索系统的好坏。
RRF (Reciprocal Rank Fusion):用于混合检索的结果融合。
1. MRR(平均倒数排名)- 评估指标
当你测试多个问题时,把每个问题的 RR 加起来求平均,就是 MRR。
query_1: 正确答案在第 1 位 → RR = 1.0
query_2: 正确答案在第 3 位 → RR = 1/3 ≈ 0.33
query_3: 正确答案在第 2 位 → RR = 1/2 = 0.5
# MRR 计算
MRR = (1.0 + 0.33 + 0.5) / 3 = 0.61
意义:MRR 越接近 1,说明系统越能把正确答案顶到第一位。
2. RRF(倒数排名融合)- 混合检索核心算法
这是 RR 在现代 RAG 中最重要、最常见的应用!
当我们在做“向量检索 + 关键词检索(BM25)”时,两套系统给出的排名完全不同,怎么把它们合并?
RRF 核心思想:不管两套系统的分数差多少,我只看你的排名!
排名越靠前,贡献的分数越多,最后把两套系统的分数加起来重新排名。
公式
RRF_score(d) = Σ 1 / (k + rank_i(d))
- d:某个文档
- i:第 i 个检索系统(如向量检索、BM25检索)
- rank_i(d):文档 d 在第 i 个系统中的排名
- k:平滑常数(通常取 60),防止排名第 1 的文档权重过大
动手算一算(k=60)
假设检索一个词,系统 A(向量)和系统 B(关键词)结果如下:
| 文档 | 系统A排名 | 系统B排名 | RRF得分计算 | (1/(60+rank))总得分 |
|---|---|---|---|---|
| 文档1 | 第1名 | 未找到 | 1/(60+1) + 0 | 0.01639 |
| 文档2 | 第2名 | 第1名 | 1/(60+2) + 1/(60+1) | 0.03252 |
| 文档3 | 第3名 | 第2名 | 1/(60+3) + 1/(60+2) | 0.03200 |
| 文档4 | 未找到 | 第3名 | 0 + 1/(60+3) | 0.01587 |
最终融合排名:
文档2 (0.03252) - 两套系统都觉得不错,排第一!
文档3 (0.03200)
文档1 (0.01639)
文档4 (0.01587)
RRF 的巨大优势
┌─────────────────────────────────────────────┐
│ 为什么 RAG 混合检索最爱用 RRF? │
├─────────────────────────────────────────────┤
│ │
│ 1. 无需归一化 │
│ 向量检索分数是 0.8,BM25 分数是 12.5 │
│ 分数量纲不同,直接相加毫无意义。 │
│ RRF 只看排名,不看分数,完美解决! │
│ │
│ 2. 抗干扰能力强 │
│ 某个系统偶尔抽风给出离谱高分, │
│ 不会严重影响最终结果。 │
│ │
│ 3. 实现简单,效果出奇的好 │
│ 不需要训练模型,不需要调参, │
│ 简单的加减法就能融合出高质量结果。 │
│ │
└─────────────────────────────────────────────┘
在 LangChain 中的体现
如果你用 LangChain 的 EnsembleRetriever 做混合检索,它底层默认使用的就是 RRF 算法!
from langchain.retrievers import EnsembleRetriever
# bm25 = 关键词检索器
# vector = 向量检索器
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25, vector],
weights=[0.5, 0.5],
# 底层利用 Reciprocal Rank 机制融合两套结果
)
# 调用时,内部自动计算每个文档在两个检索器中的 RR 分数,加和后重排
docs = ensemble_retriever.invoke("什么是大模型?")
总结
┌─────────────────────────────────────────────┐
│ Reciprocal Rank (RR) 两种形态: │
├─────────────────────────────────────────────┤
│ │
│ 作为评估指标 (MRR): │
│ 看正确答案排在第几位,评估系统好坏。 │
│ │
│ 作为融合算法 (RRF): │
│ 把不同检索系统的排名转化为分数并相加, │
│ 是 RAG 混合检索的基石。 │
│ │
└─────────────────────────────────────────────┘
💡 记忆口诀:
评估看 MRR,融合用 RRF,只看排名不看分!