AI Agent 系统设计:从单轮对话到多步推理的架构演进
AI Agent 系统设计:从单轮对话到多步推理的架构演进

一、大模型的"健忘"与"短视":Agent 系统的工程痛点
大语言模型在单轮问答中展现了令人印象深刻的能力,但一旦面对需要多步推理、工具调用、状态维护的复杂任务,其局限性便暴露无遗。模型没有持久记忆,每次对话都是无状态的;模型无法主动获取实时信息,知识截止于训练数据;模型缺乏行动能力,只能生成文本而不能执行操作。
这些局限催生了 AI Agent 系统的诞生。Agent 的核心思想是:将大模型从被动的文本生成器,升级为能够感知环境、制定计划、调用工具、反思结果的自主智能体。然而,从概念到工程落地的距离远比想象中遥远。
Agent 系统面临的核心工程痛点包括:第一,规划失败——多步任务中,模型生成的计划可能包含不可执行的步骤或逻辑矛盾;第二,工具调用错误——模型可能生成格式错误的 API 调用,或选择了不恰当的工具;第三,状态丢失——长链路推理中,早期关键信息被后续对话淹没,导致后续步骤偏离目标;第四,死循环——Agent 在错误路径上反复重试,消耗大量 Token 却无法收敛到正确结果。
二、ReAct 范式与记忆架构:Agent 系统的底层运行机制
现代 Agent 系统的运行机制,建立在 ReAct(Reasoning + Acting)范式之上。其核心循环是:观察环境状态 → 推理下一步行动 → 执行行动 → 观察执行结果 → 继续推理,直到任务完成或达到最大步数。
sequenceDiagram
participant U as 用户
participant A as Agent 核心
participant M as 记忆模块
participant P as 规划器
participant T as 工具集
U->>A: 提交任务指令
A->>M: 检索相关历史记忆
M-->>A: 返回上下文记忆
A->>P: 生成任务分解计划
loop ReAct 循环
P-->>A: 返回下一步行动
A->>A: 推理(Thought):分析当前状态
alt 需要调用工具
A->>T: 执行工具调用(Action)
T-->>A: 返回工具结果(Observation)
else 直接生成回答
A->>A: 生成最终回答
end
A->>M: 存储本轮交互记忆
A->>P: 更新计划状态
end
A->>M: 存储完整任务轨迹
A-->>U: 返回最终结果
记忆架构是 Agent 系统的关键基础设施。根据信息的生命周期与访问模式,记忆被划分为三个层次:
工作记忆(Working Memory):即当前对话上下文窗口中的信息,包括用户指令、历史推理步骤、工具返回结果。受限于上下文窗口长度,工作记忆是最稀缺的资源,需要通过摘要与淘汰策略管理。
短期记忆(Short-term Memory):跨对话轮次的任务状态,如当前执行到计划中的第几步、已获取的中间结果。通常以结构化 JSON 存储在会话状态中,供 Agent 在每轮推理时读取。
长期记忆(Long-term Memory):跨会话的知识与经验,如用户偏好、历史任务的成功模式。通常通过向量数据库实现语义检索,将相关记忆注入工作记忆中。
规划器(Planner)负责将复杂任务分解为可执行的子任务序列。常见的规划策略包括:一次性规划(生成完整计划后逐步执行)、自适应规划(每步执行后根据结果重新规划)、层次化规划(将任务分解为子目标树,逐层展开)。
三、生产级 Agent 框架:带反思与工具调用的完整实现
以下代码实现了一个基于 ReAct 范式的 Agent 框架,包含规划、工具调用、反思与记忆管理:
import json
import re
from typing import Callable, Dict, List, Optional
from dataclasses import dataclass, field
@dataclass
class Tool:
"""工具定义:名称、描述、参数 Schema 与执行函数"""
name: str
description: str
parameters: Dict
execute: Callable
@dataclass
class AgentState:
"""Agent 运行状态:维护推理链与任务进度"""
task: str
plan: List[str] = field(default_factory=list)
current_step: int = 0
thought_history: List[str] = field(default_factory=list)
action_history: List[str] = field(default_factory=list)
observation_history: List[str] = field(default_factory=list)
max_steps: int = 10
is_completed: bool = False
class ReActAgent:
"""基于 ReAct 范式的 Agent:推理-行动-观察循环"""
def __init__(self, llm_client, tools: Dict[str, Tool], memory_store=None):
self.llm = llm_client
self.tools = tools
self.memory = memory_store
def _build_prompt(self, state: AgentState) -> str:
"""构建包含历史推理链的提示词"""
prompt = f"任务: {state.task}\n\n"
# 注入相关长期记忆
if self.memory:
relevant = self.memory.retrieve(state.task, top_k=3)
if relevant:
prompt += "相关历史经验:\n"
for mem in relevant:
prompt += f"- {mem}\n"
prompt += "\n"
# 注入可用工具描述
prompt += "可用工具:\n"
for tool in self.tools.values():
prompt += f"- {tool.name}: {tool.description}\n"
prompt += f" 参数: {json.dumps(tool.parameters, ensure_ascii=False)}\n"
prompt += "\n"
# 注入历史推理链
for i, (thought, action, obs) in enumerate(zip(
state.thought_history, state.action_history, state.observation_history
)):
prompt += f"第{i+1}轮:\n"
prompt += f"思考: {thought}\n"
prompt += f"行动: {action}\n"
prompt += f"观察: {obs}\n\n"
prompt += "请输出下一步的思考和行动。格式:\n"
prompt += "思考: <你的推理过程>\n"
prompt += "行动: <工具名称>(<参数JSON>) 或 回答(<最终答案>)\n"
return prompt
def _parse_action(self, action_str: str) -> tuple:
"""解析行动字符串为工具名与参数"""
# 匹配 "工具名(参数)" 或 "回答(答案)"
match = re.match(r'(\w+)\((.*)\)', action_str.strip(), re.DOTALL)
if not match:
return "answer", action_str
tool_name = match.group(1)
params_str = match.group(2).strip()
if tool_name == "回答":
return "answer", params_str
try:
params = json.loads(params_str)
except json.JSONDecodeError:
params = {"raw_input": params_str}
return tool_name, params
def _reflect(self, state: AgentState) -> Optional[str]:
"""反思机制:检测是否陷入循环或偏离目标"""
if len(state.observation_history) < 2:
return None
# 检测连续相同观察(死循环信号)
last_two = state.observation_history[-2:]
if last_two[0] == last_two[1]:
return "检测到重复结果,需要换一种策略。"
# 检测步数过多但无进展
if state.current_step >= state.max_steps * 0.8 and not state.is_completed:
return f"已执行{state.current_step}步仍未完成,考虑简化方案或直接回答。"
return None
def run(self, task: str) -> str:
"""执行完整 Agent 循环"""
state = AgentState(task=task)
# 初始规划
plan_prompt = f"将以下任务分解为具体步骤:\n{task}\n输出JSON数组。"
plan_response = self.llm.generate(plan_prompt)
try:
state.plan = json.loads(plan_response)
except json.JSONDecodeError:
state.plan = [task]
for step in range(state.max_steps):
state.current_step = step + 1
# 反思检查
reflection = self._reflect(state)
if reflection:
state.thought_history.append(reflection)
# 生成推理与行动
prompt = self._build_prompt(state)
response = self.llm.generate(prompt)
# 解析思考与行动
thought_match = re.search(r'思考:\s*(.+?)(?=\n行动:)', response, re.DOTALL)
action_match = re.search(r'行动:\s*(.+)', response, re.DOTALL)
thought = thought_match.group(1).strip() if thought_match else response
action_str = action_match.group(1).strip() if action_match else ""
state.thought_history.append(thought)
state.action_history.append(action_str)
# 执行行动
tool_name, params = self._parse_action(action_str)
if tool_name == "answer":
state.is_completed = True
# 存储任务轨迹到长期记忆
if self.memory:
self.memory.store(task, {
"plan": state.plan,
"success": True,
"steps": state.current_step,
})
return params
if tool_name in self.tools:
try:
result = self.tools[tool_name].execute(**params)
observation = str(result)
except Exception as e:
observation = f"工具执行失败: {type(e).__name__}: {e}"
else:
observation = f"未知工具: {tool_name},可用工具: {list(self.tools.keys())}"
state.observation_history.append(observation)
return "达到最大步数限制,任务未完成。"
关键设计要点:反思机制在每步执行后检测死循环与进度停滞,主动引导 Agent 调整策略;工具调用包含完整的异常处理,将错误信息作为观察反馈给 Agent,使其能够根据错误信息修正行动;记忆模块在任务完成后存储成功轨迹,为后续相似任务提供经验参考。
四、Agent 系统的可靠性瓶颈:架构权衡与工程妥协
Token 消耗与推理深度的矛盾:每轮 ReAct 循环都需要将完整历史注入提示词,随着步数增加,Token 消耗呈线性增长。在 10 步以上的长链路任务中,Token 成本可能超过单次推理的 10 倍。解决方案包括:对历史推理链进行摘要压缩、使用滑动窗口保留最近 N 步、将中间结果结构化存储而非全文保留。
规划质量的不确定性:大模型生成的计划可能包含不可行步骤或逻辑跳跃。一次性规划在简单任务上效率高,但复杂任务中往往需要多次修正。自适应规划更鲁棒,但每步重新规划增加了延迟与 Token 消耗。实践中,推荐"粗粒度一次性规划 + 细粒度逐步执行"的混合策略。
工具调用的可靠性:模型可能生成格式错误的参数、调用不存在的工具、或选择不恰当的工具。严格的参数 Schema 校验与错误反馈机制是必要的,但过多的校验逻辑会增加系统复杂度。在工具数量较多时,工具选择的准确率会显著下降,需要通过工具描述优化与 few-shot 示例提升选择精度。
安全性与可控性:Agent 具备了执行行动的能力,也带来了安全风险。未经验证的工具调用可能产生不可逆的副作用(如删除数据、发送消息)。生产环境中必须实施工具调用的权限控制与审批机制,在自主性与安全性之间取得平衡。
五、总结
AI Agent 系统将大模型从被动生成器升级为自主智能体,ReAct 范式提供了推理-行动-观察的核心循环框架,记忆架构解决了状态持久化问题,反思机制增强了系统的自我纠错能力。然而,Agent 系统的可靠性仍受限于大模型的推理质量、工具调用的准确率与 Token 消耗的工程约束。
落地路线建议:从单工具 Agent 起步,验证 ReAct 循环的稳定性;逐步增加工具数量,同时优化工具描述与选择策略;引入反思与记忆机制提升长链路任务的成功率;在生产环境中实施工具调用的权限控制与审批流程。Agent 系统的构建是渐进式的,每一步都需要充分的测试与监控。
更多推荐
所有评论(0)