Adaptive RAG(一):何时检索比检索多少更重要

RAG 最容易被讲成一个检索增强公式:切块、向量化、取 top-k、拼进 prompt、让模型回答。这个公式很实用,但它默认了一件事:系统在回答之前已经知道自己缺什么信息。

复杂任务里,这个假设经常不成立。问题可能在生成到一半才暴露,证据可能和当前结论冲突,召回内容也可能只是语义相似而不是事实支撑。于是 Adaptive RAG 真正要解决的不是“多检索一些”,而是:系统什么时候应该承认当前上下文不够,并把检索变成下一步可验证动作。

要解决的问题

固定检索的失败通常不来自某一个 retriever 太弱,而来自检索时机和信息需求没有被显式建模。

一个简单 RAG 流程会在用户问题进入后立刻检索。这样做稳定、便宜、容易缓存,但它把不同问题压成同一个接口:不管是事实核验、多跳推理、摘要归纳还是工具调用后的验证,都先取一批相似片段。

这会带来三个工程问题。语义相关不等于证据支持;召回时机固定会浪费上下文窗口;失败原因不可分解,无法判断错误来自触发、query、召回、rerank 还是生成。

所以 Adaptive RAG 的第一性问题不是 top-k,而是 evidence gap detection:当前状态是否真的缺少外部证据。

主线判断

Adaptive RAG 的主线不是把检索次数调多,而是把“为什么需要外部证据”变成系统状态。

如果检索只是 top-k 参数,系统只能在召回质量上打转;如果检索是 evidence gap 的响应,系统就能把触发、query、证据支持和最终生成拆开评估。这个区别决定了后续是继续堆上下文,还是能真正进入可调试的工程闭环。

最小抽象

一个更稳的抽象不是“某个 token 需要检索”,而是“当前状态暴露了一个证据缺口”:

1
2
3
4
5
6
information_need = {
state: 当前子问题、生成阶段或工作流节点,
uncertainty: 不确定性来自模型分歧、槽位缺失还是证据冲突,
evidence_gap: 需要什么外部证据才能继续,
action: 是否检索、查什么、查哪里、如何验证
}

Self-RAG、FLARE、DRAGIN 这类方法的启发在于把检索放进生成过程,但落地时仍然要回答一个更朴素的问题:这次检索为什么发生。

GraphRAG 和 KG-RAG 则解决证据组织问题,把文本块升级为实体、关系、社区摘要和路径。它们适合跨文档、多跳、关系密集的场景,但不应该替代最基础的触发和验证机制。

工程闭环

第一版 Adaptive RAG 更适合先做显式 Retrieval Gate:

1
2
3
4
5
6
7
State Snapshot
-> Retrieval Gate(reason_code)
-> Query Builder(query, assumptions)
-> Hybrid Retriever(candidates)
-> Reranker(ranked_candidates)
-> Evidence Validator(supported / unsupported / conflict)
-> Generate or Rollback

Gate 不能只输出 yes/no。它至少要输出 reason code,例如 missing_factstale_contextentity_ambiguousevidence_conflictcost_guard。这样后续评测才能分清是不该检索却检索了,还是该检索却没检索。

评测也要拆成触发质量、证据质量和系统质量。尤其要看 evidence support rate,把“召回到了相似内容”和“召回到了能支撑答案的证据”区分开。没有这个指标,Adaptive RAG 很容易退化成 expensive RAG。

设计取舍

检索触发可以按强度分成五类。最弱的是固定触发,也就是每个问题都查;它稳定但成本高,且容易把相似但无关的片段带进上下文。第二类是显式控制信号,让模型在需要外部知识时发出 retrieve 请求。第三类是置信度或熵触发,用生成分布的不确定性作为信号。第四类是信息需求分类器,直接判断当前步骤是否需要外部证据。第五类是工作流路由,让不同节点决定是否进入检索分支。

这些方案没有绝对优劣。固定触发适合高召回冷启动,显式信号适合可解释训练闭环,置信度触发适合弱标注场景,信息需求分类适合离线评测,工作流路由适合复杂系统。真正的取舍,是在触发精度、漏检风险、检索成本和可调试性之间选平衡点。

query 构造也要谨慎。很多系统会让模型先猜一个中间结论,再拿这个结论去检索。这个策略在简单问题上有效,但在多跳问题里会把未验证假设写进检索条件。更稳的做法是把 query 写成待验证的信息需求,而不是已经相信的事实。

失败归因

Adaptive RAG 的常见失败不是没查到,而是系统不知道自己为什么查。如果触发器过敏,系统会在每个推理节点都检索,退化成高成本的固定 RAG。如果触发器保守,模型会在最需要事实校验时跳过检索。如果 query 由早期猜测生成,错误假设会被检索结果强化。如果证据接入没有分层,短证据会被长上下文稀释,模型最后仍然按自身偏好回答。

因此,调 Adaptive RAG 不应该先换 embedding 或向量库,而应该先看触发日志、query 变形和证据支持关系。retriever 是执行器,信息需求才是调度器。

小样本推演

假设模型正在回答一个依赖版本差异的问题:前半段推理可以来自已有上下文,但当它要给出具体接口行为时,当前状态暴露出 stale_contextmissing_fact 两个缺口。

这时 gate 不应该简单地说“检索 yes”,而要记录:缺的是版本证据,query 应围绕接口行为和版本号构造,召回结果必须能直接支持或推翻当前结论。如果检索后只拿到语义相似的教程,而没有版本证据,这次检索应被标为 unsupported,而不是继续塞进 prompt。

直接结论

Adaptive RAG 的核心不是“多检索几次”,而是让检索成为可记录、可回放、可评估的动作。第一版系统最应该做的是显式 Retrieval Gate:说明为什么触发,构造了什么 query,召回了哪些候选,证据是否支持当前结论,以及这次检索带来了多少延迟和成本。

只要这条链路清楚,后面再替换成 Self-RAG、FLARE、DRAGIN 或 GraphRAG,都有比较基线。否则系统只是把更多上下文交给模型碰运气。

下一步阅读:Adaptive RAG(二):Retrieval Gate 怎么判断该不该检索