生成模型不能独自解决的问题
助手在技术档案中寻找正确流程。关键词检索把包含准确零件编号的文档排在首位,语义检索则更重视使用不同措辞的说明。两者都可能合理,但分数尺度不同。直接相加,可能让数值尺度而不是相关性决定结果。本文解释倒数排名融合RRF如何结合位置,以及这种捷径会丢失什么信息。最终问题不是能否得到顺序,而是有没有理由信任所得顺序。
摘要。构造两个包含五篇文档的合成排序,用精确分数计算RRF。内容不变时,参数k在约4.4641这一解析阈值两侧改变A和C的相对位置。每个列表只保留前两项会再次改变顺序;把同一检索器计算四次,则会让按既定标签不相关的文档登顶。本文只计算单个案例的平均精度,不是基准测试。RRF避免直接比较分数尺度,却没有消除候选集、检索器相关性和评估方面的选择。
排序究竟包含什么
文档是有明确身份的对象,而不只是与另一段文字相似的内容。A、B、C、D、E代表五个不同对象。排序是有序列表,位置1最好。同一系统不能因重复返回一个标识而给它两票,代码会拒绝这种输入。按标识去重,并不等于删除表达相同意思的不同文档。后一种冗余需要内容层面的判断,不属于这里的公式。
L1为A-B-C-D-E,L2为B-C-D-E-A。可以把它们想象成词法和语义检索,但我们没有运行这些引擎;输入是为隔离机制而构造的。评估时只把B和C声明为相关。标签不是从排名推导出来的,而是单独确定,类似独立相关性判断的评估协议。在真实档案中,还必须说明谁针对什么问题定义相关性,以及判断样本中缺少哪些文档。
在检索增强生成RAG中,生成器先获得选定文档或片段,再组织答案。融合发生得更早,决定提交哪些候选以及先后次序。它不检查生成句子是否有文档支持,也不检查文档版本是否仍有效。这一区分很重要:更好的检索可能改善可用上下文,但看起来合理的排序不能证明最终答案正确。
相加的是排名贡献,而非置信度
一个引擎给12分,另一个给0.8分,二者相加并不会自动获得共同意义。即使只缩放第一个引擎的全部分数而不改变其内部顺序,也可能改变朴素融合的赢家。RRF放弃文档之间的分数距离,只使用位置。因此,只要候选和顺序不变,对每个引擎分数施加严格递增变换不会影响结果。代价是可能有用的距离也会丢失:巨大领先和微弱领先都只是第一名。
S(d)是文档d的融合分数,j遍历各列表,r_j(d)是d在列表j中的位置,k是非负无量纲常数。只对包含d的列表求和:在本协议中,缺失贡献零,而不是估计一个名次。分数没有物理单位,也不是相关概率。名次从1开始;若从0开始,分母会变化,k=0时甚至会除以零。
基础文献是Cormack、Clarke和Büttcher发表于SIGIR 2009的论文,第758–759页。我们阅读了公式、实验协议、表格和讨论,而非仅摘要。作者在先导研究后固定k=60,并在TREC和LETOR 3上比较融合。论文自身的表格也包含不支持绝对优越性的情况,包括CombMNZ结果。本文不复现那些实验、不使用其数据,也不把其性能移植到假想档案,而是用新输入研究规则行为。
五篇文档,逐项查看贡献
先取k=0,让计算直观。B在L1第二、L2第一,得到1/2+1=1.5。A第一和第五,得到1+1/5=1.2。C第三和第二,得到1/3+1/2=5/6,约0.833333。D得到1/4+1/3=7/12,E得到1/5+1/4=9/20。降序排列为B-A-C-D-E。B在两个列表中都靠前,胜过A单独的一次第一,但C仍落后于A。
保持其他条件不变,令k=60。B得到1/62+1/61=0.032522475,C得到1/63+1/62=0.032002048,A得到1/61+1/65=0.031778058。D和E随后,约为0.031498016和0.031009615。顺序变为B-C-A-D-E。没有文档或标签发生变化,改变的是把位置转换成贡献的函数。因此k属于实验协议,必须记录,不能视作不可见的实现细节。
| 文档 | L1名次 | L2名次 | S(k=0) | S(k=60) |
|---|---|---|---|---|
| A | 1 | 5 | 1.200000000 | 0.031778058 |
| B | 2 | 1 | 1.500000000 | 0.032522475 |
| C | 3 | 2 | 0.833333333 | 0.032002048 |
| D | 4 | 3 | 0.583333333 | 0.031498016 |
| E | 5 | 4 | 0.450000000 | 0.031009615 |
阅读表格时应关注C与A,而不是分数绝对大小。从约1变为约0.03,并不表示文档相关性下降。两种尺度属于不同规则,分数只用于在同一规则下排序。即使固定k,增加列表也会提高分数,并可能改变顺序。因此“分数超过0.03就接受”这样的阈值,不能未经专门验证就在不同配置间迁移。
推导偏好反转的位置
不必只靠尝试参数,也能解释A与C的变化。用A的分数减去C的分数。k非负时所有分母均为正,因此差值符号只由通分后的分子决定。合并四个分数得到二次多项式。这样,敏感性成为可理解的案例性质,而非图形巧合。这不是推导普适最优k,而是找出两个特定排名组合的交叉点。
分子在1加或减根号12处为零,负根不在所选定义域内。当0≤k<4.4641时分子为正,A在C前;超过阈值后为负,C在A前。程序使用整数,k=4仍是前者,k=5变成后者。在精确阈值处两者并列,需要明确的平局规则。代码按标识打破平局,这保证确定性,但没有相关性含义。
第一名相对于第五名的贡献比为(k+5)/(k+1):k=0时是5,k=60时约1.0656。k越大,相邻名次的贡献越接近。排名r远小于k时,1/(k+r)约为1/k−r/k²。出现在m个列表中的文档,其首项贡献约为m/k。这是渐近直觉,不是恒等式;它解释出现次数和列表深度为什么重要,程序仍始终使用完整分数。
截断列表会改变问题本身
真实系统很少返回全部文档。保持k=60,只取L1的A-B和L2的B-C。B保留两项贡献,分数不变;A丢失第五名贡献,只剩1/61;C丢失第三名贡献,只剩1/62。结果变成B-A-C。这不只是近似结果尾部,而是改变仍在候选集中的两个文档的偏好。“融合前两项”和融合完整列表是不同的操作算法。
缺失可能有两种不同含义:文档不在该检索器可访问的集合中,或者只是落在请求深度之外。这里的零不能区分二者,也不是“不相关”的判断。它避免编造未观察到的名次,却使结果依赖检索预算。比较配置时必须记录每个检索器请求多少结果、启用哪些过滤器,以及是否使用同一版本语料。
若相关文档在所有列表中都不存在,仅融合这些候选不可能找回它。这首先是召回问题,即候选中包含了多少相关文档,尚未涉及排序。本例截断后B和C都还在,所以损失来自位置,而不是相关文档召回。区分二者才能选择补救办法:覆盖不足时扩大候选;正确文档已经存在但排名过低时,调整融合或增加重排器。
四份副本不等于四份独立证据
保留完整列表,但加入四份L1和一份L2。这个刻意极端的设置,可以代表四种近乎相同的配置,或重复计算结果的集成错误。k=60时,A得到4/61+1/65=0.080958386,B得到4/62+1/61=0.080909572。A以微小但正的差值领先,顺序回到A-B-C-D-E。重复没有增加文档信息,只提高了已有偏好的权重。
计算RRF并不要求列表在统计上独立。问题是如何解释一致:五项贡献不等于五次独立验证。加权融合可以明确表达选择,例如给一个检索器家族分配总权重,而不是让每个变体都获得完整权重。本文不证明这种办法提高质量,只说明值得比较的替代策略。权重与家族划分不能在看到最终测试结果后投机选择,否则评估失去意义。
w_j是非负无量纲权重。加权版本在此仅供讨论,并非本文报告结果的系统。若四份副本完全相同,各赋1/4权重,就会精确恢复单份L1的总贡献,这是代数结论,不是对真实引擎的新实验。四个列表若不同,等价关系便不成立。有用的多样性不能按调用服务数计算,而应观察错误模式与新增文档。
衡量真正改善了什么
我们使用单个查询的平均精度AP。每遇到一个相关文档,就计算截至该位置的精度:已遇到的相关数除以已读取的位置数。把这些精度相加,再除以声明的相关文档总数,本例为2。缺失的相关文档贡献零。指标奖励有用文档较早出现,不衡量生成句子的正确性。明确分母可以避免列表丢失一个相关文档后反而被虚假奖励。
在B-C-A-D-E中,相关文档位于前两位,AP=(1+1)/2=1。在B-A-C-D-E中位于第1和第3,AP=(1+2/3)/2=5/6,约0.833333。重复L1让A登顶后,相关文档位于第2和第3,AP=(1/2+2/3)/2=7/12,约0.583333。合成标签始终不变。这不是助手可靠性百分比,而是一个构造查询的三种排序指标。
不可缺少的比较对象是原列表。L1的AP为7/12,L2本来就达到1。k=60的完整融合只追平L2,并未超过;k=0时甚至更差。若省略基线,就可能宣称“融合把精度从0.583提高到1”,这只有暗中选择有利的L1作为对照才成立。真实评估需要多个问题、可追溯判断以及查询间差异。单个案例证明机制与可能性,不证明平均优势。

实现很小,假设必须明确
fuse接收有序列表与非负整数k,使用Python标准库Fraction,为每个标识累加1/(k+r),保留精确整数比。仅展示用JSON将结果转换成小数,同时保存分数字符串。按分数排序避免本小例中舍入决定近似平局。这不意味着所有服务都应使用有理数运算,大规模场景可能代价高,自己的数值实现仍需检验。
若总共读取M个位置,出现U个不同文档,用映射累加需要M次更新和O(U)存储。完整排序需要O(U log U)次比较。这是键操作与比较次数,不是延迟测量;分数运算成本还取决于整数长度。只需要前K项时可使用部分选择,但这里完整排序以便检查所有分数。我们没有运行速度基准。
experiment.py重建全部输入,检查列表内唯一性,断言预期顺序,并计算k从0到100的敏感性。输入是确定性的,随机种子不适用。下面代码调用附件中的同一组函数,不是规则不同的简化算法。重现表格只需Python,绘图需要Matplotlib;版本与输出均保存在档案中。这些数字并非通过训练或调用搜索引擎、生成模型获得。
如何把推理用于真实档案
实用评估应区分三个问题:在相同权限和语料版本下,候选是否包含必要文档?融合是否在上下文预算内提供它们,同时考虑片段长度与冗余?生成器是否正确使用证据?本文AP只覆盖第二问的一部分,假定文档地位可比。很长的文档可能先耗尽上下文,因此文档排序不等于token选择。
替代方案包括:归一化分数可保留距离信息,但引入可比性假设;重排器重新评估候选,却需要额外资源和自身评估协议;检索器家族加权明确处理冗余,但必须选择并验证权重。我们没有在同一问题集合上实现和测量这些方案,因此不给出性能结论。诚实比较应先说明各自利用什么信息、增加哪些成本或假设,再讨论质量高低。
答案:融合简单,选择并不中立
使用位置和RRF这样的规则,可以在不直接相加不兼容原始分数的情况下结合检索。但计算简单不意味着结果中立。本例中,参数在可证明阈值处改变偏好,请求深度改变贡献,重复一个检索器则在没有新增知识时改变赢家。执行过的最好融合只是追平原列表,数字中没有奇迹。可信检索需要保存列表来源、参数、候选和独立判断,之后还要单独核验生成器的断言。
from experiment import fuse, ap, L1, L2
for name, lists, k in [('full', [L1,L2],60),('top2',[L1[:2],L2[:2]],60),('duplicates',[L1]*4+[L2],60)]:
result = fuse(lists,k)
print(name,result['order'],ap(result['order']))
代码、数据与说明 · JSON. 教学计算使用 Python 3.14.0,图使用 Matplotlib 3.11.2。分析由 AI 辅助,不声称经过同行评审或人工审核。原创 ImageGen 封面仅作示意,不记录 EL-AI 人员、场所或实际安装。来源查阅于 2026 年 10 月 16 日。

