09b - 核心 Agent 循环模式
本文是《AI Agent 实战手册》第 9 章第 2 节。 上一节:09a-从聊天机器人到自主Agent | 下一节:09c-Guardrails实现
概述
Agent 循环(Agentic Loop)是 AI Agent 的”心跳”——它决定了 Agent 如何感知环境、做出决策、执行行动并从结果中学习。2025-2026 年的生产实践中,四种核心循环模式已经成型:ReAct(推理+行动)、Plan-Act-Verify(规划-执行-验证)、OODA(观察-定向-决策-行动)和 Tool-Calling(结构化工具调用)。本节深入剖析每种模式的工作原理、流程图、伪代码、优劣势和最佳适用场景,并提供一个综合对比框架帮助你做出架构选择。
1. ReAct:推理与行动的交替循环
核心思想
ReAct(Reasoning + Acting)是 2022 年由 Yao 等人在论文中提出的基础范式,也是当前大多数 Agent 框架的默认模式。其核心思想是让 LLM 在每一步先进行显式推理(Thought),再决定行动(Action),然后观察结果(Observation),循环往复直到任务完成。
ReAct 模仿了人类解决问题的方式:先想清楚要做什么,做了之后看看结果,再决定下一步。
流程图
伪代码
def react_loop(goal: str, tools: list[Tool], max_steps: int = 10) -> str:
"""ReAct 循环的核心实现"""
messages = [{"role": "user", "content": goal}]
for step in range(max_steps):
# 1. LLM 推理:生成 Thought + Action(或 Final Answer)
response = llm.generate(
system_prompt=REACT_SYSTEM_PROMPT,
messages=messages,
tools=tools
)
# 2. 检查是否已得出最终答案
if response.has_final_answer:
return response.final_answer
# 3. 执行工具调用
tool_name = response.action.tool
tool_input = response.action.input
observation = execute_tool(tool_name, tool_input)
# 4. 将观察结果加入上下文
messages.append({"role": "assistant", "content": response.thought})
messages.append({"role": "tool", "content": observation})
return "达到最大步数限制,任务未完成"TypeScript 实现示例
// 使用 Vercel AI SDK 实现 ReAct 模式
import { generateText, tool } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { z } from 'zod';
const searchTool = tool({
description: '搜索网络获取实时信息',
parameters: z.object({
query: z.string().describe('搜索关键词'),
}),
execute: async ({ query }) => {
// 实际搜索实现
return await webSearch(query);
},
});
const calculatorTool = tool({
description: '执行数学计算',
parameters: z.object({
expression: z.string().describe('数学表达式'),
}),
execute: async ({ expression }) => {
return String(eval(expression)); // 生产环境应使用安全的表达式解析器
},
});
async function reactAgent(goal: string): Promise<string> {
const { text } = await generateText({
model: anthropic('claude-sonnet-4-20250514'),
system: `你是一个能使用工具的 AI 助手。
每一步先思考(Thought),再决定行动(Action),
观察结果后继续推理,直到能给出最终答案。`,
prompt: goal,
tools: { search: searchTool, calculator: calculatorTool },
maxSteps: 10, // ReAct 循环的最大步数
});
return text;
}优势与劣势
| 维度 | 说明 |
|---|---|
| ✅ 灵活性高 | 每一步都可以根据观察结果动态调整策略 |
| ✅ 可解释性强 | Thought 步骤提供了完整的推理链,便于调试 |
| ✅ 通用性好 | 适用于几乎所有需要工具调用的场景 |
| ✅ 框架支持广 | LangChain、LangGraph、Vercel AI SDK 等主流框架均原生支持 |
| ❌ Token 消耗高 | 每步都需要完整的推理输出,成本较高 |
| ❌ 可能陷入循环 | 缺乏全局规划,可能在同一步骤反复尝试 |
| ❌ 延迟较高 | 串行的推理-行动循环导致总延迟累积 |
| ❌ 缺乏验证机制 | 原始 ReAct 没有内置的结果验证步骤 |
最佳适用场景
- 信息检索和问答(需要多步搜索和整合)
- 数据分析(查询数据库 → 计算 → 可视化)
- 客户支持(查询账户 → 诊断问题 → 执行操作)
- 通用任务助手(不确定需要哪些工具的开放式任务)
提示词模板
你是一个能使用工具的 AI 助手。请按照以下模式解决问题:
## 可用工具
[工具列表及描述]
## 执行模式
每一步按以下格式输出:
Thought: [分析当前状态,思考下一步该做什么]
Action: [选择要使用的工具]
Action Input: [工具的输入参数,JSON 格式]
观察到工具返回结果后,继续推理:
Thought: [基于观察结果的分析]
...(重复直到能给出最终答案)
当你确定可以回答时:
Thought: [最终推理]
Final Answer: [完整的最终回复]
## 约束
- 每步只调用一个工具
- 如果工具调用失败,分析原因后尝试替代方案
- 最多执行 [N] 步,超过则总结当前进展并说明未完成的部分2. Plan-Act-Verify:规划-执行-验证循环
核心思想
Plan-Act-Verify(PAV)是 2024-2025 年随着编码 Agent(Claude Code、Devin、Codex)兴起而成熟的模式。与 ReAct 的”边想边做”不同,PAV 强调先制定完整计划,再逐步执行,最后验证结果。这种模式特别适合需要多步骤协调的复杂任务,如软件开发、文档生成和系统部署。
PAV 的灵感来自软件工程中的”测试驱动开发”(TDD)思想:先明确目标(Plan),再实现(Act),最后用测试验证(Verify)。
流程图
伪代码
def plan_act_verify_loop(requirement: str, tools: list[Tool]) -> Result:
"""Plan-Act-Verify 循环的核心实现"""
# ===== Phase 1: Plan =====
plan = llm.generate(
prompt=f"分析以下需求,分解为有序的子任务列表:\n{requirement}",
output_format="json_list"
)
task_queue = plan.tasks # [{id, description, dependencies, verification}]
# ===== Phase 2: Act + Verify 循环 =====
results = {}
for task in task_queue:
max_retries = 3
for attempt in range(max_retries):
# Act: 执行子任务
execution = llm.generate(
prompt=f"执行以下子任务:\n{task.description}\n已完成的上下文:{results}",
tools=tools
)
# Verify: 验证执行结果
verification = verify_result(
task=task,
result=execution,
method=task.verification # "run_tests" | "lint" | "type_check" | "manual"
)
if verification.passed:
results[task.id] = execution
break
else:
# 诊断失败原因,调整策略后重试
diagnosis = llm.generate(
prompt=f"任务失败:{verification.error}\n分析原因并调整方案"
)
else:
# 超过最大重试次数,修订计划
plan = revise_plan(plan, task, results)
# ===== Phase 3: 最终验证 =====
final_check = run_full_verification(results)
if not final_check.passed:
# 补充遗漏任务
additional_tasks = llm.generate(
prompt=f"最终验证失败:{final_check.errors}\n生成补充任务"
)
# 递归处理补充任务...
return resultsTypeScript 实现示例
// Plan-Act-Verify 模式的编码 Agent 实现
import { generateText, generateObject, tool } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { z } from 'zod';
// 定义计划结构
const PlanSchema = z.object({
tasks: z.array(z.object({
id: z.string(),
description: z.string(),
files: z.array(z.string()),
verification: z.enum(['test', 'lint', 'typecheck', 'build']),
})),
});
async function planActVerifyAgent(requirement: string) {
// Phase 1: Plan — 生成结构化计划
const { object: plan } = await generateObject({
model: anthropic('claude-sonnet-4-20250514'),
schema: PlanSchema,
prompt: `分析需求并生成执行计划:\n${requirement}`,
});
console.log(`📋 计划生成完毕,共 ${plan.tasks.length} 个子任务`);
// Phase 2: Act + Verify 循环
for (const task of plan.tasks) {
console.log(`⚡ 执行: ${task.description}`);
let verified = false;
for (let attempt = 0; attempt < 3 && !verified; attempt++) {
// Act: 执行子任务
const { text } = await generateText({
model: anthropic('claude-sonnet-4-20250514'),
prompt: `执行以下编码任务:\n${task.description}`,
tools: { editFile, readFile, runCommand },
maxSteps: 5,
});
// Verify: 运行验证
const result = await runVerification(task.verification, task.files);
if (result.success) {
console.log(`✅ 验证通过: ${task.id}`);
verified = true;
} else {
console.log(`❌ 验证失败 (尝试 ${attempt + 1}/3): ${result.error}`);
}
}
if (!verified) {
throw new Error(`任务 ${task.id} 在 3 次尝试后仍未通过验证`);
}
}
// Phase 3: 最终验证
console.log('🎯 运行最终验证...');
await runCommand({ command: 'npm run test && npm run lint && npm run build' });
}优势与劣势
| 维度 | 说明 |
|---|---|
| ✅ 结构化执行 | 先规划再执行,减少无目的的探索 |
| ✅ 内置质量保证 | Verify 阶段确保每步结果正确 |
| ✅ 可恢复性强 | 失败时可以诊断并重试,不会丢失已完成的工作 |
| ✅ 适合复杂任务 | 多文件编辑、多步骤部署等场景的最佳选择 |
| ✅ 人类可审查 | 计划阶段的输出可以在执行前由人类审查 |
| ❌ 前期开销大 | 规划阶段需要额外的 LLM 调用和 token |
| ❌ 计划可能过时 | 执行过程中发现的新信息可能使原计划失效 |
| ❌ 不适合简单任务 | 对于一步就能完成的任务,PAV 过于重量级 |
| ❌ 验证设计复杂 | 需要为每种任务类型设计合适的验证方法 |
最佳适用场景
- 软件开发(Claude Code、Devin、Codex 的核心模式)
- 文档生成(规划结构 → 逐节编写 → 审查一致性)
- 系统部署(规划步骤 → 逐步执行 → 验证健康检查)
- 数据管线构建(设计流程 → 实现各阶段 → 端到端测试)
提示词模板
你是一个高级编码 Agent,使用 Plan-Act-Verify 模式完成任务。
## 任务
[具体需求描述]
## 执行流程
### Phase 1: Plan
分析需求,输出结构化的执行计划:
- 列出所有需要修改/创建的文件
- 将任务分解为有序的子步骤
- 为每个步骤指定验证方法(测试/lint/类型检查/构建)
### Phase 2: Act + Verify
对每个子步骤:
1. 执行代码修改
2. 运行指定的验证命令
3. 如果验证失败,分析错误并修正(最多重试 3 次)
### Phase 3: Final Verification
所有子步骤完成后:
1. 运行完整测试套件
2. 运行 lint 和类型检查
3. 确认构建成功
## 约束
- 遵循项目现有的代码风格
- 每次修改后立即验证,不要积累未验证的改动
- 如果计划需要调整,先说明原因再修改3. OODA:观察-定向-决策-行动循环
核心思想
OODA(Observe-Orient-Decide-Act)源自美国空军上校 John Boyd 在 20 世纪 70 年代提出的军事决策框架。其核心洞察是:在快速变化的环境中,决策速度比决策质量更重要——能更快完成 OODA 循环的一方将获得优势。
在 AI Agent 领域,OODA 模式特别适合需要持续监控和快速响应的场景,如安全防御、实时监控、交易系统和自动化运维。与 ReAct 的”任务驱动”不同,OODA 是”事件驱动”的——Agent 持续观察环境变化,而非等待用户指令。
流程图
OODA 四阶段详解
| 阶段 | 英文 | 核心活动 | AI Agent 中的实现 |
|---|---|---|---|
| 观察 | Observe | 收集环境中的原始数据和信号 | 监控日志、指标、事件流、API 响应 |
| 定向 | Orient | 分析数据含义,结合经验形成态势感知 | LLM 分析 + 历史模式匹配 + 知识库检索 |
| 决策 | Decide | 基于态势感知选择行动方案 | LLM 推理 + 规则引擎 + 风险评估 |
| 行动 | Act | 执行决策,改变环境状态 | 调用工具、发送告警、执行修复、触发工作流 |
伪代码
def ooda_loop(agent_config: AgentConfig) -> None:
"""OODA 循环 — 持续运行的事件驱动 Agent"""
mental_model = load_mental_model(agent_config) # 历史经验和知识
while agent_config.is_running:
# ===== Observe: 观察环境 =====
observations = collect_observations(
sources=agent_config.data_sources, # 日志、指标、事件流
timeframe="last_5_minutes"
)
# ===== Orient: 定向分析 =====
situation = llm.generate(
prompt=f"""基于以下观察数据,分析当前态势:
观察数据:{observations}
历史模式:{mental_model.recent_patterns}
已知问题:{mental_model.known_issues}
输出:
1. 当前状态评估(正常/警告/危险)
2. 异常检测结果
3. 根因分析(如有异常)""",
)
# ===== Decide: 决策 =====
if situation.status == "normal":
continue # 无需行动,继续观察
decision = llm.generate(
prompt=f"""基于态势分析,选择行动方案:
态势:{situation}
可用行动:{agent_config.available_actions}
风险容忍度:{agent_config.risk_tolerance}
输出:
1. 推荐行动及理由
2. 风险评估
3. 是否需要人工审批""",
)
# ===== Act: 执行 =====
if decision.requires_approval:
await request_human_approval(decision)
result = execute_action(decision.action)
# 更新心智模型(学习)
mental_model.update(observations, situation, decision, result)TypeScript 实现示例
// OODA 模式的安全监控 Agent
import { generateObject } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { z } from 'zod';
const SituationSchema = z.object({
status: z.enum(['normal', 'warning', 'critical']),
anomalies: z.array(z.string()),
rootCause: z.string().optional(),
confidence: z.number().min(0).max(1),
});
const DecisionSchema = z.object({
action: z.string(),
reason: z.string(),
risk: z.enum(['low', 'medium', 'high']),
requiresApproval: z.boolean(),
});
async function oodaSecurityAgent() {
const mentalModel = new MentalModel(); // 历史经验存储
while (true) {
// Observe: 收集安全事件
const observations = await collectSecurityEvents({
sources: ['waf_logs', 'auth_logs', 'network_flows'],
timeframe: '5m',
});
// Orient: 态势分析
const { object: situation } = await generateObject({
model: anthropic('claude-sonnet-4-20250514'),
schema: SituationSchema,
prompt: `分析安全态势:\n${JSON.stringify(observations)}\n历史模式:${mentalModel.summary()}`,
});
if (situation.status === 'normal') {
await sleep(30_000); // 30 秒后再次观察
continue;
}
// Decide: 选择响应方案
const { object: decision } = await generateObject({
model: anthropic('claude-sonnet-4-20250514'),
schema: DecisionSchema,
prompt: `基于态势选择响应:\n${JSON.stringify(situation)}`,
});
// Act: 执行响应
if (decision.requiresApproval) {
await notifySecurityTeam(decision);
await waitForApproval(decision);
}
await executeResponse(decision.action);
mentalModel.learn(observations, situation, decision);
await sleep(10_000); // 10 秒后继续循环
}
}优势与劣势
| 维度 | 说明 |
|---|---|
| ✅ 持续适应 | 不断观察环境变化,实时调整策略 |
| ✅ 速度优先 | 强调快速决策循环,适合时间敏感场景 |
| ✅ 心智模型 | Orient 阶段整合历史经验,决策质量随时间提升 |
| ✅ 事件驱动 | 不需要用户触发,自主监控和响应 |
| ❌ 资源消耗高 | 持续运行的循环需要持续的计算和 API 调用 |
| ❌ 过度反应风险 | 快速决策可能导致误判和不必要的行动 |
| ❌ 复杂度高 | 需要设计数据收集、态势分析和行动执行的完整管线 |
| ❌ 不适合离散任务 | 对于一次性的任务请求,OODA 过于复杂 |
最佳适用场景
- 安全监控与威胁响应(SOC 自动化)
- AIOps 和基础设施自愈(异常检测 → 自动修复)
- 金融交易和风控(市场监控 → 策略调整)
- 实时客服升级(情绪检测 → 自动升级 → 人工介入)
- 供应链管理(库存监控 → 自动补货 → 供应商切换)
提示词模板
你是一个持续运行的安全监控 Agent,使用 OODA 循环模式。
## 当前观察数据
[最近 5 分钟的日志/指标/事件]
## 历史上下文
[最近 24 小时的趋势和已知问题]
## 你的任务
### Observe(已完成,数据如上)
### Orient — 态势分析
基于观察数据和历史上下文:
1. 评估当前状态(正常/警告/危险)
2. 识别异常模式
3. 如有异常,分析可能的根因
### Decide — 决策
如果状态非正常:
1. 列出可选的响应方案(最多 3 个)
2. 评估每个方案的风险和收益
3. 推荐最佳方案
4. 判断是否需要人工审批(高风险操作必须审批)
### Act — 行动建议
输出具体的执行命令或 API 调用。
## 约束
- 风险等级为"高"的操作必须等待人工审批
- 同一问题 1 小时内最多自动响应 3 次
- 所有行动必须记录审计日志4. Tool-Calling:结构化工具调用模式
核心思想
Tool-Calling(也称 Function Calling)是 2023 年由 OpenAI 引入、随后被 Anthropic、Google 等厂商采纳的标准化模式。与 ReAct 的”自由文本推理”不同,Tool-Calling 让 LLM 输出结构化的工具调用请求(函数名 + JSON 参数),由宿主应用执行工具并将结果返回给模型。
Tool-Calling 的关键创新是将”推理”和”行动”的接口标准化:LLM 不再需要在自由文本中嵌入工具调用指令,而是通过模型原生支持的结构化输出来表达工具调用意图。这大幅提升了可靠性和可控性。
流程图
工具定义规范对比
| 平台 | 工具定义格式 | 并行调用 | 强制工具调用 | 流式支持 |
|---|---|---|---|---|
| OpenAI | JSON Schema(tools 参数) | ✅ parallel_tool_calls | ✅ tool_choice: required | ✅ |
| Anthropic | JSON Schema(tools 参数) | ✅ 自动并行 | ✅ tool_choice: any | ✅ |
| Google Gemini | FunctionDeclaration | ✅ | ✅ ANY mode | ✅ |
| MCP 协议 | Tool Schema(JSON Schema) | 取决于客户端 | 取决于客户端 | ✅ |
伪代码
def tool_calling_loop(
messages: list[Message],
tools: list[ToolDefinition],
max_turns: int = 10
) -> str:
"""Tool-Calling 循环的核心实现"""
for turn in range(max_turns):
# 1. 调用 LLM,传入消息历史和工具定义
response = llm.chat(
messages=messages,
tools=tools, # 结构化工具定义(JSON Schema)
tool_choice="auto", # auto | required | none | specific_tool
)
# 2. 检查响应类型
if response.stop_reason == "end_turn":
# LLM 决定直接回复文本
return response.text
if response.stop_reason == "tool_use":
# 3. 处理工具调用(可能有多个并行调用)
tool_results = []
for tool_call in response.tool_calls:
# 4. Schema 验证
validated = validate_params(tool_call.name, tool_call.arguments)
# 5. 执行工具
try:
result = execute_tool(tool_call.name, validated)
tool_results.append({
"tool_call_id": tool_call.id,
"content": json.dumps(result)
})
except Exception as e:
tool_results.append({
"tool_call_id": tool_call.id,
"content": f"Error: {str(e)}",
"is_error": True
})
# 6. 将工具结果注入消息历史
messages.append(response.message) # assistant 消息(含 tool_use)
messages.append({"role": "tool", "content": tool_results})
return "达到最大轮次限制"TypeScript 实现示例
// 使用 OpenAI SDK 的 Tool-Calling 模式
import OpenAI from 'openai';
const openai = new OpenAI();
// 定义工具(JSON Schema)
const tools: OpenAI.ChatCompletionTool[] = [
{
type: 'function',
function: {
name: 'get_weather',
description: '获取指定城市的天气信息',
parameters: {
type: 'object',
properties: {
city: { type: 'string', description: '城市名称' },
unit: { type: 'string', enum: ['celsius', 'fahrenheit'] },
},
required: ['city'],
},
},
},
{
type: 'function',
function: {
name: 'search_database',
description: '查询产品数据库',
parameters: {
type: 'object',
properties: {
query: { type: 'string' },
limit: { type: 'number', default: 10 },
},
required: ['query'],
},
},
},
];
// 工具执行映射
const toolHandlers: Record<string, (args: any) => Promise<string>> = {
get_weather: async ({ city, unit }) => {
const data = await fetchWeatherAPI(city, unit);
return JSON.stringify(data);
},
search_database: async ({ query, limit }) => {
const results = await db.search(query, limit);
return JSON.stringify(results);
},
};
async function toolCallingAgent(userMessage: string): Promise<string> {
const messages: OpenAI.ChatCompletionMessageParam[] = [
{ role: 'user', content: userMessage },
];
for (let turn = 0; turn < 10; turn++) {
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages,
tools,
tool_choice: 'auto',
});
const choice = response.choices[0];
messages.push(choice.message);
// 如果没有工具调用,返回文本回复
if (!choice.message.tool_calls?.length) {
return choice.message.content ?? '';
}
// 执行所有工具调用(支持并行)
const toolResults = await Promise.all(
choice.message.tool_calls.map(async (tc) => {
const handler = toolHandlers[tc.function.name];
const args = JSON.parse(tc.function.arguments);
const result = await handler(args);
return {
role: 'tool' as const,
tool_call_id: tc.id,
content: result,
};
})
);
messages.push(...toolResults);
}
return '达到最大轮次限制';
}优势与劣势
| 维度 | 说明 |
|---|---|
| ✅ 可靠性高 | 结构化输出比自由文本解析更稳定,减少格式错误 |
| ✅ 类型安全 | JSON Schema 验证确保参数类型正确 |
| ✅ 并行调用 | 支持一次请求中调用多个工具,减少延迟 |
| ✅ 生态标准化 | OpenAI、Anthropic、Google 均采用类似接口 |
| ✅ 成本较低 | 无需额外的 Thought 输出,token 消耗更少 |
| ✅ 易于集成 | MCP 协议进一步标准化了工具定义和调用 |
| ❌ 推理不透明 | 没有显式的 Thought 步骤,难以理解决策过程 |
| ❌ 灵活性受限 | 只能调用预定义的工具,无法动态发现新能力 |
| ❌ 依赖模型能力 | 工具选择质量完全取决于模型的理解能力 |
| ❌ 错误处理有限 | 模型可能不理解工具返回的错误信息 |
最佳适用场景
- API 集成和数据查询(结构化的输入输出)
- 客服系统(查询账户、修改订单等标准操作)
- 工作流自动化(触发预定义的业务流程)
- 简单的单步或少步任务(不需要复杂推理链)
提示词模板
你是一个客户服务 Agent,可以使用以下工具帮助客户解决问题。
## 可用工具
工具定义已通过 API 的 tools 参数提供,包括:
- query_account: 查询客户账户信息
- modify_order: 修改订单状态
- create_ticket: 创建工单
- search_knowledge_base: 搜索知识库
## 使用规则
1. 先查询相关信息,再执行操作
2. 修改类操作前,先向客户确认
3. 如果工具调用失败,向客户解释并提供替代方案
4. 涉及退款超过 [金额] 的操作,告知客户需要人工处理
## 回复风格
- 使用友好、专业的语气
- 每次回复简洁明了
- 操作完成后总结所做的事情5. 四种模式综合对比
核心维度对比表
| 维度 | ReAct | Plan-Act-Verify | OODA | Tool-Calling |
|---|---|---|---|---|
| 核心循环 | Thought→Action→Observation | Plan→Act→Verify | Observe→Orient→Decide→Act | Message→ToolCall→Result |
| 推理方式 | 显式逐步推理 | 先全局规划再逐步执行 | 持续态势感知 | 隐式(模型内部) |
| 触发方式 | 用户请求驱动 | 用户请求驱动 | 事件/时间驱动 | 用户请求驱动 |
| 规划能力 | 无全局规划 | 强(先规划后执行) | 中(基于态势的动态规划) | 无(逐步决策) |
| 验证机制 | 无内置验证 | 强(每步验证 + 最终验证) | 通过下一轮观察间接验证 | 无内置验证 |
| 可解释性 | 高(Thought 可见) | 高(计划 + 执行日志) | 中(Orient 分析可见) | 低(推理不透明) |
| Token 消耗 | 高 | 中-高 | 高(持续运行) | 低 |
| 延迟 | 中-高(串行) | 高(规划 + 执行 + 验证) | 低-中(快速决策循环) | 低(直接调用) |
| 复杂度 | 低 | 中 | 高 | 低 |
| 适合任务类型 | 开放式探索 | 复杂多步骤任务 | 持续监控响应 | 结构化工具操作 |
| 代表实现 | LangChain Agent, Vercel AI SDK | Claude Code, Devin, Codex | 安全 SOC, AIOps | OpenAI API, Anthropic API |
| 生产就绪度 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
工具推荐
| 工具 | 支持的模式 | 价格 | 适用场景 |
|---|---|---|---|
| LangGraph | ReAct, PAV, OODA | 免费(开源) | 复杂状态图编排,支持所有模式 |
| Vercel AI SDK | ReAct, Tool-Calling | 免费(开源) | TypeScript 项目,快速集成 |
| Claude Agent SDK | PAV, Tool-Calling | 免费(开源)+ API 按量 | Anthropic 生态,编码 Agent |
| OpenAI Agents SDK | ReAct, Tool-Calling | 免费(开源)+ API 按量 | OpenAI 生态,多 Agent |
| CrewAI | ReAct, PAV | 免费(开源)+ Enterprise | 角色制多 Agent 协作 |
| AutoGen | ReAct, OODA | 免费(开源) | 研究和原型验证 |
| n8n | Tool-Calling, OODA | 免费(自托管)/ $20+/月(云) | 低代码工作流自动化 |
| LangSmith | 所有模式(监控) | 免费层 + $39+/月 | Agent 可观测性和调试 |
6. 决策框架:如何选择循环模式
决策树
选择标准速查表
| 场景特征 | 推荐模式 | 理由 |
|---|---|---|
| 需要多步搜索和信息整合 | ReAct | 灵活的推理-行动交替适合探索性任务 |
| 软件开发和代码修改 | Plan-Act-Verify | 需要规划、执行和测试验证的完整循环 |
| 7×24 小时监控和自动响应 | OODA | 事件驱动的持续观察和快速决策 |
| 标准化的 API 操作 | Tool-Calling | 结构化输入输出,可靠性高,成本低 |
| 复杂文档生成 | Plan-Act-Verify | 先规划结构,逐节编写,最后审查一致性 |
| 客服对话 + 操作 | Tool-Calling + ReAct | 简单查询用 Tool-Calling,复杂问题用 ReAct |
| 安全威胁检测和响应 | OODA | 持续观察 + 快速决策 + 自动响应 |
| 数据分析和报告 | ReAct | 需要多步查询、计算和可视化 |
| CI/CD 管线执行 | Plan-Act-Verify | 有序步骤 + 每步验证 + 失败回滚 |
| 实时交易决策 | OODA | 速度优先的持续决策循环 |
混合模式:生产环境的最佳实践
在实际生产环境中,很少只使用单一模式。2025-2026 年的主流做法是混合模式:
典型混合架构:
- OODA + Tool-Calling(AIOps):OODA 循环持续监控基础设施,检测到异常时通过 Tool-Calling 执行标准化的修复操作
- ReAct + Tool-Calling(智能助手):ReAct 负责推理和规划,Tool-Calling 负责实际的工具执行
- PAV + ReAct(编码 Agent):PAV 负责整体规划和验证,每个子任务内部使用 ReAct 进行灵活的推理和执行
- OODA + PAV(自动化运维):OODA 检测问题,PAV 执行复杂的修复流程(如数据库迁移、服务重启序列)
实战案例:编码 Agent 的 Plan-Act-Verify 循环
场景:使用 Claude Code 实现一个新功能
以下是 Claude Code 处理”为 REST API 添加分页功能”这一需求时的完整 PAV 循环:
用户输入:为 /api/users 端点添加游标分页功能
===== Phase 1: Plan =====
Claude Code 分析需求,生成计划:
1. 读取现有的 users 路由和数据库查询代码
2. 修改数据库查询,添加游标分页参数(cursor, limit)
3. 修改 API 路由,解析分页查询参数
4. 添加分页响应格式(data, nextCursor, hasMore)
5. 编写单元测试覆盖分页逻辑
6. 运行测试验证
===== Phase 2: Act + Verify =====
--- 子任务 1: 读取现有代码 ---
Act: 读取 src/routes/users.ts 和 src/db/queries.ts
Verify: ✅ 文件存在,理解了现有结构
--- 子任务 2: 修改数据库查询 ---
Act: 在 queries.ts 中添加 getUsersWithCursor() 函数
Verify: 运行 tsc --noEmit → ✅ 类型检查通过
--- 子任务 3: 修改 API 路由 ---
Act: 更新 users.ts 路由处理函数
Verify: 运行 tsc --noEmit → ✅ 类型检查通过
--- 子任务 4: 添加响应格式 ---
Act: 定义 PaginatedResponse<T> 类型
Verify: 运行 tsc --noEmit → ✅ 类型检查通过
--- 子任务 5: 编写测试 ---
Act: 创建 src/routes/users.test.ts
Verify: 运行 npm test -- users.test → ❌ 测试失败
→ 诊断:游标解码逻辑有 bug
→ 修复:修正 base64 解码
→ 重新验证:运行 npm test -- users.test → ✅ 通过
===== Phase 3: Final Verification =====
运行 npm test → ✅ 全部 47 个测试通过
运行 npm run lint → ✅ 无警告
运行 npm run build → ✅ 构建成功
📦 交付:3 个文件修改,1 个新文件,47/47 测试通过案例分析
这个案例展示了 PAV 模式的几个关键优势:
- 计划提供了全局视角:Agent 在动手之前就知道需要修改哪些文件,避免了遗漏
- 逐步验证捕获了 bug:子任务 5 的测试失败被立即发现并修复,而不是等到最后才发现
- 最终验证确保整体一致性:不仅新功能正确,原有功能也没有被破坏
- 人类可审查:用户可以在 Plan 阶段审查计划,在交付时审查结果
避坑指南
❌ 常见错误
-
所有任务都用 ReAct
- 问题:简单的 API 调用也用 ReAct,导致不必要的 Thought 输出和 token 浪费
- 正确做法:简单的结构化操作用 Tool-Calling,只有需要多步推理的任务才用 ReAct
-
Plan-Act-Verify 中跳过 Verify
- 问题:为了加速执行,跳过验证步骤,导致错误累积到最后才被发现
- 正确做法:每个子任务完成后必须验证。验证的成本远低于回滚和重做的成本
-
OODA 循环没有设置冷却期
- 问题:Agent 对同一问题反复触发响应,导致”告警风暴”或操作冲突
- 正确做法:设置去重窗口(如同一问题 1 小时内最多响应 3 次)和冷却期
-
Tool-Calling 没有错误处理
- 问题:工具调用失败时,Agent 不知道如何处理,直接返回错误给用户
- 正确做法:实现重试逻辑、降级方案和友好的错误提示。将错误信息返回给 LLM,让它决定下一步
-
混淆”模式”和”框架”
- 问题:认为使用了 LangGraph 就自动获得了 PAV 模式,或使用了 OpenAI API 就只能用 Tool-Calling
- 正确做法:模式是架构设计,框架是实现工具。任何框架都可以实现任何模式,关键是理解模式的核心循环
-
ReAct 循环没有设置最大步数
- 问题:Agent 陷入无限循环,持续调用工具但无法得出结论,token 成本失控
- 正确做法:设置
max_steps限制(通常 5-15 步),超过后总结当前进展并请求人工指导
✅ 最佳实践
- 从 Tool-Calling 开始,按需升级:大多数任务用 Tool-Calling 就够了,只有确实需要复杂推理时才升级到 ReAct 或 PAV
- 为 PAV 模式设计可测试的验证标准:每个子任务都应该有明确的”通过/失败”标准(测试、lint、类型检查等)
- OODA 模式必须配合 Guardrails:持续运行的 Agent 必须有安全边界,高风险操作必须有人工审批
- 监控所有模式的 token 消耗:使用 LangSmith、Langfuse 等工具追踪每次循环的成本
- 混合模式是生产环境的常态:不要执着于单一模式,根据任务特征动态选择
相关资源与延伸阅读
| 资源 | 类型 | 说明 |
|---|---|---|
| ReAct 论文 (arXiv) | 学术论文 | ReAct 模式的原始论文,理解理论基础 |
| Anthropic Agent 设计模式 | 官方文档 | Anthropic 推荐的 Agent 架构模式 |
| Claude Agent SDK | GitHub 仓库 | PAV 模式的生产级实现参考 |
| Vercel AI SDK — Agent 文档 | 框架文档 | TypeScript 中实现 ReAct 和 Tool-Calling 的最佳指南 |
| LangGraph 官方教程 | 框架文档 | 用状态图实现各种 Agent 循环模式 |
| OpenAI Function Calling 指南 | 官方文档 | Tool-Calling 模式的权威参考 |
| Anthropic: Effective Harnesses for Long-Running Agents | 工程博客 | 长时间运行 Agent 的架构设计 |
| Function Calling vs ReAct: Which Pattern Fits | 技术博客 | Tool-Calling 和 ReAct 的实际对比分析 |
| Harnessing the OODA Loop for Agentic AI | 技术文章 | OODA 在 AI Agent 中的应用分析 |
| AI Agents Design Patterns Guide 2026 | 综合指南 | 2026 年 Agent 设计模式全景 |
参考来源
- ReAct: Synergizing Reasoning and Acting in Language Models (2023,Yao et al.)
- Anthropic: Effective Harnesses for Long-Running Agents (2025-05)
- Claude Code: Behind the Scenes of the Master Agent Loop (2025-08)
- Harnessing the OODA Loop for Agentic AI (2025-02)
- The Agentic OODA Loop: How AI and Humans Learn to Defend Together — Snyk (2025-06)
- AI Function Calling in 2025: Build Agents That Actually Work (2025-07)
- Advanced Function Calling: Tool Composition for Production Agents 2026 (2026-01)
- Function Calling vs ReAct Agents: Which Pattern Fits Your Use Case (2026-01)
- AI Agents Design Patterns: Complete Guide 2026 (2025-12)
- Prompt Routers and Flow Engineering: Building Modular, Self-Correcting Agent Systems (2026-06)
- How AI Agents Use Tools — 2026 (2026-06)
- AI Agents in 2026: From Chatbots to Governed Digital Labor (2026-06)
📖 返回 总览与导航 | 上一节:09a-从聊天机器人到自主Agent | 下一节:09c-Guardrails实现