AI Agent 核心架构总览:从 ReAct 循环到分层设计
面向想系统构建 Agent 的开发者。本文先给速查表建立全景认知,再逐层深入原理,最后给出架构设计原则。读完你能画出完整的 Agent 架构图,并能为每个层级做技术选型。
一、概念速查
1.1 什么是 AI Agent
AI Agent(智能体)是一个能自主感知环境、做出决策、执行行动的 AI 系统。与普通 LLM 调用的"问一句答一句"不同,Agent 能主动拆解目标、调用工具、多步推理、直至完成任务。
| 维度 | 普通 LLM 调用 | Agent 系统 |
|---|---|---|
| 交互方式 | 一问一答 | 多轮推理 + 行动循环 |
| 工具使用 | 无(纯文本输出) | 调用 API / 执行代码 / 搜索 |
| 记忆能力 | 仅上下文窗口 | 短期 + 长期记忆 |
| 任务自主性 | 被动响应 | 主动拆解 + 规划 |
| 输出形式 | 文本 | 行动 + 结果 + 文本 |
1.2 核心术语速查
| 术语 | 定义 |
|---|---|
| ReAct | 推理(Reasoning)+ 行动(Acting)交替循环的模式 |
| Function Calling | LLM 输出结构化参数以触发外部函数执行的机制 |
| MCP | Model Context Protocol,统一 Agent 接入外部工具的协议标准 |
| Tool / Skill | Agent 可调用的外部能力单元(搜索、计算、API) |
| Memory | 记忆模块,分短期(对话窗口)和长期(向量检索) |
| 编排(Orchestration) | 控制 Agent 下一步做什么的逻辑(循环、分支、并行、持久化) |
| State | 编排层共享的"黑板",所有节点读写同一份状态数据 |
1.3 架构分层速查
一个生产级 Agent 系统从底到顶分 4 层:
| 层级 | 核心职责 | 技术选型 |
|---|---|---|
| 编排层 | 控制流:Agent 循环、状态持久化、人机协同 | LangGraph / 阿里云百炼 / CrewAI |
| 模型层 | 推理引擎:理解指令、拆解任务、选择工具 | Qwen-Max / Qwen-Plus / GPT-4o |
| 工具层 | 能力扩展:搜索、计算、代码执行、API 调用 | MCP / Function Calling / Tavily |
| 记忆层 | 信息持久化:跨会话上下文、知识检索 | 向量库(Milvus / pgvector)+ 对话缓存 |
1.4 快速开始:一个完整的 ReAct Agent
下面用 LangGraph 实现一个带搜索能力的 Agent。这段代码覆盖了全部 4 层的协作方式:
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
# ── 编排层:定义状态("黑板"结构) ──
class AgentState(TypedDict):
messages: List[str]
next_action: str
# ── 工具层:定义外部能力 ──
def search_web(query: str) -> str:
"""搜索 API(示例用,实际接入 Tavily/SerpAPI)"""
return f"搜索结果:{query} 的相关信息"
# ── 模型层:LLM 推理节点 ──
def agent_node(state: AgentState):
"""模拟 LLM 决策——实际应调用 Qwen API"""
last = state["messages"][-1]
if "天气" in last:
return {"next_action": "call_tool", "messages": ["让我查一下天气"]}
return {"next_action": "respond", "messages": ["已获取足够信息"]}
# ── 工具执行节点 ──
def tool_node(state: AgentState):
result = search_web(state["messages"][-1])
return {"next_action": "continue", "messages": [result]}
# ── 编排层:组装图为 ReAct 循环 ──
graph = StateGraph(AgentState)
graph.add_node("agent", agent_node)
graph.add_node("tool", tool_node)
graph.set_entry_point("agent")
# 条件边——根据 next_action 决定走向
graph.add_conditional_edges(
"agent",
lambda s: s["next_action"],
{"call_tool": "tool", "respond": END}
)
graph.add_edge("tool", "agent") # 工具执行完回到 agent
app = graph.compile()
# ── 执行 ──
result = app.invoke({"messages": ["今天北京天气怎么样?"], "next_action": ""})
print(result["messages"])
# 输出: ["让我查一下天气", "搜索结果:今天北京天气的相关信息", ...]
关键设计点:
- State 是共享"黑板":agent_node 和 tool_node 读写同一份数据
- 条件边实现 ReAct 循环:agent 根据推理结果选择走向 tool 还是直接结束
- tool→agent 的回边:工具执行后回到 agent 做下一轮推理,构成闭环
二、底层原理
2.1 ReAct 循环:Agent 的"推理—行动"闭环
ReAct(Reasoning + Acting)是 2023 年 Google 提出的 Agent 范式,核心思想是让 LLM 交替输出推理轨迹和行动指令。
三轮循环详解:
| 阶段 | 输入 | 处理 | 输出 |
|---|---|---|---|
| Thought | 系统提示 + 对话历史 + 工具结果 | LLM 推理当前状态,决定下一步 | 自然语言推理 + 行动指令(函数调用或最终回答) |
| Action | Thought 阶段输出的函数名和参数 | 框架解析函数调用,执行对应工具 | 原始工具返回结果(数据 / 错误 / 空) |
| Observation | Action 执行的原始结果 | 格式化为 LLM 可读的文本 | 结构化的观察结果,喂回下一轮 Thought |
为什么非要用循环? 因为现实任务很少一步完成:第一次搜索可能不够精确,代码执行可能报错,需要多次"尝试→观察→调整"。典型的科研 Agent 可能需要 5-10 轮循环才能写出一份可靠的文献综述。
2.2 编排层:Agent 的控制中枢
编排层回答的核心问题是:下一步做什么?
核心能力矩阵:
| 能力 | 说明 | LangGraph 实现 | 百炼 实现 |
|---|---|---|---|
| 状态管理 | 维护对话上下文和中间变量 | State TypedDict + add_node | Session 变量 |
| 条件路由 | 根据 LLM 输出决定走向 | add_conditional_edges | Switch 节点 |
| 循环控制 | Thought→Action→Observe 闭环 | 有向图的循环边 | 循环节点 |
| 持久化 | 中断后恢复执行,不丢失状态 | Checkpointer + Thread | 快照机制 |
| 人机协同 | 插入人工审批节点 | NodeInterrupt | 审批节点 |
| 多 Agent | 多个 Agent 分工协作 | Subgraph / 跨 graph 通信 | 多 Agent 编排 |
LangGraph 为什么取代了 LangChain Chain?
LangChain Chain 是线性 DAG——A→B→C 一次走完,不支持循环。但 Agent 天然需要循环(工具结果不理想要重试、信息不够要再查)。LangGraph 用有向图替代链式结构,天然支持:
- 循环边:tool→agent 构成闭环
- 条件边:agent→tool 或 agent→END 根据推理结果分支
- 并行边:fan-out 同时调用多个工具
LangGraph 核心数据结构:
# State:图的"黑板",所有节点共享读写
class AgentState(TypedDict):
messages: List[BaseMessage] # 对话历史
intermediate_steps: List[Step] # 工具调用的中间结果
remaining_tries: int # 最大重试次数,防止死循环
# Node:图中的一个处理单元
def agent_node(state: AgentState) -> AgentState:
# 读取 state → LLM 推理 → 写回更新
return {"messages": new_messages}
# Edge:节点间的连接
graph.add_edge("node_a", "node_b") # 普通边:固定顺序
graph.add_conditional_edges("agent", router, {...}) # 条件边:分支
状态持久化的接入非常简单:
from langgraph.checkpoint.memory import MemorySaver
checkpointer = MemorySaver()
app = graph.compile(checkpointer=checkpointer)
# 使用 thread_id 隔离不同会话
result = app.invoke(
{"messages": ["查询2024年GDP"]},
config={"configurable": {"thread_id": "session_001"}}
)
# 中断后可恢复:用相同 thread_id 继续
result2 = app.invoke(
{"messages": ["再帮我跟2023年对比"]},
config={"configurable": {"thread_id": "session_001"}}
)
2.3 模型层:Agent 的推理引擎
Agent 场景对 LLM 的要求比普通对话更高。不是所有模型都适合做 Agent。
Agent 对 LLM 的核心能力要求:
| 能力 | 为什么重要 | 衡量方式 |
|---|---|---|
| 工具选择准确率 | 选错工具 = 任务直接失败 | 给 10 个工具看能否选对 |
| 参数提取精度 | 参数填错 = API 返回 400 | 测试不同格式输入下的参数提取 |
| 指令遵循 | 输出格式必须严格一致 | JSON / 函数调用格式一致性测试 |
| 多步推理 | 复杂任务需要 3-5 步推理链 | 多步推理任务的完整率 |
| 幻觉控制 | 一次幻觉可能带偏整个决策链 | Unknown 场景下拒绝回答的准确率 |
Qwen 系列在 Agent 场景的定位:
| 模型 | 适用场景 | 上下文窗口 | 成本 | 延迟 |
|---|---|---|---|---|
| Qwen-Max | 复杂推理、多步 Agent 任务 | 128K | 高 | 中 |
| Qwen-Plus | 日常 Agent 调用,性价比最优 | 128K | 中 | 低 |
| Qwen-Turbo | 高并发、简单工具调用 | 32K | 低 | 极低 |
| Qwen-Flash | 边缘设备、批量处理 | 32K | 极低 | 极低 |
选型策略: 核心 Agent 链路用 Qwen-Plus 起步;复杂推理场景升级 Qwen-Max;预处理/分类等简单任务用 Qwen-Turbo。不要所有场景用一个模型——既浪费钱又牺牲延迟。
2.4 工具层:Agent 的能力边界
Agent 的能力边界由工具决定——没有搜索工具,Agent 不知道最新信息;没有代码执行器,Agent 算不了精确数学。
工具调用的完整链路:
Function Calling 与 MCP 的分工:
| 维度 | Function Calling | MCP |
|---|---|---|
| 本质 | LLM 输出结构化参数的机制 | 工具集成协议标准 |
| 谁定义 | LLM 厂商(OpenAI / 百炼) | 社区(Anthropic 发起) |
| 工具注册 | 写在 System Prompt 的函数描述中 | 通过 MCP Server 动态注册 |
| 松耦合度 | 低——工具变更需要改 Prompt | 高——Server 独立部署,Agent 无需重启 |
| 生态 | 各厂商各自一套 | 统一协议,截至 2026 年已有 3000+ 工具 |
两者不是替代关系。Function Calling 解决的是"怎么说人话→转参数",MCP 解决的是"怎么找到工具→调用工具"。生产系统中两者共存:Function Calling 做参数提取,MCP 做工具发现和调用。
2.5 记忆层:跨会话的知识持久化
没有记忆的 Agent 每轮对话都是"初次见面"。
短期记忆(Working Memory):
- 形式:当前对话的完整消息列表
- 容量上限:LLM 上下文窗口(Qwen-Max 128K tokens)
- 超限策略:
- 滑动窗口:丢弃最早的消息,保留最近的 N 轮
- 摘要压缩:将旧消息压缩为一段摘要,释放上下文空间
长期记忆(Long-term Memory):
- 形式:向量数据库中的嵌入向量 + 元数据
- 存储内容:用户偏好、历史事实、项目上下文
- 检索策略:
| 策略 | 原理 | 适用场景 |
|---|---|---|
| 相似度检索 | 计算语义相似度,返回 Top-K | 通用场景,默认选项 |
| 时间衰减 | 越近的记忆权重越高,随时间降低分数 | 偏好类记忆(用户近期的选择更重要) |
| 重要性排序 | 为每条记忆标记重要性分数,优先返回高价值内容 | 关键事实(如用户的项目信息) |
混合记忆架构:
2.6 Agent vs Workflow:选型决策
这是架构设计的第一选择,定义清楚了才能往下走。
| 决策维度 | Workflow | Agent |
|---|---|---|
| 控制流定义方式 | 代码预定义路径 | LLM 动态决策 |
| 确定性 | 高——相同输入 = 相同执行路径 | 低——每次执行可能走不同路径 |
| 维护成本 | 低——逻辑固化在代码中 | 高——需要监控 LLM 决策质量 |
| 调试难度 | 低——逐行跟踪即可 | 高——需要 tracing 和日志 |
| 适用场景 | 已知路径的稳定流程 | 需要灵活应变的开放任务 |
| 典型例子 | 客服工单处理、数据 ETL 流水线 | 科研文献分析、代码生成 |
选型原则:能 Workflow 别 Agent。 把确定的部分固化到 Workflow 里,只把需要灵活决策的部分交给 Agent。这也是 Anthropic 官方推荐的最佳实践。一个常见模式是"外围 Workflow + 核心 Agent"——任务的编排骨架是固定的 Workflow,骨架上的关键节点由 Agent 动态填充。
三、架构设计原则
3.1 四层分离原则
每一层只关心自己的职责,不要跨层耦合:
- 编排层不写业务逻辑,只负责"下一步去哪里"
- 模型层不做工具调用,只负责推理和输出结构
- 工具层不参与决策,只负责执行和返回结果
- 记忆层不关心推理细节,只负责存储和检索
3.2 状态可追溯原则
Agent 的不确定性决定了必须做完整的执行追踪:
- 每一轮 Thought 的内容要记录
- 每一次 Tool 调用的输入输出要记录
- 支持按照 session_id 回放整个执行过程
LangGraph 的 Checkpointer + thread_id 天然支持这个模式。
3.3 防御性设计原则
Agent 系统的故障模式比传统软件多:
- 工具调用设超时:每个工具调用都要有 timeout,防止卡死
- 关键步骤设检查点:重要决策前插入人工审批
- 最大循环次数:防止 Agent 陷入死循环
- 输出校验:工具调用的参数做类型和范围校验
3.4 渐进式复杂度原则
不要一开始就上全功能 Agent:
- 先用 Workflow 跑通流程
- 把需要灵活决策的节点换成 Agent
- 给 Agent 加 Memory
- 加多 Agent 协作
- 加持久化和恢复
每一步都要验证"这一步真的需要吗"。

1572

被折叠的 条评论
为什么被折叠?



