用户的问题往往不是「一次检索就能回答」的。它可能含糊、需要多跳、资料分散,甚至自相矛盾。Agentic RAG 让模型参与检索决策,而不是被动接收 top-k。
一次检索为什么不够
| 问题类型 | 例子 | 普通 RAG 的失败 |
|---|---|---|
| 指代/省略 | 「那它的价格呢?」 | 查询缺上下文,检不到 |
| 多跳 | 「CEO 母校所在城市的天气」 | 需要先查 CEO,再查城市 |
| 对比 | 「A 和 B 的政策差异」 | 只召回一方 |
| 覆盖不足 | 答案分散在 5 份文档 | top-k 只取到 2 份 |
| 冲突 | 两份文档说法不同 | 随机选一个,不说明冲突 |
| 需要计算 | 「按新政策能退多少」 | 检索到政策,但没算 |
Agentic RAG 的核心是:把检索当成一个可以反复调用的工具,由模型判断何时检索、检索什么、结果够不够。
五种模式
1. 查询改写
把口语化、含指代的问题改写成独立、可检索的查询:
对话:用户问「A1024 能退吗」,客服答「可以」,用户问「那要多久?」
改写:「订单 A1024 的退款到账需要多久?」也可以生成多个查询变体(Multi-Query),分别检索后合并。
2. 查询分解
把复杂问题拆成子问题:
原问题:对比 ACME 与 Beta 的退款政策,并说明对跨境订单的影响。
子问题:
1. ACME 的退款政策是什么?
2. Beta 的退款政策是什么?
3. 两家政策对跨境订单分别怎么规定?每个子问题独立检索,再综合。注意子问题之间可能有依赖,需要按顺序。
3. 迭代检索
关键是停止条件:
- 最多 N 轮(通常 2–4 轮);
- 新检索没有带来新信息;
- 预算耗尽;
- 已能回答且引用充分。
没有停止条件,Agent 会一直「再查一下」,成本失控。
4. 自我反思(Self-RAG 风格)
让模型对检索结果和草稿做检查:
- 这个段落与问题相关吗?(相关性)
- 它支持这个结论吗?(支撑性)
- 回答是否引入了资料外的内容?(忠实性)
- 是否还有未覆盖的子问题?(完整性)
不通过就补充检索或修改答案。注意:反思必须有外部信号,否则只是自我肯定(见〈反思〉)。
5. 多源路由
不同问题查不同来源:
政策问题 → 政策库
订单问题 → 订单 API
产品问题 → 产品文档
时效问题 → 公告/FAQ路由器可以是规则、分类模型或 LLM。路由错误比检索错误更致命——查错库,怎么排都好不了。
GraphRAG:什么时候值得
当问题需要跨文档的实体关系或全局总结时,向量检索很吃力:
- 「这个供应商和哪些子公司有交易?」
- 「过去一年所有客户投诉的共同主题是什么?」
GraphRAG 先从文档抽取实体与关系,构建知识图谱,再用图遍历或社区摘要回答。代价:
- 抽取成本高,且会出错;
- 图谱维护复杂;
- 更新不如向量索引灵活。
适合实体关系密集、问题相对稳定的领域(法律、供应链、金融)。不适合快速变化的通用问答。
一个最小实现
def agentic_rag(question: str, max_rounds: int = 3):
queries = rewrite(question)
evidence = []
seen = set()
for round_no in range(max_rounds):
for q in queries:
for doc in hybrid_search(q, top_k=8):
if doc.id not in seen:
seen.add(doc.id)
evidence.append(doc)
assessment = assess(question, evidence)
if assessment.sufficient:
break
if not assessment.missing:
break
queries = rewrite_for_gaps(question, evidence, assessment.missing)
if not evidence:
return "根据现有资料无法回答。", []
answer = generate(question, evidence, require_citations=True)
if not citations_valid(answer, evidence):
answer = generate(question, evidence, strict=True)
return answer, evidenceassess 是一个结构化输出调用:
{
"sufficient": false,
"missing": ["Beta 的跨境订单条款"],
"conflicts": [],
"next_queries": ["Beta refund policy cross-border"]
}成本控制
Agentic RAG 的调用次数可能是普通 RAG 的 3–5 倍。控制手段:
- 按难度路由:简单问题走普通 RAG,复杂问题才启用多轮;
- 限制轮数:2–4 轮,硬上限;
- 缓存:相同查询的检索结果、重排结果缓存;
- 并行子查询:独立的子问题同时检索;
- 小模型做判断:充分性评估、查询改写用便宜模型;
- 预算:按任务设置 token/金额上限。
一个实用策略:先用一次普通 RAG 生成答案,同时让模型判断置信度;只有低置信或检测到多跳时才进入迭代。这样大多数请求保持低成本。
评估
除了普通 RAG 的指标,还要看:
- 检索轮数分布:平均值与 P95;
- 新增证据的边际收益:第 2、3 轮是否真的提升了答案;
- 停止决策准确率:该停时停、该继续时继续;
- 子问题覆盖率:分解是否遗漏;
- 冲突处理:是否识别并说明矛盾。
构造测试集时,专门加入需要 2–3 跳的问题,以及「资料不足」的问题。后者能检验它是否会编。
反模式
每轮都检索、每轮都重排,成本翻倍但答案没变好。用「新信息量」判断是否继续。
模型倾向于高估自己掌握的信息。用外部信号:引用覆盖、子问题清单、检索分数。
两份文档说法不同,直接选一个。应该明确指出冲突、给出来源与时间,让用户判断。
把问题拆成 12 个子问题,每个都检索。限制分解数量,优先合并。
小结
- Agentic RAG 把检索变成可决策、可迭代的动作。
- 五种手段:改写、分解、迭代、反思、路由;GraphRAG 用于关系密集场景。
- 停止条件与预算比「多查几轮」更重要。
- 简单问题不要用复杂管线,按难度路由。
- 评估要看轮数收益、停止准确率和冲突处理。
下一篇讲连接外部世界的标准协议:MCP。