Blog
Anthropic博客阅读笔记01-《Building effective agents》
对于智能体来说,简单、可组合的模式大于复杂的框架。
原文:链接
原文发布日期:2024年12月19日
对于智能体来说,简单、可组合的模式大于复杂的框架。
Agent和Workflow的区别:工作流是通过预定义的代码路径来编排LLM和工具。Agent是 LLM 动态知道自身流程和工具使用的系统,控制完成任务的方式。
什么时候使用工作流,以及什么时候使用Agent?
应该以任务为核心,尽可能寻找简单的解决方案,Agent以延迟和成本为代价,换取更好的灵活性和任务表现。对于要求一致性以及可预测的任务,workflow更合适,而需要灵活性以及模型来驱动决策的场景,Agent会更好。对于某些应用,通过检索和单词调用LLM就足够了。
举个例子-电商客服。
客户问“我买的冲锋衣洗了一次就不防水了,能退货吗?怎么寄回?”通过检索规则+案例就可以解决这个问题,单次调用LLM即可。 而如果用户不仅问,还要办理退货,则至少需要workflow来编排A(提取信息)->B(查找数据库,看是否超期)->C(生成恢复)三个阶段。调用两次LLM,一次tool,流程编排死了。 而如果用户消息是预料之外的内容,则Agent需要自己发挥,边看结果边决定下一步干嘛。

什么时候使用框架
有很多框架对LLM的调用以及定义、解析做了封装,例如Claude Agent sdk(封装了Agent loop循环、读写工具等)、Rivet(通过可视化界面控制流程)等。
框架使得入门变得容易,但是使得开发可能更难以调试。文章建议从底层API开始,手动实现Agent模式(点击此处查看Authropic常见的 Agent模式)。
搭建Agent的积木是增强的LLM
Agent系统由增强的LLM搭建而成。此处的“增强”指经过能力扩展的LLM:检索、工具、记忆。

模型可以主动使用这些能力——生成搜索查询、选择工具、保留长期信息。
增强主要有两个方面:
- 根据具体需要定制工具
- 提供简单、文档完备的接口
基于此,文章提出几种workflow。
Workflow #1:提示链Prompt Chaining

把一个任务用一系列步骤拆分。每一个LLM的输入都是上一个LLM的输出,可以添加程序化的Gate来确保流程正常进行。
这个workflow适用于:任务可以被容易、清晰地分解为固定子任务。主要目标是用延迟来换取更高的准确率。
例子:
- 写文档大纲、检查大纲是否符合标准、基于大纲写文章
- 生成营销文案,翻译成另一种文本
Workflow #2:路由Routing

路由把任务进行分类,导向到一个专门的后续任务。这个workflow运行关注点分离,构建更专门的Prompt。
这个workflow适用于:复杂任务存在不同类别,分开处理更好,并且分类这个操作可以被准确处理。
例子:
- 客服查询导向不同下游流程(一般问题、退款请求、技术支持)
- 把简单/常见的问题路由到更小、成本更低的模型,把困难问题路由到更强的模型
Workflow #3 并行化Parallelization

LLM并行处理一个任务,程序化地聚合输出。并行化有两种使用方式:
- 分段(sectioning):把一个任务拆分成可独立执行的子任务,并行跑
- 聚合(Voting):把同一任务跑多次,得到多种输出
什么时候使用:
- 任务可以被拆分,并行加速时
- 任务需要多视角或者多次尝试提高置信度
- 多个考虑维度的复杂任务,多次调用可以被独立LLM调用表现更好
例子:
-
sectioning:
-
一个模型实例处理用户查询,另一个审查不当内容或请求。把任务分开做比让一个LLM同时审查和核心响应表现更好
-
Voting:
-
评审一段代码漏洞:几个不同Prompt一起评审,发现问题标记。
Workflow #4:编排器——工人(Orchestrator-Worker)

编排器-工人架构里,一个中央LLM动态分解任务,委托给工人LLM,合成它们的结果。
虽然跟Parallelization有点像,但是更具灵活性。子任务非提前预定义而是基于具体输入决定的。
claude code的subagent机制就是这个pattern的实现。
Workflow #5 评估器-优化器(Evaluator-Optimizer)

这种模式下,一个LLM调用生成响应,另一个LLM在Loop里提供评估和反馈直到达标。
这个workflow有效的前提:
- 人类清晰地说出反馈时,LLM可以做到针对性的提升,LLM有能力分辨出区别。
- LLM自己有能力提供这种反馈,能够根据提示词设置的标准判断。
例子:
- 写论文和审论文的Agent
- 复杂文本翻译
- 复杂搜索任务,需要多轮搜索和分析的情况。
Agents

LLM的关键能力成熟,Agent已经出现。Agent具有理解复杂输入、推理、规划、可靠使用工具、从错误中恢复的能力。
Agent 工作流:
- 从人的命令或互动开始
- 任务清晰后,Agent独立规划、操作,可能回到人类来做信息搜集
- 执行中,不断从环境中获得当前状态、工具调用结果、代码执行结果来评估进度
- Agent可以在检查点等待人类反馈,或者遇到阻塞时暂停
- 任务完成时终止,通常也有最大步数等的限制。
Agent的实现比较直接,通常是在循环里基于环境反馈使用工具。但是对于工具集和文档更重要。
什么时候用Agent:开放性问题,难以或者不可预测需要的步骤数,不能硬编码路径。
例子:
- 编程任务 claude code
- 通用Agent workbuddy等
上面几种模式是搭建Agent系统的几种积木,可以通过开发者的塑造来组合适应不用的模式。成功的关键在于测量表现并迭代实现。
不要盲目增加复杂度,应该只在增加复杂度能很好地改善结果时增加复杂度。
此外还有两个附录。
附录一中,列举了两个例子。其一是通过Agent来做客户支持的Agent系统,这个场景天然遵循对话流,同时需要访问外部信息和动作,工具也可以拉取客户数据、订单历史、知识库文章等。也可以用工具调用来发起退款,是否成功也可以通过用户是否解决问题来衡量。其二是编程Agent,代码可以通过自动化测试验证,Agent可以用测试结果作为反馈迭代方案,问题空间定义清晰、结构化,输出质量可以客观测量,因此在coding领域有巨大潜力。从现在编码Agent的火热也可以得到验证。
附录二中强调了工具定义中Prompt 的重要性。应该要消耗整体Prompt一样的精力来写工具定义。工具定义是ACI(Agent-computer接口)的说明书。要想对待HCI(人机交互)一样对待ACI。要写出好的工具定义,通常要考虑包含:示例写法、边界情况、输入格式要求、与其他工具的清晰边界。控制参数名或者描述让其含义更显然。测试模型如何使用工具,是否出错。对于LLM来说,某些格式的输出比其他格式更困难。