Skip to Content

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 results

TypeScript 实现示例

// 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 不再需要在自由文本中嵌入工具调用指令,而是通过模型原生支持的结构化输出来表达工具调用意图。这大幅提升了可靠性和可控性。

流程图

工具定义规范对比

平台工具定义格式并行调用强制工具调用流式支持
OpenAIJSON Schema(tools 参数)parallel_tool_callstool_choice: required
AnthropicJSON Schema(tools 参数)✅ 自动并行tool_choice: any
Google GeminiFunctionDeclarationANY 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. 四种模式综合对比

核心维度对比表

维度ReActPlan-Act-VerifyOODATool-Calling
核心循环Thought→Action→ObservationPlan→Act→VerifyObserve→Orient→Decide→ActMessage→ToolCall→Result
推理方式显式逐步推理先全局规划再逐步执行持续态势感知隐式(模型内部)
触发方式用户请求驱动用户请求驱动事件/时间驱动用户请求驱动
规划能力无全局规划强(先规划后执行)中(基于态势的动态规划)无(逐步决策)
验证机制无内置验证强(每步验证 + 最终验证)通过下一轮观察间接验证无内置验证
可解释性高(Thought 可见)高(计划 + 执行日志)中(Orient 分析可见)低(推理不透明)
Token 消耗中-高高(持续运行)
延迟中-高(串行)高(规划 + 执行 + 验证)低-中(快速决策循环)低(直接调用)
复杂度
适合任务类型开放式探索复杂多步骤任务持续监控响应结构化工具操作
代表实现LangChain Agent, Vercel AI SDKClaude Code, Devin, Codex安全 SOC, AIOpsOpenAI API, Anthropic API
生产就绪度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

工具推荐

工具支持的模式价格适用场景
LangGraphReAct, PAV, OODA免费(开源)复杂状态图编排,支持所有模式
Vercel AI SDKReAct, Tool-Calling免费(开源)TypeScript 项目,快速集成
Claude Agent SDKPAV, Tool-Calling免费(开源)+ API 按量Anthropic 生态,编码 Agent
OpenAI Agents SDKReAct, Tool-Calling免费(开源)+ API 按量OpenAI 生态,多 Agent
CrewAIReAct, PAV免费(开源)+ Enterprise角色制多 Agent 协作
AutoGenReAct, OODA免费(开源)研究和原型验证
n8nTool-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 年的主流做法是混合模式

典型混合架构

  1. OODA + Tool-Calling(AIOps):OODA 循环持续监控基础设施,检测到异常时通过 Tool-Calling 执行标准化的修复操作
  2. ReAct + Tool-Calling(智能助手):ReAct 负责推理和规划,Tool-Calling 负责实际的工具执行
  3. PAV + ReAct(编码 Agent):PAV 负责整体规划和验证,每个子任务内部使用 ReAct 进行灵活的推理和执行
  4. 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 模式的几个关键优势:

  1. 计划提供了全局视角:Agent 在动手之前就知道需要修改哪些文件,避免了遗漏
  2. 逐步验证捕获了 bug:子任务 5 的测试失败被立即发现并修复,而不是等到最后才发现
  3. 最终验证确保整体一致性:不仅新功能正确,原有功能也没有被破坏
  4. 人类可审查:用户可以在 Plan 阶段审查计划,在交付时审查结果

避坑指南

❌ 常见错误

  1. 所有任务都用 ReAct

    • 问题:简单的 API 调用也用 ReAct,导致不必要的 Thought 输出和 token 浪费
    • 正确做法:简单的结构化操作用 Tool-Calling,只有需要多步推理的任务才用 ReAct
  2. Plan-Act-Verify 中跳过 Verify

    • 问题:为了加速执行,跳过验证步骤,导致错误累积到最后才被发现
    • 正确做法:每个子任务完成后必须验证。验证的成本远低于回滚和重做的成本
  3. OODA 循环没有设置冷却期

    • 问题:Agent 对同一问题反复触发响应,导致”告警风暴”或操作冲突
    • 正确做法:设置去重窗口(如同一问题 1 小时内最多响应 3 次)和冷却期
  4. Tool-Calling 没有错误处理

    • 问题:工具调用失败时,Agent 不知道如何处理,直接返回错误给用户
    • 正确做法:实现重试逻辑、降级方案和友好的错误提示。将错误信息返回给 LLM,让它决定下一步
  5. 混淆”模式”和”框架”

    • 问题:认为使用了 LangGraph 就自动获得了 PAV 模式,或使用了 OpenAI API 就只能用 Tool-Calling
    • 正确做法:模式是架构设计,框架是实现工具。任何框架都可以实现任何模式,关键是理解模式的核心循环
  6. ReAct 循环没有设置最大步数

    • 问题:Agent 陷入无限循环,持续调用工具但无法得出结论,token 成本失控
    • 正确做法:设置 max_steps 限制(通常 5-15 步),超过后总结当前进展并请求人工指导

✅ 最佳实践

  1. 从 Tool-Calling 开始,按需升级:大多数任务用 Tool-Calling 就够了,只有确实需要复杂推理时才升级到 ReAct 或 PAV
  2. 为 PAV 模式设计可测试的验证标准:每个子任务都应该有明确的”通过/失败”标准(测试、lint、类型检查等)
  3. OODA 模式必须配合 Guardrails:持续运行的 Agent 必须有安全边界,高风险操作必须有人工审批
  4. 监控所有模式的 token 消耗:使用 LangSmith、Langfuse 等工具追踪每次循环的成本
  5. 混合模式是生产环境的常态:不要执着于单一模式,根据任务特征动态选择

相关资源与延伸阅读

资源类型说明
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 设计模式全景

参考来源


📖 返回 总览与导航 | 上一节:09a-从聊天机器人到自主Agent | 下一节:09c-Guardrails实现

Last updated on