8.2 Agent 设计模式
在软件工程中,有单例模式、工厂模式。在 Agent 工程中,也有经过验证的设计模式。 选择正确的模式,往往比单纯优化 Prompt 更有效。
8.2.0 五大核心模式概览
根据 Anthropic 的工程实践,Agent 设计模式并非越复杂越好。大多数生产环境的应用都主要由以下五种基础构建块组成:
Prompt Chaining (链式工作流): 最简单直观。将一个任务拆解为线性步骤,上一步的输出作为下一步的输入 (A -> B -> C)。
Routing (路由): 根据输入分类,将请求分流给最适合的下游处理单元。(详见 8.2.4)
Parallelization (并行): 同时运行多个独立的子任务,最后聚合结果。适用于可以“分而治之”的场景。
Orchestrator-Workers (指挥家-工人类): 有一个中央大脑负责动态规划和分配,子任务由专门的 Worker 完成。(详见 8.2.2)
Evaluator-Optimizer (评估-优化): 生成后由另一个角色评审并改进,循环提升质量。(详见 8.2.3)
8.2.1 ReAct
这是最经典、也是最基础的 Agent 模式。 核心思想是:行动之前先思考,行动之后看结果。
工作原理
ReAct 是一个 while 循环:
Thought: 我现在需要做什么?
Action: 调用工具。
Observation: 看到工具返回的结果。
Repeat: 基于结果,进行下一轮思考。
示例 Prompt Template
在实际应用中,我们通常会将下面这样一个完整的“问答过程”作为 少样本 (Few-Shot) 放入 System Prompt 中。模型会学习这种格式,并在遇到新问题时模仿这一过程。
注:在实际推理中,Observation 行是由程序执行工具后自动填入的,而不是模型生成的。
优缺点
优点: 灵活,能解决未知问题,容错率高。
缺点: 容易陷入死循环,Token 消耗大,可能会“跑题”。
8.2.2 Plan-and-Solve
对于特别复杂的任务(如写一本 200 页的书),由于 ReAct 视野太窄(只看下一步),容易迷失方向。 Plan-and-Solve 要求 Agent 先写大纲,再一次性执行。
工作流程
Planner: 专门负责把大目标拆解为子任务列表
[Task A, Task B, Task C]。Executor: 依次执行 Task A -> Task B -> Task C。
Replanner (可选): 发现 Task B 失败了,重新调整剩余计划。
适用场景
代码生成(先设计接口,再写实现)。
长篇写作(先写提纲,再写章节)。
ReAct vs. Plan-and-Execute
这两种模式最容易被混淆,但它们解决的问题不同:
规划方式
动态、逐步规划
静态、先整体规划
执行节奏
边想边做,实时调整
先列计划,再逐步执行
适用任务
环境不确定、需要临场纠偏
步骤明确、跨度较长的任务
容错方式
基于 Observation 即时修正
失败后局部重规划或整体重排
典型风险
容易跑偏、循环、成本上升
计划过时、对环境变化反应慢
一个好记的判断标准是:
不知道下一步会看到什么:优先 ReAct
知道大致要做哪几步:优先 Plan-and-Execute
例如“排查线上故障”更像 ReAct,因为每一步都要根据新证据决定方向;“重构支付模块并补测试”更像 Plan-and-Execute,因为整体步骤相对稳定。
Claude Code 的实践演进
Claude Code 团队在落地 Plan-and-Solve 模式时经历了显著的演进。最初,团队为 Agent 提供了一个简单的 TodoWrite 工具,用于维护待办事项列表。但实践中发现了严重问题:模型经常“忘记”列表中的条目,需要在系统提示词中反复添加提醒(如“记得更新你的 Todo 列表”)。
随着模型能力的提升(如 Opus 4.5),这些过多的提醒反而成了限制——更强的模型已经不需要如此密集的指导,过度的指令反而会干扰其自主判断。
最终,团队用更成熟的 Task 系统替代了简单的 Todo 列表。新系统的核心改进包括:
依赖关系:任务之间可以定义先后依赖(Task B 依赖 Task A 的输出),而非简单的线性列表。
跨代理共享:Task 可以在主代理和多个子代理之间共享,使计划不再是单个 Agent 的私有笔记,而是团队协作的“共享白板”。
这一演进说明:Plan-and-Solve 模式的关键不仅在于“有计划”,更在于计划的表示方式要匹配任务的复杂度。
混合模式:先规划,再局部 ReAct
工程上这两种模式并不是互斥的。更常见的成熟方案是:
先用 Planner 生成全局任务树
再让 Executor 在每个子任务内部运行局部 ReAct 循环
遇到明显阻塞时才请求 Replanner 调整剩余计划
这种做法同时保留了:
全局上的结构感
局部上的灵活性
对长任务更好的可控性
如果直接全程 ReAct,长任务容易迷路;如果全程死板按计划执行,又很容易在环境变化时崩掉。混合模式往往是更接近真实生产的折中方案。
8.2.3 Reflection
这是一种通过引入 自我批评 来提升质量的模式。 许多时候,Agent 的第一直觉是错的。如果让它“再检查一遍”,它就能自己发现错误。
流程图解
实战应用:Reflexion
在编程任务中,如果单元测试失败了:
System: 测试失败,错误信息是
IndexError。Reflexion: “我之前假设列表不为空,但实际上它可能是空的。我需要在代码里加一个检查。”
Retry: 生成修复后的代码。
8.2.4 Routing
当系统拥有成百上千个工具时,如果全部塞给一个 Agent,它会通过不了。 路由模式引入了一个轻量级的 Router(通常是一个分类器或小模型)。
架构
User Input: “我要退货。”
Router: 识别意图 ->
CustomerService_Agent。User Input: “这首歌叫什么?”
Router: 识别意图 ->
Music_Agent。
这其实就是第六章讲的 Skill Routing 的架构层面实现。
8.2.5 Tool Use vs. RAG 混合模式
最强大的 Agent 往往同时具备这两种能力:
RAG (Retrieval): 用于获取知识(“公司的请假制度是什么?”)。
Tool Use: 用于执行操作(“帮我提交请假条”)。
最佳实践:把 RAG 当作一种 Tool。 定义一个 search_knowledge_base(query) 工具。Agent 会自己决定是去搜文档,还是去调 API。
8.2.6 长任务 Agent:Harness 设计最佳实践
在生产环境中构建能够自主运行数小时甚至数天的长任务 Agent(如自动化编程、大规模数据处理等),仅有上述设计模式还不够。需要搭建一套完整的运行框架(Harness)来确保任务可持续、可监测、可回滚。Anthropic 的工程团队总结了一系列经过验证的最佳实践。
双层架构:Initializer + Executor
对于涉及环境搭建的长任务,推荐采用两层 Agent 协作:
Initializer Agent:一次性运行,负责环境检查、依赖安装、初始配置
Executor Agent:反复迭代,负责实际的增量工作,每次只完成一个功能单元
这样做的优势是:将"环保险"的初始化工作与"容易失败"的核心业务分离,提高整体稳定性。
结构化进度跟踪:JSON Checklist
不要用 Markdown 列表记录进度——改用 JSON 格式的功能清单。Anthropic 的实践中,一个 200+ 条功能的项目使用以下结构:
关键原则:
所有条目初始化为
false,Agent 只能修改passes字段禁止删除或编辑已有条目(即使发现不需要也只在
notes中标记)200+ 条目的细粒度描述比 5 个宽泛目标更有效
为什么 JSON 优于 Markdown?因为模型对 JSON 结构的遵守度显著更高,能更好地维持"只改某些字段"的约束。
单功能增量开发
Agent 容易因贪心而失败。最佳实践是:
单次迭代只做一个功能(对应清单中的一个
feature)完成后:
运行端到端测试(通常是浏览器自动化)验证该功能
若通过,标记
passes: true若失败,Agent 自我修复,重新测试,直到通过
提交 Git Commit 记录这个功能的完成
继续下一个功能
这种模式避免了"大一统开发"导致的难以定位问题。
使用浏览器端到端测试作为验证环
定义清晰的端到端测试流程(可以是 Playwright、Selenium 或 Puppeteer 脚本)。Agent 每完成一个功能就自动:
启动浏览器,访问应用
按照预定义的用户路径操作(如"填表 -> 提交 -> 检查确认信息")
验证结果是否符合预期
记录测试结果到清单
这样的测试不仅验证了功能,还给 Agent 真实的反馈,而不是代码级别的"测试通过"。
会话开头的历史回顾与基线测试
长任务的 Agent 往往分散在多个会话中运行。每个新会话启动时:
读取进度清单,了解前一个会话完成了哪些功能
基线测试:重新验证已标记为
passes: true的功能是否仍然工作目的是捕捉后续开发可能引入的回归 (Regression)
如发现回归,立即修复并更新清单
这有点像单元测试中的"冒烟测试",但针对整个已完成的功能集合。
参考资源
参考 Anthropic 工程博客 Effective Harnesses for Long-Running Agents(2026),该文详细阐述了上述实践在生产级编程 Agent 中的应用。
无论选择哪种模式,Agent 在长时间运行中面临的最大挑战都是:记不住事。 上下文窗口 (Context Window) 再大也是有限的。需要给 Agent 装备外挂海马体。
最后更新于
