Adaptive RAG:让 LLM 自己决定要不要检索 / 怎么检索
朴素 RAG 把所有问题都送去检索 = 慢 + 贵 + 噪声多。Adaptive RAG 让 LLM 先判断,再决定如何检索 / 检索几次 / 跳过检索。
L4-03 讲了”经典 RAG”——所有问题都走 embed → 检索 → 拼 prompt → LLM。 但生产系统会发现这个朴素管线有大问题:
- 问”你好” 也要检索?浪费一次 embedding + 数据库查询
- 问复杂研究问题,一次检索根本不够
- 问敏感话题,检索结果可能反而引入噪声
Adaptive RAG:让 LLM 先判断——再决定如何检索。
朴素 RAG vs Adaptive RAG
朴素 RAG(L4-03):
[问题] → embed → 向量检索 → top-k → 拼 prompt → LLM 答
Adaptive RAG:
[问题] → LLM 路由判断 → {
不需检索 → 直接答
简单检索 → 走经典 RAG
复杂检索 → 多轮 / 多源
需要工具 → 调 API(不只是文档)
}
4 种”路由策略”
1. No-retrieval(不检索)
适用:
- 简单寒暄:“你好” / “谢谢”
- 通用常识:“1+1 等于几”
- 模型已知答案:“Python 是什么”
判断方法:
- 让 LLM 自己说”我需要查资料吗?”
- 或者训一个小分类器判断
代码示例:
def needs_retrieval(query: str) -> bool:
prompt = f"""判断用户的问题是否需要查知识库。
返回 yes 或 no。
- 寒暄 / 通用常识 → no
- 公司 / 产品 / 具体事实 → yes
问题:{query}
答:"""
return "yes" in llm(prompt, max_tokens=5).lower()
省钱效果:在客服场景下能把”无效检索” 砍掉 30-50%。
2. Single-shot retrieval(单次检索)
经典 RAG,适用:
- 大多数事实查询
- “某产品的 X 参数是多少”
- “退款政策是什么”
3. Multi-hop retrieval(多跳检索)
适用复杂查询,需要多次检索 + 推理:
Q: "我去年买的产品现在还在保修期吗?"
↓
第 1 次检索:用户的订单("去年 3 月买了 X")
↓
第 2 次检索:X 产品的保修政策("2 年保修")
↓
LLM 推理:现在 2026-06,所以还在保修期
实现:ReAct 式循环
LLM 输出:thought + 下一个检索 query
执行检索
LLM 输出:基于结果决定是否继续 or 回答
4. Iterative refinement(迭代精化)
适用研究型 / 综合型查询:
Q: "对比 GPT-5 和 Claude 4 在编程上的差异"
↓
检索 1:GPT-5 编程能力 benchmark
检索 2:Claude 4 编程能力 benchmark
检索 3:差异 / 用户口碑对比
↓
LLM 综合答
不只是多次检索,还有自反思:
- 答完后让 LLM 检查”答案是否完整”
- 不完整 → 补充检索 / 答
路由判断的实现方式
A. LLM 路由(成本高但准)
直接让大 LLM 判断:
ROUTING_PROMPT = """根据用户问题类型,输出 ROUTING:
- chat → 简单寒暄
- simple_rag → 单次检索就够
- multi_hop → 需要多次检索 + 推理
- web_search → 需要联网(不是知识库)
- code_exec → 需要执行代码
仅输出一个标签。"""
成本:每次额外一次 LLM call。但省下的检索成本远大于这次 routing call。
B. 小分类器(便宜但需要训练)
用 distilbert / mini LM 训一个分类器:
from sentence_transformers import SentenceTransformer
import torch.nn as nn
class RouteClassifier(nn.Module):
# MiniLM → 5 个类别
...
# 训练数据:手标 500-1000 个 (query, route_label) 对
# 训完成本:每次 < 1ms,无 LLM call
适合高 QPS / 成本敏感场景。
C. 规则 + LLM 兜底
最朴素:
- 长度 < 10 字 → 大概率 chat
- 含日期 / 数字 / 专有名词 → 大概率 RAG
- 否则 → 让 LLM 判断
适合 MVP 阶段,3 天就能上线。
完整 Adaptive RAG 架构
[用户问题]
↓
[路由器(LLM 或分类器)]
↓
{
chat → direct LLM
simple_rag → embed → search → rerank → LLM
multi_hop → ReAct loop (search + reason)
web_search → live search API
code_exec → Python sandbox
}
↓
[Output formatter(统一格式)]
实战示例:客服系统
需求:
- 用户问寒暄 → 直接答
- 用户问产品 / 政策 → 经典 RAG
- 用户问”我的订单” → 调订单 API
- 用户问”对比 A 和 B” → 多次检索 + 综合
async def adaptive_answer(user_msg: str, user_id: str) -> str:
route = classify(user_msg) # LLM 或小模型
if route == "chat":
return llm.chat(user_msg)
if route == "order_query":
order = await get_user_order(user_id)
return llm.chat(f"用户订单: {order}\n问题: {user_msg}")
if route == "simple_rag":
chunks = retrieve(user_msg, k=3)
return llm.chat(f"文档:\n{chunks}\n问题: {user_msg}")
if route == "comparison":
# 多跳
sub_qs = decompose(user_msg) # LLM 拆问题
all_chunks = []
for q in sub_qs:
all_chunks.extend(retrieve(q, k=2))
return llm.chat(f"全部信息:\n{all_chunks}\n问题: {user_msg}")
性能 / 成本对比
假设客服场景,1000 次请求:
| 策略 | 总检索次数 | 总 LLM token | 月成本(估) |
|---|---|---|---|
| 朴素 RAG(每次都检索) | 1000 | 5M | $150 |
| + 简单 chat 路由 | 600 | 3.5M | $105 |
| + multi-hop(复杂任务效果更好) | 1200 | 4.5M | $135 |
| + small classifier(无 LLM 路由 cost) | 1200 | 4.2M | $125 |
同时质量上:multi-hop 在复杂查询上 +30-50% 准确率。
真实开源项目
| 项目 | 路线 |
|---|---|
| LlamaIndex Adaptive RAG | 内置 router + multi-hop |
| LangGraph | 用 graph 表达 Adaptive 路由 |
| DSPy | 用 prompt 编程方式定义 |
| Self-RAG(论文) | LLM 自我判断是否需检索 |
| Corrective RAG(论文) | 检索后判断”质量好不好”再决定补 |
何时不用 Adaptive RAG
- MVP 阶段:朴素 RAG 跑通再优化
- 流量极低:1 天 100 次以下,省那点钱不值开发成本
- 数据库本身极便宜:路由 cost > 检索 cost 时反而是负优化
- 用户问题极单一:所有问题都同类型,分流没意义
3 个工程经验
1. 从 2 类路由开始
不要一开始就 5 类——先 chat vs rag 两类,跑稳定后细分。
2. 路由准确率比 RAG 准确率重要
路由错了 = 整个流水线错。先把 routing accuracy 做到 > 95%。
3. 记录路由决策做 A/B
每次都记 (query, route, outcome) → 后续可以训分类器 / 改进 prompt。
推荐配套阅读
- HelloAI L4-03 RAG 从 0 到 1
- HelloAI L4-08 LLM 评估
- HelloAI L4-15 Prompt Caching
- 论文:Self-RAG (Asai 2023)
- 论文:Corrective RAG (Yan 2024)
朴素 RAG 是 0 → 1,Adaptive RAG 是 1 → 10。
朴素 RAG 让你”接上知识库”; Adaptive RAG 让你”在不同场景做对的事”。
任何上线超过 3 个月的 RAG 系统,都会自然演化到 Adaptive RAG—— 要么主动设计,要么被生产 bug 倒逼。
🚧 3 个常见坑
坑 1:路由 LLM 用最强模型 路由是简单分类,用 Sonnet / GPT-4 太贵。用 Haiku / mini / 自训小分类器即可。
坑 2:分类标签设计太细 8 类、10 类路由 = 路由 LLM 准确率掉 — 起步 2-3 类,必要时再细分。
坑 3:不监控 routing distribution 路由分布 drift 是常见——某天 chat 占比突然涨到 80%,说明用户行为变了 / 上游有 bug。
读到这里说明你认真在学 🎯
订阅每周精选 —— 下一篇新文章 / 新可视化第一时间送到邮箱。
讨论区
· 用 GitHub 账号登录评论src/components/Comments.astro 顶部填入
仓库 ID 和分类 ID(见组件注释里的配置步骤)。