检索 · 2019

重排序

召回只求全,重排序再读一遍问题和段落,把真正相关的排到前面。

常用 · 使用现成模型

要解决的问题

向量检索要在大量文本块里快速算距离,精度有限。排在前面的块经常只有部分相关,占满上下文后又挤掉真正有用的段落。

相对前一代的变化

双编码器把问题和段落分开编码。重排序的交叉编码器让问题和段落一起进入模型,相关判断更准,但算得慢,所以只用于已经召回的一小批。

做法

第一阶段用稀疏、稠密或混合检索取出几十个块。第二阶段用 BERT 交叉编码器或专门的重排序接口逐对打分,只把前几个块交给生成模型。ColBERT 用后期交互,在精度和速度之间取了一个中间点。这项技术的论文出现在 2019 年,在大模型 RAG 里大约从 2023 年起成为常用组件。

局限

重排序救不了第一阶段完全没召回到的文档。对每个候选都跑一遍模型,延迟和费用会随候选数上升。

在链路中的位置

紧挨在生成之前,是检索链路的最后一次筛选。

详解

「详解」根据 Datawhale《All-in-RAG》 的 检索进阶技术 改写,有删节和重组,未包含原教程的代码、图片和练习。原教程与本节详解均按 CC BY-NC-SA 4.0 许可提供:使用时需署名并标明修改,不得用于商业目的,再次改编须以相同许可共享。

召回之后再读一遍问题和候选

第一阶段要在全部块里快速找候选,精度有限。重排序只处理已经召回的几十个块,因此可以用更贵的模型逐一判断它们和问题的关系,再把前几个交给生成。

四种重排的成本不同

倒数排名融合不看原文,只合并多路名次。它适合作为零样本融合,不能发现两路都排错但内容其实相关的文档。

交叉编码器把问题和候选放进同一次前向计算。判断比双编码器细,延迟也随候选数上升。ColBERT 把问题和文档的 token 表示分开保存,查询时做后期交互,精度和速度都介于单向量与交叉编码器之间。

用大模型重排时,提示词里放入问题和候选摘要,要求按相关性返回编号和分数。它灵活,也更慢、更贵,而且输出格式必须校验。候选很多时,应先用交叉编码器或 ColBERT 缩小名单,再让大模型看剩下的几条。

重排改变顺序,不创造召回

正确文档如果没有进入第一阶段的候选,重排无从把它找回来。评估时要同时看重排前和重排后的 Recall@k、第一名是否变化,以及增加的延迟。只看最终答案变好,无法区分收益来自重排还是来自提示词。