RAG重排序器实际如何工作?

企业文档智能[第1卷第2D期]——数据科学家在被问及时说什么,模型在幕后实际做什么,以及为什么诚实回答会改变企业RAG中的架构决策。该文章《RAG重排序器实际如何工作?》首次发表于

来源:走向数据科学

当RAG检索结果不尽如人意时,如今AI工程师听到的建议几乎总是“加一个重排序器”。若问重排序器为何有效,答案通常停留在架构层面:它是一个交叉编码器,对查询和段落共同应用注意力机制,并在相关性标签上进行了微调。这些说法都没错,但都没有说明模型实际学到了什么。再深入一层,讲到业务伙伴能验证的术语时,解释通常就戛然而止了。

这种差距很重要。一个团队如果无法用通俗语言说明重排序器做了什么,就无法为使用它的决定辩护,也无法发现那些关键词查找能以极低成本胜出的场景。

本文给出诚实的答案,一个你可以不费口舌就能交给业务伙伴的答案。重排序器并不比它之下的嵌入步骤更聪明。它运行的是相同的机制(来自训练数据的统计词元关联),只是条件不同(作用于查询-段落对,而非每个文本独立)。一旦你明白了这一点,“何时使用重排序器”的问题就不再是“因为教程用了所以加上”,而变成“仅当这种特定权衡值得付出时才使用”。

🧭 本系列新手?从导览开始:《提示、上下文、循环》阐述了每个RAG系统所基于的三个工程层——提示(调用本身)、上下文(填充模型窗口的内容)、循环(下一次调用何时触发及何时停止)——并以此视角逐篇文章贯穿整个系列。这是了解涵盖内容和本文位置的最快捷方式。

📓 在您自己的PDF上尝试重排序器:doc-intel/notebooks-vol1。配套笔记本加载一个交叉编码器,将其应用于关键词过滤后的Top-K,并显示分数及驱动分数的词元。更改查询,观察哪些关键词决定了排序。

1. 数据科学家怎么说,以及为什么这还不够

问三位数据科学家重排序器做什么,你会得到三个答案,大致如下:

“它是一个交叉编码器。它联合评分查询-段落对并给出相关性分数。”技术上正确,但“交叉编码器”和“相关性”这两个词掩盖了模型实际学到的东西。

“它对两个文本应用注意力机制,因此能看到它们之间的交互。”在架构层面正确,但架构并不能告诉你模型在用该注意力做什么。

“它在相关性标签上训练,因此学习哪些段落回答哪些问题。”非常接近,但“学习哪些段落回答”这个动词用错了。模型并没有学会回答问题。它学会的是哪些词元共同出现。

这三种说法都不错。但当你需要决定是否在流水线中保留重排序器、是否在自有语料上微调它,或用更便宜的东西替代它时,这三种说法都有其不完整之处,而这种不完整至关重要。

本文的其余部分将沿着机制深入解析这个答案,然后指出三个改变企业RAG架构方式的结论。

2. 重排序器内部实际发生了什么

重排序器是一种特定类型的Transformer,在特定类型的数据上训练,产生特定类型的数值。这三个方面都很重要。

2.1 架构:交叉编码器,而非双编码器

嵌入器(双编码器)单独读取查询,生成一个向量。单独读取段落,生成一个向量。通过余弦比较两个向量。每个文本独立嵌入,模型在评分时从未同时看到它们。

重排序器(交叉编码器)将查询和段落一起读取,作为拼接后的输入:[CLS] 查询 [SEP] 段落 [SEP]。它在联合输入上运行类似BERT的注意力机制,每个词元都可以关注到其他每个词元。它输出一个单一的相关性分数。

“一起读取”是整个架构差异所在。双编码器:两个向量,一次比较操作。交叉编码器:一次前向传播,一个分数。联合注意力是重排序器感觉更聪明的原因,也是它每个查询慢30到100倍的原因。

2.2 训练数据:MS MARCO及其同类

重排序器从哪里学习评分?从人工标记的查询-段落相关性对。典型数据集是MS MARCO(Bajaj等人,2016年,包含100万个真实Bing搜索查询及人工评级的段落相关性)。其他数据集:Natural Questions(Google搜索+维基百科段落)、BEIR(基准聚合器)、TREC。

每个训练样本都是一个三元组:(查询,段落,相关性标签)。模型看到数百万个这样的样本,其权重进行调整,使得标记为相关的配对获得比标记为不相关的配对更高的分数。

这是唯一的学习信号。模型从未被展示一个问题并要求它组成一个答案;它被展示配对,并优化一个能区分相关配对与非相关配对的分数。

这就引出了一个诚实的问题:在训练数据中,究竟什么模式真正将它们区分开来?

2.3 模型真正学到什么:配对级别的关键词共现

这就是很少被解释的深一层内容。

模型查看数百万个(查询,段落,相关性)三元组并问:联合词元流中的哪些模式能预测相关性标签?主导模式不是“回答问题”。而是在高相关性配对中,哪些查询词元倾向于与哪些段落词元共现。

具体来说,在MS MARCO中,查询“how to cancel my subscription”与包含cancel、subscription、unsubscribe、terminate、end your membership的段落被标记为相关。数百万个样本强化了这样的关联:当查询包含cancel时,包含terminate或unsubscribe的段落往往被标记为相关。重排序器的权重吸收了这种关联。

所以,“聪明”的重排序器做的是关键词链接,在查询-段落配对层面。它是一个在查询词元邻域和段落词元邻域之间学到的关联表,以神经网络分数的形式呈现。

嵌入器做的是同样的事情,但在每个文本上独立进行。重排序器则是在配对条件下进行。相同的机制,不同的条件。

重排序器也会捕捉二阶信号:位置模式(术语在段落中出现较早通常与相关性相关)、句法结构(连接查询词元和段落词元的主谓宾关系)、定义性措辞的存在(“X是Y”)。这些都有帮助,但它们是二阶的;主导信号是关键词共现。

为什么这个框架很重要:一旦你理解了机制,“它在我语料上能用吗?”这个问题就有了明确的答案。如果你的语料词汇和查询词汇类似于MS MARCO(通用英语、常见网络主题),训练好的关联就能迁移,重排序器感觉像魔法。如果你的语料词汇是专业化的(保险合同、医疗记录、监管文件),训练好的关联无法覆盖你的领域,重排序器就会继承其下嵌入器的相同词汇外失败。再多的“但它是交叉编码器”也无法解决这个问题。

3. 机制展示:重排序器在何处胜出,在何处碰壁

第2部分提出了一个论断:重排序器是一个在问题语言和答案语言之间的学习关联表。这个论断是可测试的。选取几个候选,用三个嵌入器(MiniLM、ada-002、text-embedding-3-large)和三个交叉编码器(bge-base、bge-large、ms-marco-MiniLM)评分,并阅读每行结果。

3.1 胜出之处:不重复问题的答案

针对三个段落问“最高保额是多少?”答案是(“保额上限为每年5万欧元”),一个重复问题词句但不回答的回应(“最高保额可在福利表中找到”),以及一个干扰项。

每个嵌入器都把回应排在首位。它与问题共享maximum、coverage、amount,所以其向量距离很近。答案几乎没有词汇共享,因此排在第二或第三。两个bge重排序器将其翻转:它们一起阅读问题和答案,识别出“上限为每年X”的段落回答了“最高保额”的问题,并将其提升至#1。这就是重排序器做的真正工作:将问题的词句连接到答案的词句。

这不是个例。同样的翻转在简单事实题上也能复现:

在十几个此类查询中(谁写了某部戏剧、水的沸点、光速、第一任总统,以及企业三件套:免赔额、通知期、保额),两个bge重排序器将答案救至#1,而每个嵌入器都将回应排在它之上。这一优势是真实且可重复的,正好适用于一种形态:短事实答案,不重复问题,而排在它前面的是一个重复问题的回应。

同样两张图中存在两个诚实的注意事项。首先,并非每个重排序器都能做到:ms-marco-MiniLM在两个案例中都将回应保持在首位,与嵌入器相同的词汇偏见。其次,当强大的嵌入器已经能回答问题(text-embedding-3-large在某些问题上自己就能搞定)时,重排序器相对于使用更好的嵌入器并没有增加什么价值。

3.2 碰壁之处:你的私有词汇

现在来看看决定企业问题的案例。问“承包商加班的规定是什么?”其中答案使用了公司自己的术语“非雇员劳动力每周超过40小时的补偿”,而从未使用contractor这个词。

每一列,嵌入器和重排序器,都将答案排在最后。表面匹配(“承包商按项目计酬”)胜出。重排序器从未在MS MARCO中看到contractor映射到non-employee labor,因此其关联表中没有这个条目。它运行的交叉注意力是真实的,但它只能触发它学过的关联,而这一条它从未学过。

3.3 要跨越那道墙,你必须已经知道答案

文献提供的解决方案是微调:用来自你自己领域的标记(问题、段落、相关)三元组喂养重排序器,直到它学会contractor映射到non-employee labor。但看看标记其中一个三元组需要什么。了解领域的人必须指向正确的段落并说这个回答了问题。为了指向它,他们必须识别出“non-employee labor beyond 40h/week”就是答案的样子。这种识别就是答案关键词。

所以训练标签和词典条目携带的信息是一样的。对于“最高保额”问题,标记答案意味着知道答案包含capped at、up to、货币、per year。编写专家词典意味着准确键入:{capped at, up to, maximum, €, per year}。对于承包商案例,标记配对意味着知道contractor在这家公司等于non-employee labor,而词典条目就是那一行。

区别在于成本和形态。重排序器需要数百个标记配对来统计性地泛化该映射,需要一次再训练运行,并且它仍然是一个黑箱,输出0.83的分数。词典需要一行,确定性触发,并显示审计下匹配的确切关键词。如果你已经足够了解答案从而标记数据,你就已经知道了答案关键词,写下来是更便宜、可审计的路径。重排序器的统计学习只有在映射过于宽泛而无法枚举时才值得,那是开放网络,而不是有界的企业领域。

4. 为什么这个答案在企业中很重要

诚实的答案带来三个后果,每一个都会改变你可能未曾注意的架构决策。

4.1 审计轨迹不透明

重排序器给出的0.83的相关性分数在审查下是无法辩护的。当监管机构问“为什么返回了这个段落?”得到的答案是“重排序器给了它0.83”。这不是审计轨迹。它只是一个产生数字的黑箱。

相比之下,关键词过滤器是:检索到的段落包含force majeure和pandemic。这个声明是可检查、可重放、可辩护的。如果检索有误,你可以追踪词典中缺少哪个关键词并添加它。如果重排序器错了,你只能对着分数耸肩继续,或者重新训练整个东西。

对于检索决策具有合规或合同后果的企业用例(保险核保、法律证据开示、医疗记录、监管报告),不透明不是一个小权衡;它是一个取消资格的因素。

4.2 成本是实实在在的

交叉编码器每个查询比双编码器慢30到100倍。如果你的双编码器在20毫秒内对1000个候选打分,重排序器对同样的1000个候选打分需要600毫秒到2秒。在实践中,你不会对1000个候选重排序:你取双编码器的前20或前50个候选仅对这些进行重排序,这根据深度和模型的不同,将额外延迟降低到15到100毫秒范围内。

这在低查询量下是可以的。在每秒100个查询的持续压力下,重排序器成本是一个真正的运营支出项目:更多的GPU容量,更长的p99延迟,更多的待命基础设施。它带来的价值必须证明该成本的合理性,而这只有在其训练关联真正覆盖你的词汇时才成立。在领域外的企业语料上,它通常做不到。

4.3 词汇缺口将显现

为嵌入器在领域外企业词汇上编目的每一种失败模式也适用于重排序器,因为它在相同的分布(通用网络搜索)上训练。Force majeure和act of God在保险合同中含义相同,但在重排序器学习的关联中落在不同的邻域,因为它在不同的训练上下文中看到它们。Rescission在MS MARCO中很少见。ShieldPro Elite根本没有出现。

在领域语料上微调重排序器有帮助,但仅限于一定程度。你需要来自你领域的标记查询-段落配对才能微调,而这正是企业团队很少拥有的。即使微调后的重排序器也继承了相同的底层机制:它仍然学习词元关联,只是来自你较小的领域语料,而你能标记的样本数很少能与MS MARCO提供的数百万相匹配。

5. 应该怎么做,以及何时保留重排序器

鉴于机制和企业后果,问题变成了:什么能赢得重排序器在流水线中的位置?

企业RAG中的默认做法(本系列建议):由领域专家维护的精选关键词词典。专家已经知道force majeure在此合同中等于act of God,rescission是用户所说的cancellation的正式术语,ShieldPro Elite是顶级房主计划。在版本化的YAML词典中编码一次并在此基础上运行基于关键词的检索,你就能获得:

可审计的检索(匹配的关键词是可检查的)

低延迟(热路径中没有LLM,没有GPU成本)

跨模型版本的持久性(词典比任何重排序器版本都更持久)

对业务的可解释性(他们能读懂词典)

重排序器在四种特定情况下赢得它的位置。前三个是运行时位置,第四个不是。

领域内分布。你的语料词汇和查询词汇确实类似于MS MARCO(通用网络、常见英语、高频主题)。消费者常见问题、公共服务门户、电子商务帮助。重排序器的训练关联可迁移。使用它。

关键词过滤后Top-K的语义重排序。在关键词词典将语料过滤到20个候选后,重排序器可以按上下文相关性对它们排序。这与第2C条5.3节分配给双编码器嵌入的角色相同,而交叉编码器以额外延迟为代价更准确地完成它。当Top-K较小且排序重要时,值得使用。

重排序器分数本身作为审计产物的合规场景。如果你的合规框架要求“模型将此段落评分高于阈值X”,分数就是产物,重排序器符合要求。

离线,用于发现应进入词典的内容。在真实问题的样本上运行重排序器,并阅读它提取的内容。当它揭示词典尚未拥有的映射时,你就有了一个候选别名。专家确认或否决它,只有确认的行才会发布。模型负责搜索,专家负责决定,最终投入生产的是经过验证的行,而不是分数。第2C条对嵌入给予相同处理,而第16D条在语料规模上持续运行此循环——一个失败的搜索提出别名,专家确认它。

第四个案例重新定义了其他三个。两条路径做同样的工作,下面的图表将它们并排展示。

除了这四种情况之外,重排序器主要增加成本:在演示中令人印象深刻,在生产中昂贵,在审计中不透明,并且无法弥补它没有的训练关联。

这一切下面有一个等价关系,值得用一行来陈述。一个重排序器是一个关键词关联表,是别人在别人的语料上训练的。编写你自己的词典是同样的工作,由实际了解词汇的人完成,成本只是零头,且采用审计员能阅读的形式。只要模型被当作魔法,这种等价关系就仍然不可见。如第2.3节那样打开盒子,选择就显而易见了:使用模型来寻找候选链接,使用专家来验证它们,并让经过验证的表成为生产运行的基础。

6. 来源与进一步阅读

关于重排序器的文献密集且大多持乐观态度。以本文的框架(“交叉编码器学习的是配对层面的关键词关联,而非理解”)来阅读,比将其视为无保留的认可更有用。

与本文方向一致:

Nogueira & Cho,《使用BERT进行段落重排序》,2019年(arXiv:1901.04085)。引入了使用BERT进行交叉编码器重排序的论文,并设定了当前大多数重排序器遵循的模式。诚实地阐述了模型学习的内容。

Khattab & Zaharia,《ColBERT》,SIGIR 2020(arXiv:2004.12832)。晚期交互检索。明确设计用于保留嵌入器和交叉编码器都会丢失的词元级信号,这是词元级模式才是真正重要因素的最强架构信号。

不同角度,不同背景:

Bajaj等人,《MS MARCO》,2016年(arXiv:1611.09268)。塑造了几乎所有商业重排序器实际知识的训练数据。值得略读,以了解重排序器关联所来自的查询和段落分布。

Muennighoff等人,《MTEB:大规模文本嵌入基准》,EACL 2023(arXiv:2210.07316)。包含重排序器排行榜。该排行榜是在分布内基准上测量的,这正是重排序器看起来表现良好的情况。它对于在你的领域外企业语料上会发生什么说得较少。