06. Recall 和 Rerank 的区别是什么?为什么很多系统要分两阶段检索?

整理 Recall 和 Rerank 的区别是什么?为什么很多系统要分两阶段检索? 的核心概念、工程要点与面试回答。

简单回答

Recall(召回)负责从海量文档中快速筛选出一个候选集,追求的是"不漏掉正确文档",用的是轻量级模型(如 Bi-Encoder);Rerank(精排)负责对候选集做精细排序,追求的是"把最相关的排在最前面",用的是重量级模型(如 Cross-Encoder)。分两阶段是因为 Cross-Encoder 精度高但太慢,不可能对全库做精排,所以先用快速召回缩小范围,再用精排提升质量。

详细解释

为什么不能一步到位

这是一个经典的效率-精度权衡问题。假设知识库有 100 万个 Chunk,用户提了一个问题,我们需要找出最相关的 5 个 Chunk。

理想情况下,我们希望用最精确的模型(Cross-Encoder)对每个 Chunk 和 query 逐一打分排序。但 Cross-Encoder 的工作方式是把 query 和 document 拼在一起送进 Transformer 做 full attention,计算量很大——100 万次 Cross-Encoder 推理即使在 GPU 上也需要几十分钟,根本无法满足在线服务的延迟要求。

所以必须分阶段。第一阶段用轻量级方法快速从 100 万缩小到几百或几十个候选(召回),第二阶段再用精确方法对这几百个候选精排。这种"漏斗"式的架构在搜索和推荐领域已经用了几十年,RAG 本质上是同一套思路。

召回阶段的典型方法

Bi-Encoder(双塔模型)是语义召回的核心。它把 query 和 document 分别独立编码成向量,然后用向量相似度(余弦相似度或内积)来衡量相关性。因为 document 的向量可以提前算好存入向量库,在线时只需要对 query 做一次编码,然后做 ANN 搜索,速度非常快。代价是 query 和 document 之间没有交互——模型在编码 query 的时候看不到 document 的内容,反之亦然。这种"独立编码"的方式天然限制了精度上限。

BM25 是关键词召回的经典方法,基于词频和逆文档频率做匹配。它不理解语义,但对精确关键词匹配(如产品型号、人名、错误码)非常有效。很多 RAG 系统同时用 Bi-Encoder 做语义召回和 BM25 做关键词召回,合并两路结果作为候选集。

召回阶段通常取 Top 20~100 个候选。数量取多少取决于你对"召回率"和"后续 Rerank 计算量"之间的权衡。

Rerank 阶段的典型方法

Cross-Encoder 是 Rerank 的主流选择。和 Bi-Encoder 不同,Cross-Encoder 把 query 和 document 拼成一个序列 [CLS] query [SEP] document [SEP],送进 Transformer 做 full attention,输出一个相关性分数。因为 query 和 document 在模型内部有充分的 token 级交互(attention),精度远高于 Bi-Encoder 的独立编码方式。

直觉理解:Bi-Encoder 相当于两个人各写了一份自我介绍,比较两份自我介绍的相似度;Cross-Encoder 相当于让两个人坐在一起面对面聊,判断它们是不是在讨论同一件事。后者当然更准,但也更费时间。

常用的 Rerank 模型有 bge-reranker 系列、Cohere Rerank API、Jina Reranker 等。从效果上看,Rerank 这一步通常能带来 5%~15% 的 Recall 提升,在很多项目中是性价比很高的优化手段。

Rerank 还有哪些方案

除了 Cross-Encoder,还有一些其他 Rerank 方案。用 LLM 做 Rerank 是近年来的一个方向——把候选文档和 query 一起喂给 LLM,让 LLM 判断相关性或做排序。效果可能比 Cross-Encoder 更好(因为 LLM 更大、理解力更强),但成本和延迟也更高。适合对精度要求极高、对延迟容忍度较大的场景。

ColBERT(Contextualized Late Interaction over BERT)是一个介于 Bi-Encoder 和 Cross-Encoder 之间的方案。它对 query 和 document 分别编码成 token 级别的向量(而不是一整个向量),然后做 late interaction(MaxSim 操作)。精度接近 Cross-Encoder 但速度快得多,而且 document 端的 token 向量可以提前计算。可以同时用于召回和精排。

工程上的一些注意事项

Rerank 阶段的延迟是需要关注的。如果候选集有 100 条,每条都要过一遍 Cross-Encoder,这个延迟可能在几十到几百毫秒。在对延迟敏感的场景下,需要控制候选集大小,或者选用更轻量的 Rerank 模型。

Rerank 的输入长度也有限制。Cross-Encoder 通常有最大输入长度(如 512 token),如果 query + document 超了就需要截断。截断策略(从前截还是从后截、要不要保留 query 完整)对效果有影响。

面试时可以这样答

Recall 和 Rerank 本质上是效率和精度的分层权衡。Recall 阶段用 Bi-Encoder 或 BM25 快速从全库中筛出候选集,速度快但精度有限;Rerank 阶段用 Cross-Encoder 对候选集做精排,query 和 document 有充分的 token 级交互,精度高但计算量大。

分两阶段的原因很直接:Cross-Encoder 不可能对全库每一条都算一遍,太慢了。所以先用快方法缩小范围到几十到一百条,再用精确方法排序。这是搜索和推荐领域几十年的经典架构,RAG 直接复用了这套思路。

实际项目中,加一层 Rerank 通常是性价比很高的优化手段,Recall 指标能提升 5% 到 15%。常用的 Rerank 模型有 bge-reranker、Cohere Rerank 等。如果对精度要求更高、延迟容忍度更大,也可以用 LLM 做 Rerank,但成本会高不少。

还有一个折中方案是 ColBERT,它在 query 和 document 之间做 token 级别的 late interaction,精度接近 Cross-Encoder 但速度快得多,而且 document 端可以预计算。

常见追问

  1. Bi-Encoder 和 Cross-Encoder 在模型结构上具体有什么区别?
  2. 两路召回(语义 + 关键词)的结果怎么融合?有哪些融合策略?
  3. 如果不加 Rerank,直接增大召回数量(比如 Top 50)能不能替代?