5.6 Agent 设计模式总结
在 5.5 节中,我们深入探讨了 Agent 的反思机制——它让 Agent 从"只顾执行"进化为"边执行、边审视、边改进"的闭环系统。反思赋予 Agent 自我纠错的能力,但一个关键问题随之浮现:反思应该嵌入在哪个架构层次中? 是每一步都反思,还是阶段性地回顾?又或者由专门的 Agent 负责审视全局?这个问题的答案,正是 Agent 设计模式要回答的。
如果把构建一个 Agent 系统比作建造一栋大楼,那么设计模式就是建筑师手中的建筑图纸。同样是一堆砖瓦(LLM、工具、记忆、规划),不同的图纸会产出截然不同的建筑——可以是精巧的单层小屋(ReAct),可以是层层递进的高楼(Plan-Execute-Reflect),也可以是功能分区明确的大型综合体(Autonomous Multi-Agent)。图纸本身没有绝对的好坏,关键在于地基(任务复杂度)、用途(应用场景)和预算(资源约束)是否匹配。
本节作为第 5 章的收官,将系统梳理前面各节涉及的 Agent 设计模式,从最基础的 ReAct 到最复杂的 Autonomous 架构,逐一剖析其核心思想、适用场景与工程实践要点,并在最后给出模式选型的决策框架。
5.6.1 设计模式全景:从建筑图纸说起
在软件工程领域,"设计模式"一词源自建筑学家 Christopher Alexander 的经典著作《建筑的永恒之道》。他指出:"每一个模式描述了一个在我们周围环境中反复出现的问题,以及该问题的解决方案的核心。" 这句话同样适用于 Agent 架构。
Agent 设计模式本质上是对"如何组织 LLM 的推理、工具调用与反思"这一反复出现问题的抽象解答。我们可以用建筑图纸的层次来理解它们的递进关系:
| 图纸层次 | 建筑类比 | Agent 设计模式 | 核心特征 |
|---|---|---|---|
| 一层平房 | 功能单间,即用即走 | ReAct | 思考-行动-观察循环,适合探索性任务 |
| 多层楼房 | 先画蓝图再施工 | Plan-Execute-Reflect | 规划→执行→反思三阶段分离 |
| 商业综合体 | 多栋楼协同运营 | Autonomous Multi-Agent | 多角色自治,可长期运行 |
这三类模式并非互斥,而是可以层层嵌套:一栋综合体的内部可能有多个楼层,每个楼层可能用的是 ReAct 循环。理解了这层关系,就掌握了 Agent 架构设计的核心方法论。
下面我们逐一展开。
5.6.2 ReAct 模式:边想边做的基础循环
核心思想。 ReAct(Reasoning + Acting)将推理(Thought)和行动(Action)紧密交织:Agent 先"想"一步,再"做"一步,根据观察结果(Observation)决定下一步怎么走。这是最直觉的 Agent 范式,也是所有更复杂模式的基石。
ReAct 循环:
┌──────────────────────────────────────────────────┐
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Thought │────▶│ Action │ │
│ │ (思考) │ │ (行动) │ │
│ └──────────┘ └────┬─────┘ │
│ ▲ │ │
│ │ ┌───────▼──────┐ │
│ │ │ Observation │ │
│ └────────│ (观察) │ │
│ └──────────────┘ │
│ │
│ 重复直到任务完成或达到最大迭代次数 │
└──────────────────────────────────────────────────┘何时选择 ReAct。 当任务路径不确定、需要根据中间结果动态调整策略时,ReAct 的"走一步看一步"策略最为灵活。典型场景包括:探索性研究、Bug 调试、实时信息查询与综合。
局限性。 每一步都需要 LLM 参与决策,token 消耗和延迟随步数线性增长;缺乏全局规划能力,在长链任务中容易"迷路"。
以下是使用 LangGraph 实现的 ReAct Agent 核心代码,逐行注释如下:
# ─── 导入依赖 ──────────────────────────────────────
from langgraph.graph import StateGraph, END # 状态图构建器与终止节点
from langgraph.prebuilt import ToolNode # LangGraph 预置的工具执行节点
from langchain_openai import ChatOpenAI # OpenAI 聊天模型封装
from langchain_core.messages import HumanMessage, AIMessage # 消息类型
from typing import TypedDict, Annotated, List # 类型注解工具
import operator # 用于定义状态合并策略
# ─── 定义状态结构 ──────────────────────────────────
class ReActState(TypedDict):
# messages 字段使用 operator.add 作为 reducer,
# 表示新消息会追加到列表末尾而非替换
messages: Annotated[List, operator.add]
# ─── 定义工具函数 ──────────────────────────────────
def search(query: str) -> str:
"""模拟搜索工具:接收查询字符串,返回模拟的搜索结果"""
return f"搜索结果: 关于'{query}'的最新信息..."
def calculate(expression: str) -> str:
"""计算工具:安全地计算数学表达式并返回结果"""
try:
return f"计算结果: {eval(expression)}" # 实际生产环境应使用 ast.literal_eval
except Exception as e:
return f"计算错误: {e}"
# 将工具函数组装成列表,并创建 ToolNode
tools = [search, calculate] # 注册两个工具
tool_node = ToolNode(tools) # LangGraph 预置的批量工具执行节点
# ─── 初始化 LLM 并绑定工具 ─────────────────────────
llm = ChatOpenAI(model="gpt-4o", temperature=0) # temperature=0 保证输出稳定
llm_with_tools = llm.bind_tools(tools) # 将工具描述注入 LLM 的 function-calling 接口
# ─── 定义节点函数 ──────────────────────────────────
def call_model(state: ReActState):
"""LLM 推理节点:读取当前消息历史,调用 LLM 生成下一步响应"""
messages = state["messages"] # 获取完整对话历史
response = llm_with_tools.invoke(messages) # LLM 决定是回答还是调用工具
return {"messages": [response]} # 将响应追加到 messages 列表
def should_continue(state: ReActState):
"""条件路由节点:判断是否还需要执行工具"""
last_message = state["messages"][-1] # 取最近一条消息
# 如果 LLM 返回了 tool_calls,说明它想调用工具,路由到 "tools" 节点
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
return "tools"
# 否则说明 LLM 已给出最终答案,结束循环
return END
# ─── 构建状态图 ────────────────────────────────────
workflow = StateGraph(ReActState) # 以 ReActState 为状态类型创建状态图
workflow.add_node("agent", call_model) # 添加 LLM 推理节点
workflow.add_node("tools", tool_node) # 添加工具执行节点
workflow.set_entry_point("agent") # 入口节点为 "agent"
# 从 agent 出发:如果需要工具则去 "tools",否则去 END
workflow.add_conditional_edges("agent", should_continue, {"tools": "tools", END: END})
# 工具执行完毕后回到 agent,形成循环
workflow.add_edge("tools", "agent")
app = workflow.compile() # 编译为可执行的 LangGraph 应用
# ─── 运行 Agent ────────────────────────────────────
result = app.invoke({
"messages": [HumanMessage(
content="计算 (25+15)*3 的结果,并搜索一下'AI Agent 2024'的最新信息"
)]
})
# ─── 输出最终结果 ──────────────────────────────────
for msg in result["messages"]:
if isinstance(msg, AIMessage) and not hasattr(msg, "tool_calls"):
print(f"🤖 最终回答: {msg.content}")这段代码体现了 ReAct 模式的精髓:一个仅含两个节点的循环图——agent(思考)和 tools(行动),由 should_continue 函数充当"交通灯",在"继续探索"与"给出答案"之间动态切换。
5.6.3 Plan-Execute-Reflect 模式:先画蓝图再施工
如果说 ReAct 是"走一步看一步"的即兴发挥,那么 Plan-Execute-Reflect 就是"先画蓝图、再按图施工、完工后验收"的工程化流程。该模式将 Agent 的工作分为三个阶段:
- Plan(规划):LLM 一次性分析任务全貌,输出结构化的步骤列表。
- Execute(执行):按计划逐步(或并行)执行,每步可调用工具。
- Reflect(反思):检查执行结果是否达标,必要时触发重规划(Replan)。
┌──────────────────────────────────────────────────────────┐
│ Plan-Execute-Reflect 工作流 │
│ │
│ ┌──────────┐ │
│ │ Plan │ 一次性生成完整计划 │
│ │ (规划器) │ Step1 → Step2 → Step3 → Step4 │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Execute │ │ Step1 │ │ Step2 │ │ Step3 │ (并行) │
│ │ (执行器) │ └───┬────┘ └───┬────┘ └───┬────┘ │
│ │ │ └─────┬─────┘ │ │
│ │ │ ▼ │ │
│ │ │ ┌────────┐ │ │
│ │ │ │ Step4 │ (依赖 Step1,2) │
│ │ │ └───┬────┘ │ │
│ └──────────┘ │ │ │
│ │ ▼ ▼ │
│ ┌──────────┐ ┌──────────────────────┐ │
│ │ Reflect │◀───│ 检查结果是否达标? │ │
│ │ (反思器) │ │ 是 → 输出 / 否 → 重规划│ │
│ └──────────┘ └──────────────────────┘ │
└──────────────────────────────────────────────────────────┘与 ReAct 的关键区别。 ReAct 每一步都让 LLM 参与决策(约 N×2 次调用),而 Plan-Execute-Reflect 只在规划阶段调用 1 次 LLM 生成全量计划,执行阶段交由轻量函数处理,最后再调用 1 次做反思——总调用次数约为 2-4 次,在可预测任务上成本优势显著。
下面用一个对比基准测试来量化两种模式的差异,代码逐行注释:
import time
from dataclasses import dataclass
from typing import List
@dataclass
class AgentMetrics:
"""Agent 性能指标数据类"""
name: str # 模式名称
llm_calls: int # LLM 调用次数(与成本正相关)
execution_time: float # 总执行时间(秒)
tokens_used: int # 消耗的 token 数
task_completed: bool # 任务是否成功完成
class AgentBenchmark:
"""ReAct 与 Plan-Execute 的对比基准测试"""
def __init__(self):
self.results = [] # 存储所有测试结果
def simulate_react(self, task_steps: int, uncertainty: float) -> AgentMetrics:
"""模拟 ReAct 模式的开销"""
# 每步需要 Thought + Action 两次 LLM 调用,
# 不确定性越高,额外调整的次数也越多
llm_calls = task_steps * 2 + int(uncertainty * task_steps)
execution_time = llm_calls * 0.5 # 每次调用约耗时 0.5 秒
tokens_used = llm_calls * 500 # 每次调用约消耗 500 token
return AgentMetrics(
name="ReAct",
llm_calls=llm_calls,
execution_time=execution_time,
tokens_used=tokens_used,
task_completed=True # ReAct 在高不确定性下仍能适应
)
def simulate_plan_execute(self, task_steps: int, uncertainty: float) -> AgentMetrics:
"""模拟 Plan-Execute-Reflect 模式的开销"""
# 规划 1 次 + 反思 1 次 + 可能的重规划
replans = max(0, int(uncertainty * 3) - 1) # 不确定性越高,重规划越多
llm_calls = 1 + replans + 1 # 规划 + 重规划 + 反思
execution_time = llm_calls * 0.5 + task_steps * 0.1 # 执行步骤本身很快
tokens_used = llm_calls * 800 # 规划型调用 token 更多
return AgentMetrics(
name="Plan-Execute",
llm_calls=llm_calls,
execution_time=execution_time,
tokens_used=tokens_used,
task_completed=uncertainty < 0.5 # 不确定性高时计划容易失效
)
def run_benchmark(self):
"""运行对比基准测试"""
scenarios = [
{"task": "简单信息查询", "steps": 3, "uncertainty": 0.1},
{"task": "数据分析报告", "steps": 5, "uncertainty": 0.3},
{"task": "复杂问题排查", "steps": 7, "uncertainty": 0.7},
{"task": "探索性研究", "steps": 10, "uncertainty": 0.9},
]
for s in scenarios:
for sim in [self.simulate_react, self.simulate_plan_execute]:
m = sim(s["steps"], s["uncertainty"])
print(f"{s['task']:<12} {m.name:<14} "
f"调用:{m.llm_calls:<4} 耗时:{m.execution_time:.1f}s "
f"Token:{m.tokens_used:<6} "
f"{'✅' if m.task_completed else '❌'}")
print()
AgentBenchmark().run_benchmark()运行上述基准测试后,你会看到一个清晰的趋势:低不确定性场景下 Plan-Execute 以极少的 LLM 调用完成任务,而高不确定性场景下 ReAct 更可靠但成本翻倍。 这正是模式选型的核心权衡。
5.6.4 Autonomous 多 Agent 协作模式:综合体式的自治系统
当任务的复杂度超出单个 Agent 的能力边界时——例如"收集数据 + 分析趋势 + 撰写报告 + 制作 PPT"这样的复合型工作——我们需要多栋"建筑"协同运作,这就是 Autonomous 多 Agent 模式。
三种协作架构。 多 Agent 之间的协作关系可分为三种拓扑:
┌──────────────────────────────────────────────────────┐
│ 1. 顺序协作(Sequential) │
│ Agent A ──▶ Agent B ──▶ Agent C ──▶ 输出 │
│ (数据收集) (数据分析) (报告生成) │
│ │
│ 2. 层级协作(Hierarchical) │
│ ┌── Supervisor ──┐ │
│ │ (监督调度) │ │
│ └─┬───┬───┬─────┘ │
│ ┌─────┘ │ └─────┐ │
│ ┌────▼────┐ ┌──▼──┐ ┌───▼───┐ │
│ │Agent A │ │Agent│ │Agent C│ │
│ │ 搜索 │ │ 分析│ │ 写作 │ │
│ └─────────┘ └─────┘ └───────┘ │
│ │
│ 3. 辩论协作(Debate) │
│ Agent A ──▶ 提出方案 │
│ Agent B ──▶ 质疑/批评 ──▶ 多轮迭代 ──▶ Judge │
│ Agent A ──▶ 改进方案 │
└──────────────────────────────────────────────────────┘- 顺序协作最简单,上游的输出直接作为下游的输入,适合流水线式任务。
- 层级协作引入 Supervisor 负责调度,适合需要动态分配子任务的中等复杂度场景。
- 辩论协作通过对抗式对话提升方案质量,适合需要多角度论证的决策类任务。
主流框架对比。
| 框架 | 核心理念 | 协作方式 | 适用场景 |
|---|---|---|---|
| AutoGen | 对话即编程 | 消息传递 | 代码生成、复杂工作流 |
| CrewAI | 角色扮演 | 任务委派 | 模拟团队协作 |
| LangGraph | 图编排 | 状态管理 | 自定义复杂流程 |
| OpenAI Swarm | 轻量多Agent | 交接转移 | 客服路由、简单协作 |
下面是用 LangGraph 实现顺序协作多 Agent 的核心代码,逐行注释:
# ─── 导入与状态定义 ──────────────────────────────────
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage
from typing import TypedDict, Annotated, List
import operator
class MultiAgentState(TypedDict):
"""多 Agent 共享状态"""
messages: Annotated[List, operator.add] # 消息历史(追加式)
next_agent: str # 下一个要执行的 Agent
task: str # 用户原始任务描述
# ─── 初始化 LLM ─────────────────────────────────────
llm = ChatOpenAI(model="gpt-4o", temperature=0)
# ─── 定义三个角色的 Agent ───────────────────────────
def researcher(state: MultiAgentState):
"""研究员 Agent:负责信息收集"""
response = llm.invoke([
HumanMessage(content=f"你是一个研究员。请为以下任务收集相关信息。\n\n"
f"任务:{state['task']}\n\n请提供关键数据和事实。")
])
return {
"messages": [AIMessage(content=f"📊 [研究员]: {response.content}")],
"next_agent": "analyst" # 指定下一步交给分析师
}
def analyst(state: MultiAgentState):
"""分析师 Agent:负责数据分析"""
context = state["messages"][-1].content # 获取研究员的输出
response = llm.invoke([
HumanMessage(content=f"你是一个数据分析师。请分析以下研究结果。\n\n"
f"研究结果:{context}\n\n请提供深度分析和洞察。")
])
return {
"messages": [AIMessage(content=f"📈 [分析师]: {response.content}")],
"next_agent": "writer" # 指定下一步交给撰稿人
}
def writer(state: MultiAgentState):
"""撰稿人 Agent:负责报告撰写"""
# 获取最近两条消息(研究员 + 分析师)作为上下文
context = "\n".join([m.content for m in state["messages"][-2:]])
response = llm.invoke([
HumanMessage(content=f"你是一个专业撰稿人。请基于以下分析撰写报告。\n\n"
f"{context}\n\n请生成结构化的最终报告。")
])
return {
"messages": [AIMessage(content=f"📝 [撰稿人]: {response.content}")],
"next_agent": END # 任务完成
}
# ─── 构建多 Agent 协作图 ─────────────────────────────
workflow = StateGraph(MultiAgentState)
workflow.add_node("researcher", researcher) # 注册研究员节点
workflow.add_node("analyst", analyst) # 注册分析师节点
workflow.add_node("writer", writer) # 注册撰稿人节点
workflow.set_entry_point("researcher") # 从研究员开始
# 条件路由:根据 next_agent 字段决定下一个节点
def route_agent(state: MultiAgentState):
return state["next_agent"]
workflow.add_conditional_edges("researcher", route_agent, {"analyst": "analyst"})
workflow.add_conditional_edges("analyst", route_agent, {"writer": "writer"})
workflow.add_conditional_edges("writer", route_agent, {END: END})
app = workflow.compile() # 编译为可执行应用
# ─── 运行多 Agent 系统 ──────────────────────────────
result = app.invoke({
"messages": [],
"task": "分析2024年AI Agent的技术发展趋势"
})
for msg in result["messages"]:
print(f"\n{msg.content[:300]}...")这段代码的精妙之处在于:三个 Agent 各司其职,通过 next_agent 字段实现"接力棒"传递,而 messages 列表作为共享"黑板"让后继 Agent 可以看到前序 Agent 的全部输出。这种"共享黑板 + 显式路由"的模式正是 LangGraph 多 Agent 编排的核心范式。
5.6.5 模式选型决策框架
面对一个具体任务,如何选择合适的设计模式?下面的决策树给出了系统化的判断路径:
开始
│
├─ 任务步骤是否明确且可预测?
│ ├─ 是 ──▶ 步骤之间是否存在依赖关系?
│ │ ├─ 无依赖(可并行)──▶ Plan-Execute-Reflect(并行执行)
│ │ └─ 有依赖(顺序执行)──▶ Plan-Execute-Reflect(顺序执行)
│ │
│ └─ 否 ──▶ 任务是否超出单个 Agent 能力?
│ ├─ 是 ──▶ 需要 Supervisor 调度?
│ │ ├─ 是 ──▶ Autonomous 多 Agent(层级协作)
│ │ └─ 否 ──▶ Autonomous 多 Agent(顺序协作)
│ │
│ └─ 否 ──▶ 是否需要严格质量控制?
│ ├─ 是 ──▶ ReAct + Reflection(每步反思)
│ └─ 否 ──▶ ReAct(标准循环)选型速查表。
| 任务特征 | 推荐模式 | 理由 |
|---|---|---|
| 简单查询,1-3步 | ReAct | 轻量灵活,无需规划开销 |
| 明确流程,步骤多 | Plan-Execute | 一次规划,高效执行 |
| 不确定性高,需探索 | ReAct + Reflection | 动态调整 + 自我纠错 |
| 跨领域,需专业分工 | Multi-Agent | 各角色专业化,质量更高 |
| 需要多角度论证 | Debate | 对抗式辩论提升决策质量 |
| 长期运行,自主决策 | Autonomous | 全局编排 + 持续运行 |
自动化选型工具。 在实际工程中,可以构建一个智能选择器,让 LLM 先分析任务特征再推荐模式:
class AgentPatternSelector:
"""根据任务特征自动推荐 Agent 设计模式"""
def __init__(self, llm):
self.llm = llm # 注入 LLM 实例
def analyze_task(self, task: str) -> dict:
"""让 LLM 分析任务的五个维度"""
prompt = f"""分析以下任务的特征,返回JSON格式:
任务:{task}
返回字段:
- complexity: low/medium/high(复杂度)
- predictability: low/medium/high(可预测性)
- parallelizable: true/false(是否可并行)
- requires_specialization: true/false(是否需专业分工)
- suggested_steps: 3-10(预估步骤数)
只返回JSON。"""
response = self.llm.invoke([HumanMessage(content=prompt)])
import json
content = response.content
if "```json" in content: # 处理 markdown 包裹的 JSON
content = content.split("```json")[1].split("```")[0]
return json.loads(content)
def select_pattern(self, task: str) -> dict:
"""基于分析结果推荐设计模式"""
analysis = self.analyze_task(task)
if analysis.get("requires_specialization"):
pattern, reason = "Multi-Agent", "任务需要多个专业领域协作"
elif analysis.get("predictability") == "high" and analysis.get("parallelizable"):
pattern, reason = "Plan-Execute (并行)", "可预测且可并行,效率最优"
elif analysis.get("predictability") == "high":
pattern, reason = "Plan-Execute", "可预测,适合先规划后执行"
elif analysis.get("complexity") == "low":
pattern, reason = "ReAct (轻量)", "简单任务,轻量级 ReAct 即可"
else:
pattern, reason = "ReAct + Reflection", "复杂且不确定,需动态调整和反思"
return {"pattern": pattern, "reason": reason, "analysis": analysis}5.6.6 常见误区
在 Agent 架构设计的实践中,以下误区值得警惕:
误区一:上来就用最复杂的多 Agent 架构。
很多开发者一看到 Multi-Agent 框架的强大能力,就迫不及待地将所有任务都套上多 Agent 模式。这就像盖一个简易传达室却用了摩天大楼的结构设计——不仅大材小用,还引入了不必要的通信开销和调试复杂度。
正确做法: 从 ReAct 开始,当且仅当单个 Agent 明显力不从心时才升级到多 Agent。记住:最好的架构是最简单的、能解决问题的那个。
误区二:忽视工具质量,只关注推理模式。
无论选择哪种设计模式,Agent 的能力上限最终取决于工具的质量。一个精心编写的搜索工具比任何复杂的推理链路都更有效。
正确做法: 在优化架构之前,先确保每个工具都是健壮的、文档完善的、有明确输入输出契约的。
误区三:反思环节形同虚设。
不少开发者在架构图中画了 Reflect 节点,但实际上只是简单打印"任务完成",没有真正的质量检查逻辑。反思如果没有可执行的改进动作,就只是装饰品。
正确做法: 反思必须包含(1)明确的验收标准、(2)失败时的重试/重规划动作。没有行动的反思等于没有反思。
误区四:缺少最大迭代次数的保护。
ReAct 循环和 Multi-Agent 辩论都可能陷入无限循环——Agent 不断"思考"却永远无法收敛到最终答案。这在生产环境中会导致 token 消耗失控。
正确做法: 为所有循环设置硬性的最大迭代次数(通常 10-20 次),超限后强制降级到人工干预或返回部分结果。
误区五:低估了 Memory 的作用。
在设计模式选型时,很多开发者只关注推理和工具,却忽略了 Memory 的设计。实际上,对于需要多轮交互的 Agent,Memory 策略(全量保留 vs 摘要 vs 滑动窗口)对性能和成本的影响不亚于模式选择本身。
正确做法: 在架构设计阶段就明确 Memory 策略,特别是长对话场景下的上下文窗口管理。
5.6.7 生产环境落地检查清单
将 Agent 从原型推进到生产环境时,以下检查清单是不可或缺的:
| 检查项 | 关键要点 | 风险等级 |
|---|---|---|
| 可观测性 | 记录每次 LLM 调用的输入/输出、工具调用统计、端到端延迟 | 🔴 必须 |
| 成本控制 | 设定 token 预算上限、限制单任务 LLM 调用次数、简单子任务用小模型 | 🔴 必须 |
| 错误恢复 | 全局 try-catch、优雅降级策略、人工干预逃生通道 | 🔴 必须 |
| 安全防护 | 工具调用权限控制、敏感信息过滤、代码执行沙箱 | 🔴 必须 |
| 评估测试 | 端到端任务完成率、回答质量评分、回归测试套件 | 🟡 推荐 |
| 版本管理 | Prompt 版本化、工具接口版本化、回滚机制 | 🟡 推荐 |
| 限流熔断 | 并发控制、超时机制、请求队列 | 🟡 推荐 |
这张清单可以作为一个通用的 Agent 上线 checklist,在每次发版前逐项确认。
5.6.8 本节小结
本节从建筑图纸的类比出发,系统梳理了三大类 Agent 设计模式:
ReAct(边想边做)——最基础的模式,思考-行动-观察循环,适合不确定性高的探索性任务。优势是灵活,劣势是每步都需要 LLM 参与导致成本线性增长。
Plan-Execute-Reflect(先规划后执行再反思)——将规划、执行、反思三阶段分离,适合可预测的结构化任务。优势是 LLM 调用次数少、支持并行执行,劣势是面对高不确定性时计划容易失效、需要重规划。
Autonomous 多 Agent 协作——通过角色分工实现专业化,适合跨领域的复杂任务。顺序协作适合流水线、层级协作适合动态调度、辩论协作适合决策论证。优势是质量最高,劣势是实现复杂度和通信开销也最高。
此外,我们还讨论了模式选型的决策框架和自动化选型工具,以及五个常见误区和七项生产环境落地检查清单。
这些设计模式构成了 Agent 架构设计的"标准图纸库",但无论选择哪种模式,Agent 都面临一个共同的瓶颈:它们的知识来源于 LLM 的预训练数据,无法访问实时的、私有的或专业的领域知识。 一个不知道公司最新产品文档的研究员 Agent、一个无法查阅最新法规的分析师 Agent——它们的输出质量注定受限。
这就引出了我们下一章的核心主题:检索增强生成(RAG,Retrieval-Augmented Generation)。 RAG 为 Agent 配备了"外部知识库"——让它在回答问题前先检索相关文档,将检索到的上下文与 LLM 的推理能力结合,从而产出更准确、更可信、更及时的结果。如果说本章的设计模式解决了"如何组织推理流程"的问题,那么下一章的 RAG 将解决"推理所需的原料从哪里来"的问题。两者结合,才能构建出真正强大的 Agent 系统。