RAG 的流水线搭完了:解析 → 切片 → 索引 → 检索 → 重排 → 生成 → 服务化。但这套系统有个本质局限——它是被动的。

用户问一句,它答一句。用户不问,它不动。它不会主动查天气、不会调 API、不会写数据库、不会在回答前先确认"你要的是 2024 年还是 2025 年的数据?"

Agent 要解决的就是这个问题:让 AI 从"回答者"变成"行动者"。


一、RAG vs Agentic RAG:本质区别在哪?

维度传统 RAGAgentic RAG
流程线性:检索 → 生成循环:感知 → 规划 → 行动 → 观察 → 再规划
工具无,只查向量库可调用搜索、API、数据库、代码解释器
决策无,固定流水线有,根据上下文决定下一步做什么
状态无状态,每轮独立有状态,记住历史动作和中间结果
适用场景知识问答复杂任务、多步推理、需要外部数据

一句话总结: 传统 RAG 是"查资料写答案",Agentic RAG 是"接到任务后自己想办法完成"。


二、Agent 的核心组件

一个 Agent 由四个基本零件组成,缺一不可:

1. 大脑(LLM + Prompt)

负责理解任务、做决策、规划步骤。这里的关键不是模型多大,而是 Prompt 里是否清晰定义了"你可以做什么"和"你该怎么做" 。

2. 工具集(Tools)

Agent 的"手"。每个工具是一个函数,有明确的输入输出签名。常见工具:

  • search_knowledge_base(query) — 查知识库
  • web_search(query) — 联网搜索
  • query_database(sql) — 查数据库
  • send_email(to, subject, body) — 发邮件
  • calculator(expression) — 计算器
3. 记忆(Memory)

Agent 需要记住:

  • 短期记忆:当前任务的历史对话和已执行的动作
  • 长期记忆:跨会话的用户偏好、历史经验(可选)
4. 规划器(Planner)

决定"下一步做什么"。有两种主流模式:

  • ReAct:Reason + Act,交替进行推理和行动
  • Plan-and-Execute:先列完整计划,再逐步执行

三、ReAct 模式详解:最经典的 Agent 循环

ReAct 的核心思想是:先想清楚再动手,每动一步再想想。

一个典型的 ReAct 循环长这样:

Thought: 用户想知道上季度销售额,我需要先查数据库。
Action: query_database("SELECT SUM(amount) FROM sales WHERE quarter='Q3'")
Observation: 1250000
Thought: 数据拿到了,但用户可能还想知道环比增长。
Action: query_database("SELECT SUM(amount) FROM sales WHERE quarter='Q2'")
Observation: 1100000
Thought: 环比增长 = (1250000-1100000)/1100000 = 13.6%
Final Answer: 上季度销售额为 125 万元,环比增长 13.6%。

关键点:LLM 每次输出都包含 Thought(思考)、Action(行动)、Observation(观察结果)三个部分,循环直到产出 Final Answer。


四、动手:用 LangGraph 搭建第一个 Agent

LangGraph 是目前最流行的 Agent 框架,它把 Agent 建模成一个状态图,每个节点是一个动作,边是决策逻辑。

下面是一个最小可用的 ReAct Agent 实现:

from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langchain_openai import ChatOpenAI
import operator

# 1. 定义状态
class AgentState(TypedDict):
    messages: Annotated[list, operator.add]  # 消息历史自动累加
    next_step: str  # 下一步动作

# 2. 定义工具
def search_knowledge_base(query: str) -> str:
    """搜索内部知识库"""
    # 这里替换成你实际的 RAG 检索逻辑
    return f"知识库中关于 '{query}' 的信息..."

def web_search(query: str) -> str:
    """联网搜索"""
    return f"网络搜索结果: {query}"

tools = {
    "search_knowledge_base": search_knowledge_base,
    "web_search": web_search,
}

# 3. 定义 LLM
llm = ChatOpenAI(model="gpt-4o", temperature=0)
llm_with_tools = llm.bind_tools([
    {"name": "search_knowledge_base", "description": "搜索内部知识库", "parameters": {"query": {"type": "string"}}},
    {"name": "web_search", "description": "联网搜索最新信息", "parameters": {"query": {"type": "string"}}},
])

# 4. 定义节点
def agent_node(state: AgentState):
    messages = state["messages"]
    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}

def tool_node(state: AgentState):
    last_message = state["messages"][-1]
    tool_calls = last_message.tool_calls
    results = []
    for tool_call in tool_calls:
        tool_name = tool_call["name"]
        tool_args = tool_call["args"]
        result = tools[tool_name](**tool_args)
        results.append(ToolMessage(content=result, tool_call_id=tool_call["id"]))
    return {"messages": results}

# 5. 定义路由逻辑
def should_continue(state: AgentState):
    last_message = state["messages"][-1]
    if last_message.tool_calls:
        return "tools"  # 还有工具要调用,继续
    return END  # 没有工具调用了,结束

# 6. 构建图
workflow = StateGraph(AgentState)
workflow.add_node("agent", agent_node)
workflow.add_node("tools", tool_node)
workflow.set_entry_point("agent")
workflow.add_conditional_edges("agent", should_continue, {"tools": "tools", END: END})
workflow.add_edge("tools", "agent")  # 工具执行完回到 agent

app = workflow.compile()

# 7. 运行
result = app.invoke({
    "messages": [HumanMessage(content="帮我查一下公司最新的报销政策,顺便搜一下同行是怎么做的")]
})
for msg in result["messages"]:
    print(msg.type, ":", msg.content[:100])

这段代码做了什么:

  1. LLM 收到问题后,决定调用 search_knowledge_base 和 web_search
  2. 工具节点执行两个函数,把结果写回状态
  3. LLM 看到工具返回的结果,整合成最终答案

五、Agent 的三个常见陷阱

1. 无限循环

Agent 可能陷入"调用工具 → 结果不满意 → 再调用同一个工具"的死循环。 解法:设置最大迭代次数(如 10 次),超时强制终止。

2. 工具参数幻觉

LLM 可能编造不存在的参数名或参数值。 解法:用 Pydantic 严格校验工具输入,参数不对直接报错让 LLM 重试。

3. 状态爆炸

长对话中消息历史越来越长,超出上下文窗口。 解法:定期压缩历史消息,只保留关键摘要。

      最后说一句,技术成长不只是写代码,职业规划和自我包装同样重要。我整理了一份简历、面试和职业规划的学习资料,适合想在职场上走得更远的朋友看看。

  资料展示

下面是我整理的AI大模型学习资料和工具包预览,适合收藏后按主题逐步学习。

AI大模型资料展示 1

AI大模型资料展示 2

AI大模型资料展示 3

如果你想看完整资料目录,可以在评论区留言「资料」;也欢迎告诉我你更关注AI大模型里的哪类内容。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐