RRF 如何融合向量检索与 ES 结果?

考查重点:排名贡献与跨路结果归并。按同文档ID合并,各路贡献1/(c+rank)后相加排序,不直接加向量/BM25原分,校K与权重

本题目录

参考答案

核心回答

RRF(Reciprocal Rank Fusion,倒数排名融合)把多路检索结果按名次合成一份排序,不直接相加 BM25 分数与向量相似度。

以向量语义检索和 ES 的 BM25 关键词检索为例:先让两路分别返回有序候选,再按同一片段 ID 对齐。某个片段在一路排名为 r,这一路就贡献 1 / (c + r);将它在各路的贡献相加,按总分降序排列。c 是平滑常数,名次通常从 1 开始;未进入某路候选的片段,在该路贡献为 0。两路都靠前的片段容易获得较高总分,也能保留只被一路找到的候选。

融合后可以直接取结果,也可以把有限候选交给 Rerank 模型进一步判断内容是否回答了问题。**RRF 解决的是不同排序怎样合并,Rerank 解决的是候选与问题究竟有多相关。**这里用 ES 指代关键词通道;Elasticsearch 本身也支持向量检索,两路可以由同一个引擎完成。

为什么用排名,而不是直接加原始分数

BM25 分数受词频、文档长度等影响,向量分数则取决于相似度或距离定义,数值范围和含义不同。例如一路的 8 分和另一路的 0.8 分,不能直接认为前者贡献应是后者的十倍。

RRF 只需要两路各自的名次,因此不用先把原始分数校准到同一尺度。不过,它也舍弃了原分数之间的差距:第一名领先第二名很多,还是只领先一点,RRF 都只看到名次差 1。是否采用 RRF,仍要与单路检索及其他融合方法在实际问题集上比较。

用一个例子算清楚

假设返回的都是同一批知识片段的 ID,两路结果如下,左侧排名更靠前:

  • 向量检索:A、B、C。
  • ES 关键词检索:B、D、A。

取 c = 60,不设置额外通道权重,排名从 1 开始:

  • B:1/62 + 1/61 ≈ 0.032522。
  • A:1/61 + 1/63 ≈ 0.032266。
  • D:1/62 ≈ 0.016129。
  • C:1/63 ≈ 0.015873。

所以融合排序为 B、A、D、C。B 在两路分别排第二、第一,累计贡献超过 A;D 虽然没有进入向量候选,也可以通过关键词通道进入合并结果。这里的数字只是排名计算示例,不是相关概率或实际检索效果。

实现时怎样把两路接起来

  1. 准备可对齐的候选。 同一知识片段在两路使用一致的 ID,并能取回正文、来源和版本。若一路按整篇文档返回、另一路按片段返回,先确定共同的融合单位,否则不能把两个排名直接相加。
  2. 分别完成检索。 两路使用相符的租户、权限、时间或版本范围,返回各自候选及排名。每路候选数可不同,要给它们足够的覆盖空间,也要考虑检索与后续处理成本。
  3. 按 ID 累加贡献。 同一片段在一条结果列表里只计一次;出现在不同通道时,各贡献一次。保留原通道、原排名和融合分数,便于检查结果为什么排到前面。
  4. 排序并控制后续预算。 融合后按分数取有限候选;需要精排时再交给 Rerank,最后根据证据长度和问题需要选入上下文。片段未被任何通道召回时,RRF 无法把它补回来。

Elasticsearch 的 RRF retriever 可以组合关键词与 kNN 等子检索器。rank_constant 对应公式中的平滑常数;rank_window_size 控制参与融合的每路候选窗口,最终返回数量又是另一层设置。使用具体版本时,应核对这些参数的约束,不能把它们都叫作同一个 Top-K。

常见追问

调大 c,会让向量检索权重更高吗?

不会。等权 RRF 的 c 同时作用于两路,调整的是单个列表内不同名次的相对差异。c 越大,前后名次的贡献越接近。若要偏重某一路,需要显式使用通道权重,例如把其贡献写为 w / (c + r),并评估效果;具体引擎和版本对加权 RRF 的支持不同。

RRF 后为什么还可能需要 Rerank?

RRF 没有重新阅读问题和片段,只利用上游名次。候选可能都谈同一个主题,却只有部分满足版本、否定条件或业务限制。Cross-Encoder 等重排模型联合处理问题与候选内容,可以进一步区分这些差异,但会增加推理成本。相关机制可继续看混合检索的排序融合方式。

怎样判断融合有用,而不是增加了噪声?

把精确编号、专有名词、同义表达和复杂条件等问题分组,在相同数据与上下文预算下比较向量、关键词和融合方案。既看相关证据是否被召回、前排是否更相关,也看最终回答、延迟和成本。若正确片段在合并前就缺失,先查检索与过滤;若已进入候选但被挤出,再查融合和精排。

对应教程

参考资料

  • 国内:JavaGuide:RAG 检索优化:借鉴混合检索的多阶段候选预算,说明正文中 RRF 处于两路召回与可选精排之间的位置。
  • 国内:Datawhale:Hello-Agents 第八章——记忆与检索:参考按稳定 ID 汇总候选的实现,说明正文中两路片段对齐;原例是多查询向量检索,异构分数另按 RRF 计算。
  • 国内:zero2Agent:RAG 与检索:借鉴查询分组、原始排名记录和两阶段排序,说明正文中融合收益评估及召回与排序排错的安排。
  • 国外:Microsoft:Hybrid search scoring with RRF:依据倒数名次累加的计算,解释正文算例和 RRF 融合与后续语义重排的不同职责。
  • 国外:Elastic:RRF retriever:依据关键词与 kNN 子检索器、排名常数、窗口和权重配置,说明正文中 Elasticsearch 的对应实现及各参数分工。

RagentJava Workflow

基于 Ragent

核心回答

Ragent 的 Java Workflow 在知识检索后,按“去重、加权 RRF 融合、截断候选、可选模型重排”处理多路结果。去重保证同一片段只保留一份;RRF 根据它在各通道中的原始名次累计贡献,避免直接比较向量相似度与 BM25 分数;重排模型再阅读问题与候选内容,判断哪些片段更能回答问题。

以向量加 ES 关键词检索为例,需要先配置启用关键词后端和通道。该版本默认 rag.keyword.type=none,关键词通道也默认关闭,不能把这条双路融合写成默认运行状态。

去重以后,怎样保留多路贡献

MultiChannelRetrievalEngine 保存各通道的 SearchChannelResult,并将后置处理器按顺序执行。DeduplicationPostProcessor 的顺序为 1,用 RetrievedChunkKey 放入 LinkedHashMap,同键片段保留首次出现的对象。键优先取片段 id,缺失时使用文本的 SHA-256 摘要;两路索引应使用一致的片段标识,才能正确对齐。去重处理器、片段键。

去重处理的是输出对象,原通道列表仍然保留。例如片段 A 同时命中向量和关键词通道,去重后只有一个 A,但融合时仍能分别找到它在两路中的名次,不会因为只保留一个对象而丢掉另一路贡献。

加权 RRF 怎样实现

FusionPostProcessor 的顺序为 5。它遍历每条原通道列表,按片段键累计:

score(chunk) = Σ channelWeight / (rrfK + rank)

源码循环下标从 0 开始,所以计算用 weight / (k + rank + 1)。得到所有贡献后,把融合分写回去重后的片段,再按融合分降序排列。这里用的是各通道原始召回名次,不是去重后的遍历顺序,也不是原始相似度分数。融合计算。

rrfK 控制名次之间的贡献差异,通道权重控制各路贡献大小,两者作用不同。当前配置的 rrf-k 为 20,向量和关键词权重均为 1.0;它们是该版本配置值,是否适合具体知识库仍应评估。只有一条通道时,处理器跳过跨路融合,保留原顺序并执行候选截断。检索与融合配置。

候选截断与模型重排怎样分工

融合后按 candidateLimit 截断候选池,控制送入重排阶段的数量。RerankPostProcessor 的顺序为 10,开启时把当前子问题、候选片段和 contextTopK 传给重排服务;后者决定内容相关性的排序及返回条数。若使用 NoopRerankClient,则仅截取前若干条,没有模型重新评分。候选截断、可选重排、无模型重排实现。

重排调用抛出异常时,多通道引擎会捕获异常并跳过该处理器,后续流程继续使用当时已有的候选。这里没有重排自动重试,返回候选也不代表本次完成了模型精排。处理器异常分支。

这条链路区分三段预算:recallBudget 是各通道召回的基数,candidateLimit 是融合后的候选上限,contextTopK 是后续上下文的条数预算。检索结果格式化时也会使用 contextTopK,因此不能把三者合成一个含义模糊的 Top-K。预算定义、上下文装配。

怎样验证这套实现有价值

固定文档、问题集和检索范围,分别比较向量单路、关键词单路、融合,以及融合后加模型重排。先检查正确证据是否进入各路,再看融合排名、候选截断和精排各淘汰了什么,最后比较答案、引用和延迟。

加权 RRF 实现简单,不需要校准不同通道的原始分数,但会舍弃分数差距,也可能让噪声通道贡献过高。模型重排能补充内容判断,却无法找回已被候选截断淘汰的片段;扩大候选池又会增加重排成本,应在同一任务集上取舍。

参考资料

相关面经

7 篇

公司未注明

面经合集
查看原面经 →
多路召回如何融合,RRF 为什么不直接比较原始分数?(5篇)

东方财富

AI 应用开发工程师
一面
查看原面经 →
RRF 的计算过程是什么?
多路召回的结果为什么需要融合?RRF 如何根据排名完成融合?

美团

AI 全栈开发工程师
校招秋招二面
查看原面经 →
两路召回结果怎么融合?RRF的k值怎么设

阿里巴巴

AI 应用研发工程师
校招秋招一面
查看原面经 →
BM25和向量检索怎么融合?RRF的k值怎么设

百度

Agent 应用开发工程师
秋招一面
查看原面经 →
RRF 具体是什么算法?
展开剩余 2 篇面经

字节跳动

后端开发工程师
一面
查看原面经 →
Dense、Sparse 和 RRF 分别是什么?

百度

Agent 应用开发工程师
秋招二面
查看原面经 →
RRF融合排序是怎么做的?什么原理呢
所以这个RRF是使用的向量检索的结果和ES的结果来进行融合的吧?

收录题集

3 个来源,共3 份题集

Agent_RAG与混合检索工程

Rocky Ding · AIGC-Interview-Book · 1 条原题

查看题集 →

八股集锦(高频问题)

小熊饼干_ · 个人整理 · 1 条原题

查看题集 →

RAG 与检索系统:从 chunk 设计到多路召回

Onefly · zero2Agent · 1 条原题

查看题集 →

相关题目

4 题