📌 回顾
上篇我们讲了模型部署与推理优化——如何用 vLLM 的 PagedAttention、连续批处理和 FP8 KV Cache 把微调完的模型跑起来。系列第二篇我们还搭过一个基础的 RAG 系统:向量化文档 → Chunk 存储 → 语义检索 → 拼接 Prompt → 生成回答。这种”单次检索 + 直给答案”的模式解决了很多问题,但也有明显的天花板。
这期我们把这个天花板捅破——从基础 RAG 进化到 Agentic RAG,让模型不再只是”搜到啥就答啥”,而是能自己决定什么时候搜、搜什么、搜完怎么推理。
一、基础 RAG 的四个天花板
系列第二篇我们做的 RAG 流程是固定的:
- 用户提问 → 2. 向量检索 → 3. 拼接上下文 → 4. 生成回答
这套流程在大多数场景下够用,但遇到下面这几种情况就扛不住了:
| 场景 | 基础 RAG 的问题 |
|---|---|
| 问题本身是错的/模糊的 | “那个 API 怎么用?”——”哪个 API?” 基础 RAG 不会反问,直接搜错方向 |
| 需要多步推理 | “对比 Qwen2.5 和 LLaMA 3 的上下文窗口区别”——需要搜两个模型的信息再对比,单次检索不够 |
| 检索结果不相关 | 搜到的 Top-K chunks 质量差,模型硬着头皮从垃圾信息里生成答案 |
| 需要查外部工具 | “今天北京天气怎么样”——知识库里没有实时数据,但你可以调天气 API |
Agentic RAG 的核心思路就是:不给模型定死”检索→生成”的流程,而是让模型自己决定每一步做什么。像 Agent 一样思考,像 RAG 一样检索。
二、Agentic RAG 的三种架构演进
从基础 RAG 到完整的 Agentic RAG,中间经历了几次架构迭代。我用一张表格说明演进路径:
| 架构 | 核心机制 | 能解决什么 | 复杂度 |
|---|---|---|---|
| 基础 RAG | 固定检索→生成 | 简单问答 | ★☆☆ |
| Adaptive RAG | 先判断是否需要检索,不需要就直接生成 | 避免不相关时硬检索 | ★★☆ |
| Multi-Hop RAG | 把问题拆成子问题,逐层检索+推理 | 多步推理、对比分析 | ★★★ |
| Agentic RAG | 完整的 ReAct 循环:思考→决策→执行(检索/计算/API)→观察→再思考 | 复杂推理+工具调用+自适应 | ★★★★ |
下面逐一实战。
2.1 Adaptive RAG:先判断要不要搜
最简单但最实用的改进。模型先判断问题是否需要外部知识:如果问的是”1+1=?”,模型可以直接答,不用浪费检索资源;如果问的是”Qwen2.5 的上下文长度”,才去检索。
判断逻辑可以用一条简单的 Prompt 实现:
def needs_retrieval(question: str) -> bool:
"""判断问题是否需要检索外部知识"""
prompt = f"""判断以下问题是否需要查询外部资料才能回答。
只需要回复 YES 或 NO。
问题:{question}"""
response = llm.invoke(prompt)
return response.strip().upper() == "YES"
# 使用
if needs_retrieval(user_question):
context = retrieve(user_question)
answer = generate_with_context(user_question, context)
else:
answer = llm.invoke(user_question)
这其实就是 Self-RAG 的简化版思想。完整版 Self-RAG 还会判断检索到的内容是否真的相关、以及生成的答案是否被检索内容支撑。
2.2 Multi-Hop RAG:拆解复杂问题
多跳(Multi-Hop)问题需要多步检索。比如:”Qwen2.5-7B 和 Qwen2.5-14B 的推荐显存是多少?”——你需要先搜 7B 的,再搜 14B 的,然后对比。
实现方式是让模型把主问题拆成多个子查询,分别检索后汇总:
sub_queries = decompose_question("对比 A 和 B 的区别")
# 返回: ["A 的技术规格", "B 的技术规格", "A 和 B 的对比"]
contexts = [retrieve(q) for q in sub_queries]
answer = generate(user_question, contexts)
arXiv 上最新的消融研究(2606.21553)用 Qwen2.5-7B 在 HotpotQA 上验证了这一点:两次检索迭代就能捕获 95% 的性能收益,五次以上几乎没增量。所以对本地模型来说,2-3 轮检索就够了,不是越多越好。
2.3 完整 Agentic RAG:ReAct 循环
这是最完整的形态。模型运行一个 ReAct(Reasoning + Acting) 循环:
- 思考(Thought)——分析当前问题,决定下一步做什么
- 行动(Action)——调用一个工具(检索、计算器、API 调用等)
- 观察(Observation)——拿到工具返回的结果
- 回到步骤 1,直到能给出最终答案
用 LangGraph 实现一个最简的 Agentic RAG 节点图如下:
from langgraph.graph import StateGraph
from typing import TypedDict, List
class AgentState(TypedDict):
messages: List # 对话历史
question: str
context: str
retrieved: bool
# 三个节点
def decide_retrieval(state: AgentState):
"""判断是否需要检索"""
return {"retrieved": needs_retrieval(state["question"])}
def retrieve_docs(state: AgentState):
"""执行检索"""
docs = vector_store.similarity_search(state["question"], k=3)
return {"context": "\n".join([d.page_content for d in docs])}
def generate_answer(state: AgentState):
"""生成回答"""
prompt = f"""基于以下上下文回答问题。
如果上下文不足以回答,请如实说明。
上下文:{state.get('context', '无')}
问题:{state['question']}"""
answer = llm.invoke(prompt)
return {"messages": [{"role": "assistant", "content": answer}]}
# 组装图
graph = StateGraph(AgentState)
graph.add_node("decide", decide_retrieval)
graph.add_node("retrieve", retrieve_docs)
graph.add_node("generate", generate_answer)
graph.set_entry_point("decide")
graph.add_conditional_edges(
"decide",
lambda state: "retrieve" if state["retrieved"] else "generate",
{"retrieve": "retrieve", "generate": "generate"}
)
graph.add_edge("retrieve", "generate")
这个图虽然简单,但已经包含了 Agentic RAG 的核心:条件判断 + 工具调用 + 生成。你可以在 retrieve 前加多个子问题分解节点,也可以在 generate 后加反思节点,形成一个完整循环。
三、生产环境方案推荐
如果不想手写 Agent 循环,业界已经有成熟的方案可以直接用:
| 框架 | 定位 | Agentic RAG 能力 | 适合场景 |
|---|---|---|---|
| LangGraph | 有向图 Agent 框架 | 完全自定义的 Agent 流程,细粒度控制 | 需要深度定制的研究型项目 |
| Dify ⭐146k | 可视化 AI 工作流平台 | 拖拽式 Agent + RAG workflow,开箱即用 | 快速原型、非技术团队 |
| RAGFlow ⭐83k | 企业级 RAG 引擎 | 内置 Agent 能力 + 深度文档解析 | 企业知识库、严格数据治理 |
有趣的是,同一篇 arXiv 论文对 Agentic RAG 做消融实验后发现:对本地 7B 模型来说,固定混合检索(稠密+稀疏向量 RRF 融合)的效果反而优于基于规则的动态路由,因为路由启发式会把命名实体误判为”需要检索”的信号,导致过度路由到 BM25。这个发现告诉我们:Agentic RAG 的复杂度不是越高越好,关键要看模型能力是否匹配架构复杂度。
总结
从基础 RAG 到 Agentic RAG 的演进,本质上是把”固定流程”变成了”动态决策”。核心三件事:Adaptive Retrieval(判断搜不搜)→ Multi-Hop Decomposition(拆解怎么搜)→ ReAct Loop(循环迭代)。但请记住:对于本地 7B 级别的模型,简短的检索循环 + 固定混合检索往往比花哨的 adaptive routing 更实用——不要把 Agent 架在模型能力够不到的高度。
下期预告:RAG 评估体系 —— 怎么量化你的 RAG 系统好不好?Retrieval 准不准?Generation 有没有幻觉?下一期我们从 Recall、Precision 到 Faithfulness 打分,全盘拆解。
参考资料
- Dissecting Agentic RAG: A Component Ablation for Multi-Hop QA with a Local 7B Model, arXiv:2606.21553 — https://arxiv.org/abs/2606.21553
- LangGraph Agentic RAG Tutorial — LangGraph Docs
- Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection, arXiv:2310.11511 — https://arxiv.org/abs/2310.11511
- RAGFlow — https://github.com/infiniflow/ragflow
- Dify — https://github.com/langgenius/dify
- HotpotQA: A Dataset for Diverse, Explainable Multi-hop Question Answering, arXiv:1809.09600 — https://arxiv.org/abs/1809.09600



