构建高效的 AI Agent
"Building Effective Agents"
必读全文中译查看原文(HTML) ↗
导读
本文是 Anthropic 工程博客 2024 年 12 月 19 日的经典文章,作者 Erik Schluntz 与 Barry Zhang,是第 2 周「给开发者的 LLM」的核心必读。Anthropic 基于与数十个行业团队共建 LLM Agent 的经验,提出全文最重要的判断:最成功的实现往往不用复杂框架,而是用简单、可组合的模式。文章首先给出关键概念区分——工作流(workflows,由预定义代码路径编排 LLM 与工具)与 Agent(LLM 动态主导自身流程与工具使用),然后从最小构建块「增强型 LLM」出发,逐级介绍五种工作流模式(提示链、路由、并行化、编排者-执行者、评估者-优化者)与自主 Agent,并说明各自的适用场景与例子。文末给出三原则(保持简单、优先透明、精心打磨智能体-计算机接口 ACI)与两个附录:Agent 的两类高价值落地场景(客服、编程),以及「为工具做提示工程」的实操建议。这篇文章是本课程 Agent 工程模块的模式语言总纲。
全文中译
构建高效的 AI Agent
发布时间:2024 年 12 月 19 日 · Anthropic 工程博客
我们与数十个跨行业团队合作构建过 LLM Agent。始终如一的是,最成功的实现使用的是简单、可组合的模式,而不是复杂的框架。
注:本文所述的不少工具生态自 2024 年 12 月以来已经变化。关于我们当前的做法,请参阅《我们如何构建 Claude Managed Agents》及 Managed Agents 文档。
过去一年,我们与数十个跨行业团队合作构建大语言模型(LLM)Agent。始终如一的是,最成功的实现并没有使用复杂的框架或专门的库,而是用简单、可组合的模式构建的。
在这篇文章中,我们分享与客户合作及自己构建 Agent 的经验,并为开发者提供构建高效 Agent 的实用建议。
什么是 Agent?
「Agent」可以有几种定义。一些客户把 Agent 定义为长时间独立运行、使用各种工具完成复杂任务的完全自主系统;另一些人用这个词描述遵循预定义工作流的、更规约式的实现。在 Anthropic,我们把所有这些变体统称为智能体系统(agentic systems),但在架构上做一个重要区分——工作流(workflows)与Agent(agents):
- 工作流是通过预定义代码路径编排 LLM 和工具的系统。
- Agent 则是 LLM 动态主导自身流程和工具使用、掌控如何完成任务的系统。
下文将详细探讨这两类智能体系统。在附录 1(「Agent 实践」)中,我们描述客户在这类系统中获得特别价值的两个领域。
何时(以及何时不要)使用 Agent
用 LLM 构建应用时,我们建议寻找尽可能简单的方案,只在需要时才增加复杂度。这可能意味着根本不构建智能体系统。智能体系统常常以延迟和成本换取更好的任务表现,你应该考虑这种权衡何时划算。
当确实需要更多复杂度时,工作流为定义明确的任务提供可预测性与一致性,而 Agent 则是在需要灵活性与模型驱动决策(且要规模化)时更好的选择。但对很多应用而言,用检索和上下文示例优化单次 LLM 调用通常就足够了。
何时以及如何使用框架
有许多框架可以让智能体系统更容易实现,包括:
- Claude Agent SDK;
- AWS 的 Strands Agents SDK;
- Rivet,一个拖拽式 GUI LLM 工作流构建器;
- Vellum,另一个用于构建和测试复杂工作流的 GUI 工具。
这些框架简化了调用 LLM、定义和解析工具、串联调用等标准底层任务,让人容易上手。但它们往往引入额外的抽象层,遮蔽了底层的提示与响应,使调试更难;也容易诱使人在更简单的设置就够用时添加复杂度。
我们建议开发者从直接使用 LLM API 开始:许多模式用几行代码就能实现。如果使用框架,请确保理解其底层代码。对「引擎盖下」运作方式的不正确假设是客户错误的常见来源。
请参阅我们的 cookbook 获取一些示例实现。
构建块、工作流与 Agent
本节探讨我们在生产环境中见过的智能体系统常见模式。我们将从基础构建块——增强型 LLM——开始,逐步提升复杂度,从简单的组合式工作流到自主 Agent。
构建块:增强型 LLM
智能体系统的基本构建块,是经检索(retrieval)、工具(tools)和记忆(memory)等增强的 LLM。我们当前的模型可以主动使用这些能力——生成自己的搜索查询、选择合适的工具、决定保留什么信息。
[图:增强型 LLM 示意图——中心为 LLM,周围是检索、工具与记忆三种增强]
我们建议关注实现的两个关键方面:让这些能力适配你的具体用例,并确保它们为你的 LLM 提供简单、文档完善的接口。实现这些增强的方式很多,其中一种是通过我们近期发布的模型上下文协议(Model Context Protocol),开发者只需一个简单的客户端实现,即可接入不断增长的第三方工具生态。
在本文余下部分,我们假设每次 LLM 调用都能使用这些增强能力。
工作流:提示链(Prompt Chaining)
提示链把任务分解为一系列步骤,每次 LLM 调用处理上一步的输出。你可以在任何中间步骤加程序化检查(见下图中的「gate/门」),确保流程仍在正轨上。
[图:提示链工作流——LLM 调用 1 → 检查门 → LLM 调用 2]
何时使用此工作流:
提示链适用于任务可以轻松、干净地分解为固定子任务的场景。其主要目标是以延迟换更高准确率——让每次 LLM 调用面对更简单的任务。
提示链有用的例子:
- 生成营销文案,再把它翻译成另一种语言。
- 先写文档提纲,检查提纲是否满足一定标准,再基于提纲写出文档。
工作流:路由(Routing)
路由对输入进行分类,并将其导向专门的后续任务。这种工作流实现了关注点分离,可以构建更专门的提示。没有它,针对一类输入的优化可能损害其他输入上的表现。
[图:路由工作流——输入经分类后分流到不同专门提示与工具]
何时使用此工作流:
路由适用于存在明显类别、分别处理效果更好的复杂任务,且分类可以由 LLM 或更传统的分类模型/算法准确完成。
路由有用的例子:
- 把不同类型的客服请求(一般咨询、退款申请、技术支持)导向不同的下游流程、提示与工具。
- 把简单/常见问题路由给 Claude Haiku 4.5 这类更小、更具成本效益的模型,把困难/罕见问题路由给 Claude Sonnet 4.5 这类更强模型,以优化整体表现。
工作流:并行化(Parallelization)
LLM 有时可以同时处理一个任务,再用程序聚合输出。并行化有两种关键变体:
- 分区(Sectioning):把任务拆成可并行运行的独立子任务。
- 投票(Voting):对同一任务运行多次以获得多样的输出。
[图:并行化工作流——多个 LLM 并行调用后由聚合器合并]
何时使用此工作流:
当拆出的子任务可以并行以提速,或需要多视角、多次尝试以获得更高置信度结果时,并行化很有效。对于有多个考量的复杂任务,让每个考量由单独的 LLM 调用处理、专注各自方面,LLM 通常表现更好。
并行化有用的例子:
- 分区:实现护栏(guardrails),一个模型实例处理用户查询的同时另一个筛查不当内容或请求——这往往比让同一次 LLM 调用同时负责护栏和核心回答效果更好;自动化评估(eval),每次 LLM 调用评估模型在给定提示上表现的不同方面。
- 投票:审查一段代码的漏洞,多个不同提示各自审查并在发现问题时标记;评估给定内容是否不当,多个提示评估不同方面或要求不同投票阈值,以平衡假阳性与假阴性。
工作流:编排者-执行者(Orchestrator-workers)
在编排者-执行者工作流中,一个中央 LLM 动态拆解任务、委派给执行者(worker)LLM,并综合它们的结果。
[图:编排者-执行者工作流——编排者 LLM 把任务拆分给多个执行者 LLM,再综合结果]
何时使用此工作流:
这种工作流适合无法预测所需子任务的复杂工作(例如编程中,需要改动的文件数量和每个文件的改动性质可能取决于具体任务)。虽然它与并行化在拓扑上相似,关键差别在于灵活性——子任务不是预定义的,而是由编排者根据具体输入决定。
编排者-执行者有用的例子:
- 每次需要对多个文件做复杂修改的编程产品。
- 需要从多个来源收集并分析可能相关信息、用于综合研判的搜索任务。
工作流:评估者-优化者(Evaluator-optimizer)
在评估者-优化者工作流中,一次 LLM 调用生成回答,另一次调用在循环中提供评估与反馈。
[图:评估者-优化者工作流——生成者 LLM 与评估者 LLM 循环迭代]
何时使用此工作流:
当我们有清晰的评估标准、且迭代精炼能带来可衡量的价值时,这种工作流尤其有效。两个契合信号是:其一,当人类清晰表达反馈意见时,LLM 的回答可以被证明得到改进;其二,LLM 自己能提供这样的反馈。这类似人类作者打磨文档时的迭代写作过程。
评估者-优化者有用的例子:
- 文学翻译:译者 LLM 起初可能抓不住细微之处,而评估 LLM 能给出有用的批评。
- 需要多轮搜索与分析才能收集全面信息的复杂搜索任务,由评估者决定是否需要进一步搜索。
Agent
随着 LLM 在关键能力上成熟——理解复杂输入、参与推理与规划、可靠地使用工具、从错误中恢复——Agent 正在生产环境中兴起。Agent 的工作始于人类用户的指令或交互式讨论。一旦任务明确,Agent 便独立规划与运作,其间可能回到人类那里获取更多信息或判断。执行过程中,Agent 至关重要的是在每一步从环境获得「真实依据(ground truth)」(如工具调用结果或代码执行),以评估自己的进展。Agent 可以在检查点或遇到阻碍时暂停以获取人类反馈。任务通常在完成时终止,但也常设停止条件(如最大迭代次数)以保持控制。
[图:自主 Agent 高层流程——Agent 在循环中基于环境反馈使用工具,必要时回到人类]
Agent 能处理复杂任务,但其实现往往很直白:它们通常就是基于环境反馈、在循环中使用工具的 LLM。因此,清晰而周到地设计工具集及其文档至关重要。我们在附录 2(「为工具做提示工程」)中展开工具开发的最佳实践。
何时使用 Agent:
Agent 适合难以或无法预测所需步骤数的开放性问题,以及无法硬编码固定路径的场景。LLM 可能要运行很多轮,你必须对其决策有一定信任。Agent 的自主性使它非常适合在受信任环境中规模化执行任务。
Agent 的自主性也意味着更高成本和错误累积的可能。我们建议在沙盒环境中进行大量测试,并配以恰当的护栏。
Agent 有用的例子(来自我们自己的实现):
- 解决 SWE-bench 任务的编程 Agent,这类任务需要基于任务描述对多个文件进行修改;
- 我们的「计算机使用(computer use)」参考实现,Claude 借助操作一台计算机来完成任务。
[图:编程 Agent 的高层流程]
组合与定制这些模式
这些构建块并非硬性规定。它们是开发者可以塑造和组合以适应不同用例的常见模式。与任何 LLM 功能一样,成功的关键是衡量性能并迭代实现。再强调一次:只有当复杂度可证明地改善结果时,才应该增加它。
总结
在 LLM 领域取得成功,不在于构建最精巧的系统,而在于构建适合你需求的系统。从简单提示开始,用全面的评估来优化,只有当更简单的方案不够用时才引入多步智能体系统。
实现 Agent 时,我们尽量遵循三条核心原则:
- 在 Agent 设计中保持简单(simplicity);
- 通过显式展示 Agent 的规划步骤来优先保证透明度(transparency);
- 通过完善的工具文档和测试,精心打磨你的智能体-计算机接口(agent-computer interface,ACI)。
框架能帮你快速起步,但走向生产时,不要犹豫削减抽象层、用基础组件构建。遵循这些原则,你可以创建不仅强大,而且可靠、可维护、被用户信任的 Agent。
致谢
由 Erik S. Schluntz 和 Barry Zhang 撰写。本文源自我们在 Anthropic 构建 Agent 的经验,以及客户分享的宝贵洞见,对此我们深表感谢。
附录 1:Agent 实践
我们与客户的合作揭示了两个特别有前景的 AI Agent 应用,它们展示了上述模式的实用价值。两个应用都说明:Agent 在那些既需要对话又需要行动、有清晰成功标准、能形成反馈闭环、并配以有意义的人类监督的任务上增值最多。
A. 客户支持
客户支持把人们熟悉的聊天机器人界面与通过工具集成获得的增强能力结合起来。这对更开放的 Agent 是天然适配,因为:
- 支持交互天然遵循对话流,同时又需要访问外部信息与执行操作;
- 可以集成工具来调取客户数据、订单历史和知识库文章;
- 退款、更新工单等操作可以程序化处理;
- 成功与否可以通过用户定义的「问题解决」清晰衡量。
已有几家公司通过「按解决量计费」的用量定价模式证明了这一路线的可行性,显示了它们对自家 Agent 有效性的信心。
B. 编程 Agent
软件开发领域已显示出 LLM 功能的巨大潜力,能力正从代码补全演进到自主解决问题。Agent 在此特别有效,因为:
- 代码方案可以通过自动化测试验证;
- Agent 可以用测试结果作为反馈来迭代方案;
- 问题空间定义良好且结构化;
- 输出质量可以客观衡量。
在我们自己的实现中,Agent 现在可以仅凭 pull request 描述就解决 SWE-bench Verified 基准中的真实 GitHub issue。不过,虽然自动化测试有助于验证功能,人工评审对于确保方案符合更广泛的系统要求仍然至关重要。
附录 2:为工具做提示工程
无论你构建哪种智能体系统,工具很可能都是 Agent 的重要组成部分。工具让 Claude 能与外部服务和 API 交互,办法是在我们的 API 中明确指定工具的结构与定义。当 Claude 打算调用某个工具时,会在 API 响应中包含一个工具使用块(tool use block)。工具的定义与规格说明,应当得到与整体提示同等程度的提示工程关注。在这个简短附录中,我们介绍如何为工具做提示工程。
同一个动作往往有多种指定方式。例如,指定文件编辑可以写一个 diff,也可以重写整个文件;结构化输出可以把代码放在 markdown 里或放在 JSON 里。在软件工程中,这类差异只是表面形式,可以无损互转。但对 LLM 来说,有些格式写起来比另一些难得多:写 diff 要求在写新代码之前就知道 chunk header 里改了多少行;把代码写进 JSON(相比 markdown)要求对换行和引号做额外转义。
我们对决定工具格式的建议如下:
- 给模型足够的 token 去「思考」,免得它把自己写进死角;
- 让格式贴近模型在互联网自然文本中见过的样子;
- 确保没有格式「负担」,比如要精确数着几千行代码的行数,或对所写代码做字符串转义。
一条经验法则:想想人机交互接口(HCI)上投入了多少精力,就打算在创建好的智能体-计算机接口(ACI)上投入同样多的精力。以下是几点具体做法:
- 设身处地站在模型的角度。 只看描述和参数,这个工具的用法显而易见吗,还是需要仔细琢磨?如果是后者,对模型多半也是如此。好的工具定义往往包含用法示例、边缘情况、输入格式要求,以及与其他工具的清晰边界。
- 如何修改参数名称或描述让事情更显然? 把这当作给团队里初级开发者写一份出色的 docstring。在使用许多相似工具时尤其重要。
- 测试模型如何使用你的工具: 在我们的 workbench 里跑大量示例输入,观察模型犯什么错,然后迭代。
- 为工具做防错设计(poka-yoke)。 修改参数设计,让犯错变得更难。
在为 SWE-bench 构建 Agent 时,我们实际上花在优化工具上的时间比花在整体提示上的更多。例如,我们发现 Agent 移出根目录后,模型在使用相对路径文件的工具上容易出错。为解决这一问题,我们把工具改为始终要求绝对路径——之后模型用起来再无差错。
要点速览
- 核心结论:最成功的 Agent 实现用的是简单、可组合的模式,而非复杂框架;应从最简单方案开始,仅在可证明改善结果时增加复杂度。
- 关键区分:工作流(workflows)= 预定义代码路径编排 LLM 与工具,可预测、一致;Agent = LLM 动态主导自身流程与工具使用,适合需要灵活性与模型决策的开放任务。
- 最小构建块是增强型 LLM:检索 + 工具 + 记忆;可通过 MCP 等协议接入工具生态。
- 五种工作流模式:提示链(以延迟换准确率)、路由(分类后分流,如 Haiku 处理简单问题、Sonnet 处理难题)、并行化(分区 + 投票)、编排者-执行者(动态拆分委派子任务,适合多文件编程)、评估者-优化者(生成-评估循环,适合文学翻译等迭代精炼)。
- Agent 的本质:「基于环境反馈、在循环中使用工具的 LLM」;每步需从环境获得 ground truth 评估进展,并设停止条件(如最大迭代数)。
- Agent 的代价:更高成本与错误累积;建议沙盒环境充分测试并加护栏。
- 实现三原则:保持简单、显式展示规划步骤以保证透明、精心打磨智能体-计算机接口(ACI)。
- 两大高价值落地场景:客户支持(对话 + 工具操作 + 可衡量解决标准,支持按解决计费)与编程 Agent(测试可验证、可迭代反馈,SWE-bench Verified 上仅凭 PR 描述解决真实 issue,但仍需人工评审)。
- 工具即提示工程:格式要贴近模型见过的自然文本、避免 diff 行数统计与 JSON 转义等负担;像投入 HCI 一样投入 ACI,做防错设计(poka-yoke),Anthropic 在 SWE-bench Agent 上花在工具优化的时间多于整体提示(如强制绝对路径)。
- 框观建议:框架(如 Claude Agent SDK)便于起步,但直接用 LLM API 几行代码即可实现多数模式;对框架底层的不正确假设是客户错误的常见来源。