Advanced RAG:混合检索、重排与查询改写设计

12769 字
32 分钟

Advanced RAG:混合检索、重排与查询改写设计

发布于

在这世界上有一道被称为 你 的光芒,在这小小的地球上不断扩大照亮了黑暗。

文档性质:Phase 2 新增模块的学习说明与系统架构
代码核对日期:2026-08-25
当前实现:Dense / BM25 / Hybrid / Hybrid-Rerank / Advanced 五组可比较 Profile
当前评测:自建 60 题五组完整消融;MultiHop-RAG 2,255 题四组完整检索评测

Base RAG 已经建立了最小闭环:文档经过切块和 Embedding 进入 FAISS,问题通过 Dense Retrieval 找到 Top-K Chunk,最后由大语言模型基于证据回答。

Phase 2 不改变这条链路的目标,而是针对三个常见问题逐层增强:

  1. 只靠语义检索可能漏掉精确术语:增加 BM25 稀疏检索;
  2. 召回结果不等于最佳排序:先用 RRF 融合两路召回,再用 Reranker 精排;
  3. 用户问题不一定适合直接检索:在检索前增加一次结构化 Query Rewrite;
  4. 模块执行成功不代表模块有效:增加证据级指标与五组 Profile 消融实验。

Phase 2 的核心变化可以概括为:

Base RAG 与 Advanced RAG 链路对比
Base RAG 与 Advanced RAG 链路对比

本文先分别说明每个新增模块解决什么问题、依据什么原理工作,再给出完整的 Advanced RAG 架构。

1. Phase 2 新增模块

1.1 models.py:让一个命中记录完整保留多阶段排名

Base RAG 中的 SearchHit 只需要表达一个 Chunk 的最终相似度和排名。Phase 2 引入 Dense、BM25、RRF 和 Rerank 后,同一个 Chunk 会连续经过多个排序阶段。如果只保存最终 score,就无法解释它为什么上升或下降。

当前 SearchHit 因此增加了四组过程字段:

SearchHit(
    chunk=chunk,
    score=0.91,
    rank=1,
    dense_score=0.72,
    dense_rank=8,
    bm25_score=6.34,
    bm25_rank=2,
    rrf_score=0.0318,
    rrf_rank=3,
    rerank_score=0.91,
    rerank_rank=1,
)

其中,scorerank 表示当前阶段的有效结果;dense_*bm25_*rrf_*rerank_* 保存每一阶段留下的轨迹。

Dense 第 8 名 → BM25 第 2 名 → RRF 第 3 名 → Rerank 第 1 名

这组字段把“检索结果”升级成了“可解释的检索过程”。当最终答案错误时,可以继续判断:正确 Chunk 是从未召回,还是进入候选后被错误排序。

1.2 bm25.py:增加擅长精确词匹配的稀疏检索

Dense Retrieval 会把问题和 Chunk 分别编码成稠密向量,再按向量相似度检索。它擅长同义表达和概念匹配,但面对版本号、命令、代码标识符和罕见缩写时,不一定稳定。

BM25 从另一个角度判断相关性:

  • 问题中的词是否出现在 Chunk 中、出现多少次
  • 这个词在整个语料中是否稀有
  • 当前 Chunk 是否过长。
Dense 与 BM25 的互补关系
Dense 与 BM25 的互补关系

BM25 被称为稀疏检索,是因为文本可以表示为一个词表向量:语料词表很大,而一个 Chunk 只包含少数词,大部分维度都是零。

当前实现先将文本分词:

  • 中文部分使用 jieba
  • 英文、数字和技术标识符保留为整体;
  • 所有英文统一转成小写;
  • 标题、章节和正文共同参与统计。

例如:

qwen3-rerank 可以对 RRF 候选做二阶段精排

会保留 qwen3-rerankrrf 等技术词,同时对中文部分分词。

对查询中的每个词,BM25 分数可理解为:

score(q,d)=tqIDF(t)TF(t,d)(k1+1)TF(t,d)+k1(1b+bd/avgdl)score(q,d)=\sum_{t\in q} IDF(t)\cdot \frac{TF(t,d)(k_1+1)} {TF(t,d)+k_1(1-b+b\cdot |d|/avgdl)}

公式中的三个核心因素是:

因素含义作用
TF(t,d)词在当前 Chunk 中出现的次数出现越多通常越相关,但收益逐渐饱和
IDF(t)词在整个语料中的稀有程度越少见的词越有区分力
长度归一化当前 Chunk 长度与平均长度之比避免长文本仅因包含更多词而占优势

当前参数为 k1=1.5b=0.75。建库时,词频、文档频率、Chunk 长度和分词器版本会保存到 bm25.json

BM25 与 Dense 不是替代关系,而是互补关系:

问题类型DenseBM25
“精排模型有什么作用?”能理解“精排”与“Reranker”的语义接近文档未出现相同词时可能漏掉
IndexFlatIP 是什么?”罕见标识符的语义表示可能不稳定精确命中标识符时优势明显
口语化、同义改写通常更强依赖实际分词重合
命令、版本号、报错文本可能召回相似概念通常更适合精确匹配

1.3 retrieval.py:使用 RRF 融合 Dense 与 BM25 排名

Dense 分数与 BM25 分数来自不同计算空间:Dense 是归一化向量的内积,BM25 是词频、稀有度和长度共同形成的统计分。两者的数值范围与含义不同,不能直接相加。

RRF(Reciprocal Rank Fusion,倒数排名融合)绕开原始分数,只使用每个 Chunk 在各检索器中的名次:

RRF(d)=rrankings1k+rankr(d)RRF(d)=\sum_{r\in rankings}\frac{1}{k+rank_r(d)}

当前 k=60。某个 Chunk 没有出现在一路结果中,就不获得该路加分;同时出现在 Dense 与 BM25 前列的 Chunk 会获得两路加分。

RRF 如何融合两路排名
RRF 如何融合两路排名

例如:

Chunk A:Dense 第 1,BM25 未命中
RRF(A) = 1 / (60 + 1)

Chunk B:Dense 第 3,BM25 第 2
RRF(B) = 1 / (60 + 3) + 1 / (60 + 2)

即使 Chunk B 在任何一路都不是第一名,它也可能因为获得两路共同支持而排到融合结果前面。

代码先用 chunk_id 合并重复命中,再保留 dense_*bm25_* 字段,最后写入新的 rrf_scorerrf_rank。同分时按 chunk_id 排序,使重复运行保持确定性。

RRF 的职责是提高候选池的稳健性。它不会判断一个 Chunk 是否真正回答了问题,这一步交给后续 Reranker。

1.4 rerank.py:使用二阶段精排提升正确证据的位置

Dense、BM25 和 RRF 的目标是高召回:尽量把可能相关的 Chunk 放进候选池。候选池中的文本可能只是出现了相同术语,或主题相近,却没有直接回答问题。

Rerank 的目标是高精度:把用户问题与每个候选 Chunk 放在一起进行更细粒度的相关性判断,然后只返回最相关的少量证据。

两阶段检索与 Cross-Encoder 精排
两阶段检索与 Cross-Encoder 精排

典型的 Reranker 使用 Cross-Encoder 思路:

[Question] + [Candidate Chunk]

        同一个 Transformer

        relevance_score

它与 Dense Retrieval 常用的 Bi-Encoder 有明显区别:

结构编码方式优点代价
Bi-Encoder问题与 Chunk 分开编码,再计算向量相似度Chunk 向量可提前保存,适合全库检索问题与文本缺少逐 Token 交互
Cross-Encoder问题与 Chunk 一起输入模型能细致判断文本是否真正回答问题每次提问都要重新计算每个候选,速度较慢

因此,Reranker 只处理 RRF 已经筛出的有限候选,而不扫描整个知识库。

当前代码将原始用户问题、候选 Chunk 正文、top_n 和任务说明发送给 qwen3-rerank 服务。服务返回候选索引和 relevance_score,程序校验越界、重复和无效分数后,写入新的 rerank_scorererank_rank

Rerank 的能力边界也很明确:

如果正确证据没有进入候选池,Reranker 无法凭空找回它;它只能重新排列已有候选。

1.5 rewrite.py:把自然语言问题整理成可检索查询

用户问题不一定是适合检索的表达。例如“那个比赛要人会干啥”包含指代和口语,Dense 可能理解得不稳定,BM25 也缺少可以精确匹配的实体与术语。

Query Rewrite 在检索前调用一次大语言模型,将问题整理成结构化结果:

{
  "intent": "了解 KDD Cup 2026 Data Agents 的核心能力要求",
  "rewritten_query": "KDD Cup 2026 Data Agents 比赛强调哪些核心能力?",
  "keywords": ["KDD Cup 2026", "Data Agents", "核心能力"]
}
Query Rewrite 的输入输出与双路使用方式
Query Rewrite 的输入输出与双路使用方式

当前 Prompt 要求模型:

你是 RAG 查询理解器。分析用户问题并只输出一个 JSON 对象,不要 Markdown、解释或代码块。
JSON 必须严格含有 intent(字符串)、rewritten_query(字符串)和 keywords(字符串数组)。
rewritten_query 应补全指代与上下文,保持原意;keywords 只保留实体、术语、缩写、版本号和限定词。

三个字段的用途不同:

  • intent:保存模型对用户意图的概括,当前仅用于运行记录;
  • rewritten_query:作为 Dense 的查询文本;
  • rewritten_query + keywords:共同作为 BM25 查询,补充精确术语。

改写使用 temperature=0,并严格检查 JSON 结构。

1.6 pipeline.py:用 Profile 编排不同能力组合

pipeline.py 将新增模块组合成五个可比较的 Profile:

ProfileDenseBM25RRFRerankRewrite
dense
bm25
hybrid
hybrid-rerank
advanced
  • 离线 ingest() 在原有 FAISS 索引之外,同步建立 BM25 索引。
  • 在线 ask() 按 Profile 依次执行 Rewrite、索引加载、Dense/BM25 召回、RRF、Rerank、Context 装配与生成。

默认候选规模为:

Dense Top-20 ─┐
              ├→ RRF Top-30 → Rerank Top-6 → LLM Context
BM25 Top-20 ──┘

最终运行记录会保存 Rewrite 结果、两路查询、每层候选及排名、Prompt、答案、引用、模型身份、阶段耗时和调用次数。

1.7 evaluation.py:用证据级指标判断模块是否有效

Phase 2 将 Base RAG 的来源命中评估扩展为“召回、排序、答案质量和成本”四类观察。

Phase 2 的评测与消融闭环
Phase 2 的评测与消融闭环

主要自动检索指标包括:

指标评测问题
Source Recall@6最终 Top-6 是否至少来自正确文章
Chunk Recall@6最终 Top-6 是否包含标注的正确证据片段
Chunk Recall@20正确证据是否进入较大的初始候选池
MRR@6第一个正确 Chunk 排得有多靠前
nDCG@6Top-6 中相关 Chunk 的整体排序质量
unanswerable_retrieved无答案题是否仍返回了检索结果
mean latency / stage calls指标变化付出了多少延迟和模型调用

其中,Chunk Recall@20Chunk Recall@6 的组合可以区分两类问题:

Recall@20 = 0
→ 正确证据没有进入候选池,属于召回问题

Recall@20 = 1,Recall@6 = 0
→ 正确证据已被召回但排序靠后,属于排序问题

实验固定比较:

Hybrid - Dense             → BM25 + RRF 的增量价值
Hybrid - BM25              → Dense + RRF 的增量价值
Hybrid-Rerank - Hybrid     → Reranker 的增量价值
Advanced - Hybrid-Rerank   → Query Rewrite 的增量价值

评测还可以使用 LLM Judge 对 correctnesscompletenessgroundednesscitation_correctness 给出 0~2 分,并生成匿名的 Dense/Advanced 人工复核表。不过当前主报告仍以检索指标和延迟为主,Judge 与人工复核是辅助证据,不应与确定性的检索指标混为一个总分。

2. Advanced RAG 架构

2.1 完整架构图

Advanced RAG Phase 2 完整架构
Advanced RAG Phase 2 完整架构

3. Advanced RAG 评测:模块能运行,不等于模块有效

前面的章节回答了 Advanced RAG 如何工作,但系统增加了 BM25、RRF、Reranker 和 Query Rewrite,并不意味着检索质量一定会提高。一个模块可能成功完成调用,却没有找回更多正确证据;也可能改善候选召回,却破坏最终排序;还可能只带来很小的质量收益,却显著增加响应延迟。

因此,本章不把评测理解为给整个系统计算一个总分,而是逐层回答四个问题:

  1. 正确证据是否进入了候选池?
  2. 正确证据是否被排到了足够靠前的位置?
  3. 多证据问题所需的事实是否被完整找回?
  4. 指标改善付出了多少延迟和模型调用成本?

3.1 从“找到文档”到“正确回答”的四层评测

RAG 的最终目标是根据证据正确回答问题,但错误可能发生在链路的不同位置。只看最终答案,无法判断问题究竟来自检索还是生成;只看 Source Recall,也无法证明模型获得了真正支持答案的 Chunk。

Advanced RAG 的四层评测对象
Advanced RAG 的四层评测对象

四层评测之间是递进关系:

层级核心问题主要指标当前实验是否覆盖
候选召回正确证据是否进入较大的候选池Chunk Recall@20、Coverage@10
最终排序正确证据是否进入最终 Top-K,并且排得足够靠前Chunk Recall@6、MRR、nDCG、MAP
证据完整性多证据问题需要的事实是否被共同找回Evidence Coverage、Complete Evidence
最终回答回答是否正确、完整、忠实且引用准确Correctness、Groundedness、Citation Support

当前两套完整实验都是仅检索评测,没有调用 LLM 生成最终答案。因此,本章可以判断检索链路是否找到了正确证据,但不能把这些指标写成答案正确率。

3.2 两套数据集分别验证什么

只使用自建题集,容易让评测结论依赖熟悉的语料和标注方式;只使用公开数据集,又很难精确定位某个模块为什么成功或失败。因此,当前评测采用“内部诊断集 + 外部压力测试”的双数据集结构。

自建数据集与 MultiHop-RAG 的评测职责
自建数据集与 MultiHop-RAG 的评测职责
数据集规模与构成主要用途不能单独证明什么
自建数据集60 题:12 道词法、16 道语义、12 道多证据、10 道歧义、10 道无答案逐类诊断 Dense、BM25、RRF、Rerank 和 Rewrite 的增量价值不能代表陌生领域上的泛化能力
MultiHop-RAG2,556 道原始问题;跳过 301 道null_query,实际评测 2,255 道检查系统在陌生英文新闻语料、跨文档和多事实问题上的表现当前仅评检索,不能证明答案与推理正确

两套数据集的关系可以概括为:

自建题集回答“模块为什么变好或变差”,公开数据集回答“换一个领域以后,这个结论是否仍然成立”。

MultiHop-RAG 中实际参与评分的问题包含 inference_querycomparison_querytemporal_query。它们通常需要组合来自不同文档的事实,因此除了观察第一条相关证据的位置,还必须检查所需 Gold 事实是否被完整覆盖。

3.3 如何保证消融比较公平

五个 Profile 并不是五套互不相关的系统,而是在相同底座上逐步增加能力:

五个 Profile 的能力递进关系
五个 Profile 的能力递进关系

实验固定语料、Chunk、索引、问题集和主要候选规模,每次只观察一个新增模块带来的变化:

Hybrid - Dense             → BM25 + RRF 是否带来互补召回
Hybrid-Rerank - Hybrid     → Reranker 是否改善最终证据排序
Advanced - Hybrid-Rerank   → Query Rewrite 的收益是否覆盖成本

质量指标还必须与运行成本一起报告。否则,一个 Profile 即使只提高很小的 MRR,也可能因为额外模型调用而被误判为更好的默认方案。

两套数据集的 Top-K 设置并不相同:自建题集观察最终 Top-6,MultiHop-RAG 观察 Top-4 和 Top-10。因此,二者适合比较“模块作用是否一致”,不应直接横向比较 MRR@6MRR@10 的绝对数值。

3.4 自建 60 题:Reranker 收益最明确,Rewrite 成本过高

自建题集在相同 60 道题上完整运行了五个 Profile,所有 Profile 均完成 60/60,失败数为 0。该实验不生成答案,评分分母是 50 道可回答题;10 道无答案题的检索行为单独记录。

ProfileChunk Recall@6Chunk Recall@20Evidence Coverage@6MRR@6nDCG@6平均延迟
Dense0.78670.86670.79330.61170.67070.195s
BM250.63670.84670.64330.48980.54260.028s
Hybrid0.77670.90670.78670.55490.62590.170s
Hybrid-Rerank0.85670.90670.85670.64970.72140.447s
Advanced0.85670.93670.85670.66140.729917.071s
自建题集上的检索质量与延迟权衡
自建题集上的检索质量与延迟权衡

3.4.1 Hybrid 找回更多候选,但不保证最终排序更好

Hybrid 的 Chunk Recall@20 从 Dense 的 0.8667 提升到 0.9067,说明 Dense 与 BM25 的互补候选确实找回了更多正确证据。

但是,Hybrid 的最终 MRR@60.6117 降至 0.5549Evidence Coverage@6 也从 0.7933 小幅降至 0.7867。这说明 RRF 扩大了候选池,却没有充分判断哪个 Chunk 真正回答了问题:

更多正确证据进入 Top-20

正确证据已经排进最终 Top-6

这一结果与 RRF 的算法职责一致。RRF 根据两路名次寻找共同支持,不直接建模“问题与候选文本是否构成答案关系”。

3.4.2 Reranker 是最明确的质量增益来源

从 Hybrid 到 Hybrid-Rerank:

指标HybridHybrid-Rerank变化
Evidence Coverage@60.78670.8567+0.0700
MRR@60.55490.6497+0.0948
nDCG@60.62590.7214+0.0955
平均延迟0.170s0.447s+0.277s

Chunk Recall@20 没有变化,但 Top-6 的覆盖与排序同时提高,说明正确证据原本已经进入候选池,Reranker 的主要作用是把它们从候选后部移动到最终上下文。

这正是“第一阶段追求高召回,第二阶段追求高精度”的两阶段检索价值。

3.4.3 Query Rewrite 改善了候选召回,但不足以支持全量启用

从 Hybrid-Rerank 到 Advanced:

  • Chunk Recall@200.9067 提升到 0.9367
  • MRR@6 只从 0.6497 提升到 0.6614
  • Evidence Coverage@6 保持 0.8567
  • 平均延迟从 0.447s 增加到 17.071s,约为原来的 38 倍。

因此,不能简单地说 Query Rewrite 完全无效:它确实帮助部分正确证据进入了 Top-20 候选池。但这些新增候选没有转化成更高的最终 Top-6 证据覆盖,而每道题都增加了一次高延迟模型调用。

当前更合理的定位是:

Query Rewrite 适合作为检测到歧义、指代或首次检索不足时的按需能力,而不是所有问题都执行的默认步骤。

3.5 MultiHop-RAG:模块收益会随领域与 Top-K 改变

MultiHop-RAG 评测使用同一英文新闻语料、索引、问题集和 top_k=10。Dense、BM25、Hybrid、Hybrid-Rerank 四个 Profile 均完成 2,255/2,255,失败数为 0。

ProfileCoverage@4Coverage@10Complete@10Hits@4Hits@10MAP@10MRR@10平均延迟
Dense0.28780.44400.16450.59600.78090.20570.43840.148s
BM250.31680.47490.19870.62840.79070.23290.48060.150s
Hybrid0.33750.51050.23370.65010.82790.24500.50290.349s
Hybrid-Rerank0.32520.54920.27450.60800.84700.20790.39630.598s

3.5.1 BM25 在英文新闻语料上强于 Dense

BM25 在主要指标上均高于 Dense,平均延迟几乎相同。自建中文技术题中,Dense 的整体表现更强;换到英文新闻后,人名、机构、时间、标题和来源等精确词项为 BM25 提供了更强的区分信号。

这组差异说明:

检索器的强弱不是固定属性,而是查询表达、语言和语料分布共同作用的结果。

因此,不能只根据自建题集宣布 Dense 或 BM25 是永远更好的检索器。

3.5.2 Hybrid 是公开集上最稳定的综合基线

相对 BM25,Hybrid 将 Coverage@100.4749 提升到 0.5105,将 MRR@100.4806 提升到 0.5029。它同时取得最高的 Coverage@4Hits@4MAP@10MRR@10

这说明 Dense 与 BM25 的互补候选在陌生领域中仍然有效。即使 Hybrid 在自建题集的最终 Top-6 上没有直接超过 Dense,它仍然是后续 Rerank 或 Agentic 检索更稳健的无生成候选基线。

3.5.3 Reranker 提高完整覆盖,却降低前排质量

Hybrid-Rerank 相对 Hybrid:

观察目标HybridHybrid-Rerank变化
Coverage@100.51050.5492+0.0387
Complete Evidence@100.23370.2745+0.0408
Hits@100.82790.8470+0.0191
MRR@100.50290.3963-0.1066
MAP@100.24500.2079-0.0371

它找全多条 Gold 事实的能力更强,却把第一条相关证据排得更靠后。这与自建题集上 Reranker 同时改善覆盖和排序的结果不同,但二者并不矛盾:

  • 自建题集观察最终 Top-6,问题主要来自中文技术文档;
  • MultiHop-RAG 观察 Top-10,问题需要组合英文新闻中的多个事实;
  • 当前 Reranker 的任务说明强调“共同提供全部所需证据”,可能更偏向集合完整性,而不是首条证据排名。

另一个重要原因可能来自 MultiHop-RAG 的问题结构与当前重排方式并不完全匹配。多跳问题不是直接从问题定位答案,而是需要沿着一条证据链逐步找到中间实体。最直观的结构是:

问题提到 A
    ↓ 第 1 跳
证据 1:A → B
    ↓ 第 2 跳
证据 2:B → C

最终答案在 C 中

例如,题目询问“创办 A 公司的人后来领导了哪家机构?”。第一篇文档只说明 A 公司 → 创办者 B,第二篇文档再说明 人物 B → 机构 C。最终答案是 C,但包含 C 的第二篇文档可能完全不出现 A;它只有通过中间实体 B,才能与原问题建立关系。

当前 Reranker 则把每个候选 Chunk 与完整的原始问题组成一对,逐条独立计算相关性:

完整多跳问题 + Chunk A → score_A
完整多跳问题 + Chunk B → score_B
完整多跳问题 + Chunk C → score_C

这种直接重排存在两个潜在问题:

  1. A → B 的 Chunk 与原问题直接相关,通常容易获得较高分数;
  2. 真正包含最终答案的 B → C Chunk 可能不包含 A,与原问题的直接语义相似度较低,反而会在 Rerank 时被降到后面;
  3. 多个反复介绍 A 的相似 Chunk 还可能重复占据前排,进一步挤压包含 B 和 C 的关键证据。

因此,多跳检索真正需要优化的不是“每条 Chunk 单独有多相关”,而是“选出的整组 Chunk 是否共同覆盖了所有证据子目标”:

单条相关性目标:哪些 Chunk 与关于 A 的原问题最相似?

多跳证据目标:先找到 A → B,再使用 B 找到 B → C

这可以解释为什么直接使用 Reranker 不一定适合多跳查询:Reranker 可以判断一段文本是否直接回答当前问题,却不会自动执行 A → B → C 的链式检索。它可能保留大量与 A 直接相关的文本,同时把包含最终答案 C 的第二跳证据降权。

当前结果中,Hybrid-Rerank 的 Top-10 完整覆盖提高,但 MRR 和 MAP 没有同步改善,说明它确实改变了候选集合,却没有稳定地把多跳证据链按有效顺序放到前排。

后续更适合 MultiHop-RAG 的做法,是把检索改成迭代过程:先围绕 A 检索并识别中间实体 B,再使用 B 构造第二跳查询寻找 C。每一跳可以分别 Rerank,最后再进行去重和证据链组合,而不是一开始就使用关于 A 的原问题对所有候选统一重排。

因此,配置选择取决于下游如何使用上下文:

上下文很短,强调前几条证据
→ 优先 Hybrid 的前排质量

允许保留 Top-10,强调多事实完整覆盖
→ Hybrid-Rerank 更有价值

3.6 跨数据集结论:不存在脱离任务目标的“最佳 Profile”

模块自建数据集MultiHop-RAG当前判断
BM25单路整体弱于 Dense,但词法题有优势整体强于 Dense对实体和精确词项密集的领域很有价值
Hybrid / RRF扩大 Top-20 候选召回,但 Top-6 排序未直接改善综合检索表现最稳定适合作为后续检索增强的候选基线
Reranker明显改善 Top-6 覆盖与排序提高 Top-10 完整覆盖,但降低前排质量是否启用取决于上下文长度和证据完整性目标
Query Rewrite小幅改善候选召回,最终覆盖不变,延迟显著增加完整结果缺失暂不适合全量默认启用,应改为按需触发

Advanced RAG 的价值并不来自模块数量,而来自每个模块能否针对特定失败模式产生可验证收益。

4. 下一阶段设想:从固定链路走向 Agentic Multi-Hop RAG

当前 Advanced RAG 已经具备混合检索、融合、重排和查询改写,但它仍然是一条固定的单轮链路:系统围绕原问题检索一次,再将得到的结果直接交给生成模型。这种方式适合答案能够被直接检索的问题,却不擅长需要逐步发现中间信息的多跳问题。

MultiHop-RAG 的评测结果已经暴露出这一边界。对于 A → B → C 类型的问题,原问题通常只提到 A,最终答案却位于描述 B 与 C 关系的另一篇文档中。即使第二跳证据已经进入候选池,它也可能因为没有直接出现 A,而在使用原问题统一 Rerank 时被降到后面。

下一阶段希望将这条固定链路升级为一种受控的 Agentic Multi-Hop RAG:系统先判断问题是否需要多跳。简单问题继续使用当前成熟的 Hybrid 或 Hybrid-Rerank,只有确实需要组合多条证据的问题才进入迭代检索。

从固定 Advanced RAG 到 Agentic Multi-Hop RAG
从固定 Advanced RAG 到 Agentic Multi-Hop RAG

多跳检索不再要求一次找到最终答案,而是允许系统沿证据链逐步前进:先围绕 A 找到中间实体 B,再使用 B 构造新的查询寻找 C。每一跳都围绕当前子问题检索和重排,最后将不同来源的证据组合成一条可解释的推理链。

这一变化也会重新定位现有模块:

  • Hybrid Retrieval 继续作为稳定的基础召回能力;
  • Reranker 不再用原问题统一处理所有候选,而是服务于当前一跳的具体子问题;
  • Query Rewrite 不再对每个问题默认执行,而是在某一跳检索不足时按需触发;
  • Evidence Evaluation 从判断单条 Chunk 是否相关,进一步扩展到判断整条证据链是否完整。

这里的“Agentic”并不意味着让模型自由调用任意工具或无限尝试。系统仍然运行在明确边界内,只在“继续下一跳、修复当前查询、生成答案或证据不足时结束”之间做有限选择。这样既保留动态决策能力,也能控制循环次数、模型调用和响应延迟。

理想情况下,下一阶段的系统将形成下面的能力分工:

简单问题
→ 单轮 Hybrid / Hybrid-Rerank

多跳问题
→ 发现中间实体
→ 生成下一跳查询
→ 补齐后续证据
→ 组合证据链
→ 生成并验证答案

这次升级希望解决的并不是“让流程看起来更像 Agent”,而是当前系统中几个已经被实验观察到的具体痛点:单轮检索无法主动追踪中间实体、直接 Rerank 可能压低后续跳证据、Rewrite 固定执行的成本过高,以及检索到多条材料后仍缺少证据链完整性判断。

因此,项目的下一阶段可以概括为:

保留当前 Advanced RAG 已验证的检索底座,在其上增加问题路由、逐跳检索、证据链组合和有限纠错,使系统能够根据问题难度决定“是否继续寻找下一条证据”,而不是对所有问题执行同一条固定流水线。

Last updated on