Anthropic:构建有效的 AI Agent(全文中文翻译)

原文:Building Effective AI Agents
作者:Erik S.、Barry Zhang / Anthropic
原文发布日期:2024 年 12 月 19 日
本文依据原文当前网页版本翻译,在 SunAI 论坛翻译转载。原文版权归原权利人所有;须注明原始来源,不得用于付费教育用途。

说明:本文所描述的工具生态自 2024 年 12 月以来已发生许多变化。关于我们目前采用的方法,请参阅我们如何构建 Claude Managed Agents以及 Managed Agents 文档。

过去一年里,我们与数十支团队合作,他们在各行各业构建大语言模型(LLM)智能体。我们一直观察到,最成功的实现并没有使用复杂的框架或专门的库,而是采用简单、可组合的模式。

在这篇文章中,我们将分享与客户合作以及自行构建智能体过程中学到的经验,并为开发者提供构建有效智能体的实用建议。

什么是智能体?

“智能体”(Agent)有多种定义方式。一些客户将智能体定义为完全自主的系统:能够长时间独立运行,使用各种工具完成复杂任务。另一些客户则用这个词描述更具规定性的实现,这些实现遵循预先定义的工作流。在 Anthropic,我们把这些不同形式统称为智能体系统(agentic systems),但在架构上对**工作流(workflows)与智能体(agents)**作出一个重要区分:

  • 工作流:通过预先定义的代码路径编排 LLM 和工具的系统。
  • 智能体:由 LLM 动态主导自身的处理过程和工具使用,并掌控任务完成方式的系统。

下文将详细探讨这两类智能体系统。在附录 1“智能体的实践应用”中,我们会介绍两个领域,客户在这些领域使用此类系统时发现了尤为突出的价值。

何时应该使用智能体,何时不应该?

使用 LLM 构建应用时,我们建议寻找尽可能简单的解决方案,只在必要时增加复杂性。这可能意味着根本不构建智能体系统。智能体系统往往以更高的延迟和成本换取更好的任务表现,你应该考虑这种取舍在什么时候才是合理的。

当确实需要更高的复杂性时,工作流能为定义明确的任务提供可预测性和一致性;而在需要大规模提供灵活性、由模型作出决策的场景中,智能体则是更好的选择。不过,对于许多应用来说,通过检索和上下文内示例优化单次 LLM 调用,通常已经足够。

何时以及如何使用框架

许多框架可以让智能体系统更容易实现,包括:

这些框架简化了调用 LLM、定义和解析工具、串联调用等常见的底层任务,让开发者更容易上手。然而,它们往往会增加额外的抽象层,可能遮蔽底层的提示词和响应,使调试更加困难。它们也可能让开发者倾向于增加复杂性,即使更简单的实现已经足够。

我们建议开发者先直接使用 LLM API:许多模式只需几行代码就能实现。如果确实使用框架,请确保你理解其底层代码。对底层机制作出错误假设,是客户出错的常见原因。

一些示例实现可参阅我们的 cookbook。

基础构件、工作流与智能体

这一节将探讨我们在生产环境中见到的智能体系统常见模式。我们会从最基础的构件——增强型 LLM——开始,逐步增加复杂性,从简单的组合式工作流讲到自主智能体。

基础构件:增强型 LLM

智能体系统的基本构件,是通过检索、工具和记忆等能力得到增强的 LLM。我们目前的模型能够主动使用这些能力:生成自己的搜索查询、选择适当的工具,以及决定保留哪些信息。

增强型 LLM

我们建议实现时关注两个关键方面:根据具体使用场景定制这些能力,并确保它们为 LLM 提供易于使用、文档完善的接口。这些增强能力有许多实现方式,其中一种是使用我们最近发布的模型上下文协议(Model Context Protocol)。开发者可以通过一个简单的客户端实现,接入不断扩展的第三方工具生态。

在本文余下部分,我们假定每次 LLM 调用都可以使用这些增强能力。

工作流:提示链

提示链将任务分解为一系列步骤,每次 LLM 调用都处理上一次调用的输出。你可以在任意中间步骤加入程序化检查(见下图中的“gate”,即检查关卡),确保整个过程仍按预期推进。

提示链工作流

何时使用这种工作流: 当任务能够轻松、清晰地拆分成固定子任务时,这种工作流非常适合。其主要目标是让每次 LLM 调用处理更容易的任务,以更高的延迟换取更高的准确性。

提示链适用的示例:

  • 先生成营销文案,再将其翻译成另一种语言。
  • 先撰写文档提纲,检查提纲是否满足特定标准,再根据提纲撰写文档。

工作流:路由

路由会对输入进行分类,并将其导向专门的后续任务。这种工作流可以实现关注点分离,并构建更有针对性的提示词。如果没有这种工作流,对某一类输入进行优化,可能会损害其他输入的处理表现。

路由工作流

何时使用这种工作流: 如果复杂任务存在不同的类别,分别处理效果更好,而且能够通过 LLM 或更传统的分类模型、算法准确分类,那么路由就很适合。

路由适用的示例:

  • 将不同类型的客服咨询,例如一般问题、退款请求、技术支持,导向不同的下游流程、提示词和工具。
  • 将简单、常见的问题路由给 Claude Haiku 4.5 等规模较小、成本效益较高的模型,将困难、少见的问题交给 Claude Sonnet 4.5 等能力更强的模型,以优化整体表现。

工作流:并行化

LLM 有时可以同时处理一项任务,再通过程序汇总其输出。并行化工作流主要有两种形式:

  • 分块(Sectioning):将任务拆成相互独立的子任务,并行运行。
  • 投票(Voting):多次执行同一任务,以获得不同的输出。

并行化工作流

何时使用这种工作流: 当拆分后的子任务可以通过并行执行提高速度,或者需要多个视角、多次尝试来获得更有把握的结果时,并行化很有效。对于需要考虑多个方面的复杂任务,通常将每个方面交给一次独立的 LLM 调用,让它专注于具体方面,效果会更好。

并行化适用的示例:

  • 分块:
    • 实现安全护栏:一个模型实例处理用户查询,另一个模型实例筛查其中的不当内容或请求。这通常比让同一次 LLM 调用同时承担安全护栏和核心回答任务的效果更好。
    • 自动化评测 LLM 表现:针对给定提示词,每次 LLM 调用评估模型表现的不同方面。
  • 投票:
    • 检查一段代码是否存在漏洞:使用多个不同的提示词进行审查,发现问题时标记代码。
    • 判断一段内容是否不当:通过多个提示词评估不同方面,或设置不同的投票阈值,在误报和漏报之间取得平衡。

工作流:编排器—工作者

在编排器—工作者工作流中,一个中央 LLM 动态拆解任务,将任务委派给工作者 LLM,并综合它们的结果。

编排器—工作者工作流

何时使用这种工作流: 当复杂任务所需的子任务无法事先预测时,这种工作流很适合。例如,在编程任务中,需要修改多少个文件、每个文件需要做什么修改,很可能取决于具体任务。尽管其结构与并行化相似,关键区别在于灵活性:子任务不是预先定义的,而是由编排器根据具体输入决定的。

编排器—工作者适用的示例:

  • 每次都需要对多个文件进行复杂修改的编程产品。
  • 需要从多个来源收集、分析信息,以寻找可能相关信息的搜索任务。

工作流:评估器—优化器

在评估器—优化器工作流中,一次 LLM 调用生成回答,另一次调用提供评估和反馈,形成循环。

评估器—优化器工作流

何时使用这种工作流: 当存在明确的评估标准,而且迭代改进能够带来可衡量的价值时,这种工作流尤为有效。适合采用它的两个信号是:第一,当人类明确表达反馈时,LLM 的回答确实能够得到改进;第二,LLM 本身能够提供这样的反馈。这类似于人类作者为了写出一篇打磨完善的文档而进行的反复修改。

评估器—优化器适用的示例:

  • 文学翻译:翻译 LLM 最初可能无法捕捉某些细微之处,但评估 LLM 能够提供有用的批评意见。
  • 复杂搜索任务:需要多轮搜索和分析才能收集全面信息,由评估器判断是否有必要进一步搜索。

智能体

随着 LLM 在理解复杂输入、推理与规划、可靠使用工具、从错误中恢复等关键能力上逐渐成熟,智能体开始出现在生产环境中。智能体通过接收人类用户的指令,或者与用户进行交互式讨论来开始工作。任务明确后,智能体会独立规划和执行,也可能返回向人类请求更多信息或判断。在执行过程中,智能体必须在每一步从环境中获得“真实依据”(ground truth),例如工具调用结果或代码执行结果,以评估进展。随后,智能体可以在检查点或遇到阻碍时暂停,等待人类反馈。任务通常在完成后终止,但为了保持控制,也常常会设置停止条件,例如最大迭代次数。

智能体能够处理复杂任务,但其实现往往很直接。它们通常只是根据环境反馈,在循环中使用工具的 LLM。因此,清晰、周到地设计工具集及其文档至关重要。我们会在附录 2“为工具进行提示工程”中进一步讨论工具开发的最佳实践。

自主智能体

何时使用智能体: 智能体适用于开放式问题:很难甚至无法预测需要多少步骤,也无法硬编码一条固定路径。LLM 可能会运行许多轮,因此你必须对其决策能力有一定程度的信任。智能体的自主性,使其非常适合在可信环境中扩大任务处理规模。

智能体的自主性也意味着更高的成本,以及错误不断累积的可能性。我们建议在沙箱环境中进行充分测试,并设置适当的安全护栏。

智能体适用的示例:

以下示例来自我们自己的实现:

编程智能体的高层流程

组合与定制这些模式

这些构件并不是必须照搬的规定。它们是一些常见模式,开发者可以根据不同使用场景进行调整和组合。与任何 LLM 功能一样,成功的关键在于衡量表现,并对实现进行迭代。再次强调:只有在复杂性确实能够改善结果时,才应考虑增加复杂性。

总结

在 LLM 领域取得成功,并不在于构建最复杂的系统,而在于构建适合自身需求的系统。从简单的提示词开始,通过全面评测加以优化,只有当更简单的方案无法满足要求时,才引入多步骤的智能体系统。

实现智能体时,我们努力遵循三个核心原则:

  1. 保持智能体设计的简单性。
  2. 明确展示智能体的规划步骤,优先保证透明度。
  3. 通过完善的工具文档和测试,精心打造智能体—计算机接口(ACI)。

框架能够帮助你快速起步,但在迈向生产环境时,不要犹豫,应当减少抽象层,使用基础组件构建。遵循这些原则,你就能创建不仅功能强大,而且可靠、可维护、受到用户信任的智能体。

致谢

本文由 Erik S. 和 Barry Zhang 撰写。这项工作基于我们在 Anthropic 构建智能体的经验,以及客户分享的宝贵见解,对此我们深表感谢。

附录 1:智能体的实践应用

与客户合作的过程中,我们发现了两类特别有前景的 AI 智能体应用,它们展示了上述模式的实际价值。这两类应用都说明:当任务既需要对话,也需要行动,具有明确的成功标准,能够形成反馈循环,并融入有实质意义的人类监督时,智能体能够发挥最大的价值。

A. 客户支持

客户支持将熟悉的聊天机器人界面,与通过工具集成获得的增强能力结合起来。这天然适合更开放式的智能体,因为:

  • 客服交互自然地遵循对话流程,同时又需要访问外部信息并执行操作;
  • 可以集成工具来获取客户数据、订单历史和知识库文章;
  • 发放退款或更新工单等操作可以通过程序处理;
  • 可以根据用户定义的问题解决标准,明确衡量是否成功。

多家公司采用按使用量计费、仅对成功解决的问题收费的模式,证明了这种方法的可行性,也体现了它们对智能体有效性的信心。

B. 编程智能体

软件开发领域已经展现出 LLM 功能的巨大潜力,相关能力正从代码补全发展到自主解决问题。智能体在这里特别有效,因为:

  • 代码解决方案可以通过自动化测试验证;
  • 智能体可以将测试结果作为反馈,迭代改进解决方案;
  • 问题空间定义明确、结构清晰;
  • 输出质量可以客观衡量。

在我们自己的实现中,智能体现在仅根据拉取请求(pull request)的描述,就能解决 SWE-bench Verified 基准测试中的真实 GitHub 问题。不过,虽然自动化测试有助于验证功能,人类审查对于确保解决方案符合更广泛的系统要求,仍然至关重要。

附录 2:为工具进行提示工程

无论构建哪一种智能体系统,工具都很可能是其中的重要组成部分。工具通过在我们的 API 中指定精确的结构和定义,使 Claude 能够与外部服务及 API 交互。当 Claude 准备调用工具时,它会在 API 响应中包含一个工具使用块(tool use block)。工具定义和规格说明,应当得到与整体提示词同样充分的提示工程投入。在这个简短的附录中,我们将介绍如何为工具进行提示工程。

同一种操作,通常有多种指定方式。例如,可以通过编写 diff 来指定文件修改,也可以重写整个文件。对于结构化输出,可以将代码放在 Markdown 中返回,也可以放在 JSON 中返回。在软件工程中,这类差别只是形式上的差别,可以彼此无损转换。然而,某些格式对 LLM 来说,比其他格式难写得多。编写 diff 时,需要在写出新代码之前,就知道块头中应当标明多少行发生了变化。与 Markdown 相比,在 JSON 中编写代码,需要额外转义换行符和引号。

对于如何确定工具格式,我们的建议如下:

  • 给模型足够的 token,让它在因输出格式陷入困境之前有空间进行“思考”。
  • 让格式尽量接近模型在互联网上见过的、自然出现的文本形式。
  • 确保没有额外的格式负担,例如必须准确计算数千行代码的行数,或对写出的任何代码进行字符串转义。

一条经验法则是:想想人们在人机接口(HCI)上投入了多少精力,并计划为打造优秀的智能体—计算机接口(ACI)投入同样多的精力。以下是一些具体思路:

  • 站在模型的角度思考。根据描述和参数,这个工具的使用方法是否一目了然,还是需要仔细琢磨?如果你需要琢磨,模型很可能也一样。优秀的工具定义通常包括使用示例、边界情况、输入格式要求,以及与其他工具之间清晰的职责边界。
  • 怎样调整参数名称或描述,才能让它们更清楚?可以把这件事想象成给团队里的初级开发者编写一份优秀的文档字符串(docstring)。当使用许多类似工具时,这一点尤为重要。
  • 测试模型如何使用你的工具:在我们的 workbench 中运行大量示例输入,观察模型会犯哪些错误,并据此迭代改进。
  • 为工具进行防错设计(Poka-yoke)。调整参数,让出错变得更困难。

在构建用于 SWE-bench 的智能体时,我们实际上花在优化工具上的时间,比优化整体提示词的时间更多。例如,我们发现,智能体离开根目录后,模型在使用采用相对文件路径的工具时会出错。为了解决这个问题,我们将工具改为始终要求使用绝对文件路径,并发现模型采用这种方式时没有出错。

术语解释

以下为译文涉及的术语说明,不属于原文正文。

  • LLM(Large Language Model,大语言模型):用于理解和生成文本的语言模型。
  • Agent(智能体):本文特指由 LLM 动态决定执行过程与工具使用方式的系统,而不是所有带工具调用的应用。
  • Agentic systems(智能体系统):本文的总称,同时包含预定义工作流和由模型自主控制执行的 Agent。
  • Workflow(工作流):由预先编写的代码路径安排模型与工具的执行过程。
  • Augmented LLM(增强型 LLM):配备检索、工具、记忆等能力的 LLM。
  • Prompt chaining(提示链):将任务拆成固定步骤,前一步的输出作为后一步的输入。
  • Routing(路由):先判断输入属于哪类任务,再交给对应的模型、提示词或工具。
  • Parallelization(并行化):让多个调用同时处理独立子任务,或对同一任务进行多次独立判断,再汇总结果。
  • Orchestrator-workers(协调者—工作者):由中央模型按当前任务动态拆解并分派子任务,再综合结果。
  • Evaluator-optimizer(评估者—优化者):一个模型生成结果,另一个模型评估并反馈,通过循环改进结果。
  • Ground truth(真实反馈):本文指工具调用结果、代码执行结果等来自环境的实际信息,用于判断任务进展。
  • Guardrails(防护机制):对输入、输出或执行行为设置的检查与限制。
  • MCP(Model Context Protocol,模型上下文协议):用于连接模型应用与外部工具、数据源的协议。
  • ACI(Agent-Computer Interface,智能体—计算机接口):提供给 Agent 使用的工具接口、参数、格式及说明。
  • HCI(Human-Computer Interaction,人机交互):人与计算机系统交互的设计与研究领域。
  • Poka-yoke(防错):通过设计降低错误发生的可能性,例如要求文件路径必须为绝对路径。
  • SWE-bench Verified:用于评估模型解决真实软件仓库问题能力的基准;本文讨论使用测试反馈验证编码 Agent 的结果。