返回 文章 build CMS 文章

构建有效 AI 代理:Anthropic 的架构区分与实用建议

Anthropic 教你如何根据任务需求选择工作流或代理,并遵循简单优先、透明可控的原则构建可靠 AI 系统。

AI代理工作流LLMAnthropic
成长分 / 100 76 综合收获、行动、留存与影响

构建有效 AI 代理:Anthropic 的架构区分与实用建议
为什么值得读获得来自 Anthropic 一线实践的代理系统设计经验,避免常见陷阱。

清晰理解工作流与代理的架构区别,帮助你在项目中做出合适的技术选型。

关键洞察
  1. 代理系统分为工作流和代理:工作流通过预定义代码路径编排 LLM 和工具,代理则动态指导自身流程和工具使用。
  2. 构建 LLM 应用时应优先寻找最简单方案,仅在需要时增加复杂性;代理系统以延迟和成本换取更好性能。
  3. 常见工作流模式包括提示链、路由、并行化、编排器-工作者和评估器-优化器,各有适用场景。
转成行动

深入阅读

正文与原文对照

原文保真覆盖:全文原文字符:13332

注:本文所描述的工具生态在 2024 年 12 月之后已发生很大变化。关于我们当前的做法,请参阅我们如何构建 Claude Managed Agents 以及 Managed Agents 文档。

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

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

什么是智能体?

“智能体”(agent)有多种定义方式。一些客户把智能体定义为完全自主的系统,能够长时间独立运行,借助各种工具完成复杂任务;另一些人则用这个词来描述遵循预定义工作流的、更具规定性的实现。在 Anthropic,我们把所有这些变体统称为智能体系统(agentic systems),但在工作流(workflows)与智能体(agents)之间划出一条重要的架构界线:

  • 工作流是通过预定义的代码路径来编排 LLM 和工具的系统。
  • 而智能体则是由 LLM 动态地主导自身流程和工具使用、自行掌控任务完成方式的系统。

下文将详细探讨这两类智能体系统。在附录 1(“智能体实践”)中,我们介绍了客户发现这类系统特别有价值的两个领域。

何时使用(以及何时不用)智能体

在用 LLM 构建应用时,我们建议寻找尽可能简单的方案,只在必要时才增加复杂度。这可能意味着根本不构建智能体系统。智能体系统通常以延迟和成本换取更好的任务表现,你需要考虑这种取舍在什么情况下是值得的。

当确实需要更高的复杂度时,对于定义明确的任务,工作流能提供可预测性和一致性;而当需要大规模的灵活性和由模型驱动的决策时,智能体是更好的选择。不过,对许多应用来说,通过检索和上下文内示例(in-context examples)来优化单次 LLM 调用通常就足够了。

何时以及如何使用框架

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

这些框架通过简化调用 LLM、定义和解析工具、串联调用等标准的底层任务,让入门变得容易。然而,它们往往会引入额外的抽象层,掩盖底层的提示词和响应,使调试更加困难。当更简单的配置就已足够时,它们也容易诱使人增加不必要的复杂度。

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

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

构建模块、工作流与智能体

本节将探讨我们在生产环境中见过的智能体系统常见模式。我们从基础构建模块——增强型 LLM——开始,逐步提高复杂度,从简单的组合式工作流直至自主智能体。

构建模块:增强型 LLM

智能体系统的基本构建模块,是经过检索、工具和记忆等增强的 LLM。我们当前的模型可以主动使用这些能力:自行生成搜索查询、选择合适的工具,并决定保留哪些信息。

增强型 LLM

我们建议把实现的重点放在两个方面:根据你的具体用例定制这些能力,并确保它们为 LLM 提供简单且文档完备的接口。实现这些增强的方式有很多,其中一种是借助我们最近发布的 Model Context Protocol,开发者只需一个简单的客户端实现,就能接入不断壮大的第三方工具生态。

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

工作流:提示链

提示链(prompt chaining)把任务分解为一系列步骤,每次 LLM 调用处理上一次调用的输出。你可以在任意中间步骤加入程序化检查(见下图中的“gate”),以确保整个过程仍在正轨上。

提示链工作流

何时使用该工作流:当任务可以轻松、清晰地分解为固定的子任务时,这个工作流最为理想。其主要目标是通过让每次 LLM 调用的任务更简单,以延迟换取更高的准确率。

提示链适用的示例:

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

工作流:路由

路由(routing)先对输入进行分类,再将其导向专门的后续任务。该工作流实现了关注点分离,并可以构建更专门化的提示词。没有这个工作流时,针对某一类输入的优化可能会损害其他输入上的表现。

路由工作流

何时使用该工作流:对于存在若干不同类别、分开处理效果更好的复杂任务,且分类可由 LLM 或更传统的分类模型/算法准确完成时,路由效果很好。

路由适用的示例:

  • 将不同类型的客服咨询(一般问题、退款请求、技术支持)导向不同的下游流程、提示词和工具。
  • 将简单/常见的问题路由到 Claude Haiku 4.5 这类更小、更具成本效益的模型,将困难/罕见的问题路由到 Claude Sonnet 4.5 这类能力更强的模型,以实现最佳性能。

工作流:并行化

LLM 有时可以同时处理一项任务,并通过程序对它们的输出进行汇总。这种并行化工作流主要有两种变体:

  • 分段(Sectioning):将任务拆分为相互独立的子任务并行运行。
  • 投票(Voting):多次运行同一任务以获得多样化的输出。

并行化工作流

何时使用该工作流:当拆分出的子任务可以并行以提高速度,或需要多种视角或多次尝试以获得更高置信度的结果时,并行化很有效。对于需要考虑多个因素的复杂任务,通常让每个因素由单独的 LLM 调用来处理,模型的表现更好,因为这样可以把注意力集中在每个具体方面。

并行化适用的示例:

  • 分段:
    • 实现护栏(guardrails):一个模型实例处理用户查询,另一个则筛查其中是否包含不当内容或请求。这通常比让同一次 LLM 调用同时处理护栏和核心响应效果更好。
    • 自动化评估(evals)来衡量 LLM 的表现,其中每次 LLM 调用评估模型在给定提示词上表现的不同方面。
  • 投票:
    • 审查一段代码是否存在漏洞,由多个不同的提示词分别审查,发现问题就标记。
    • 评估某段内容是否不当:由多个提示词评估不同方面,或设置不同的投票阈值,以平衡误报与漏报。

工作流:协调者-执行者

在协调者-执行者(orchestrator-workers)工作流中,一个中央 LLM 动态地拆解任务,将其委派给执行者 LLM,并综合它们的结果。

协调者-执行者工作流

何时使用该工作流:该工作流非常适合无法预知所需子任务的复杂任务(例如在编码中,需要修改的文件数量以及每个文件的修改性质,很可能取决于具体任务)。虽然在拓扑结构上与并行化相似,但关键区别在于其灵活性:子任务并非预先定义,而是由协调者根据具体输入来确定。

协调者-执行者适用的示例:

  • 每次都需要对多个文件做复杂修改的编码产品。
  • 需要从多个来源收集并分析信息、以找出可能相关内容的搜索任务。

工作流:评估者-优化者

在评估者-优化者(evaluator-optimizer)工作流中,一次 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 issue。不过,自动化测试虽然有助于验证功能,人工审查对于确保方案符合更广泛的系统要求仍然至关重要。

附录 2:为你的工具做提示工程

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

同一个操作往往有多种指定方式。例如,你可以通过编写 diff 来指定文件编辑,也可以重写整个文件。对于结构化输出,你可以把代码放在 markdown 里返回,也可以放在 JSON 里返回。在软件工程中,这类差异只是表面上的,可以无损地相互转换。然而,有些格式对 LLM 来说比其他格式难写得多。编写 diff 需要在写出新代码之前,就知道数据块头部中变化的行数。在 JSON 中编写代码(相比 markdown)则需要对换行符和引号做额外的转义。

我们对如何选定工具格式的建议如下:

  • 在模型把自己写进死胡同之前,给它足够的 token 来“思考”。
  • 让格式贴近模型在互联网文本中自然见到的形式。
  • 确保没有格式“开销”,例如不必精确统计成千上万行代码的行数,也不必对它写出的任何代码做字符串转义。

一条经验法则是:想想人机界面(HCI)上投入了多少精力,并计划为打造良好的智能体-计算机接口(ACI)投入同样多的精力。以下是关于如何做到这一点的一些想法:

  • 设身处地为模型着想。根据描述和参数,这个工具的用法是否显而易见,还是需要仔细思考才能明白?如果是后者,那么对模型来说多半也是如此。好的工具定义通常包含使用示例、边界情况、输入格式要求,以及与其他工具之间的清晰界限。
  • 如何修改参数名称或描述,让一切更加明了?可以把它想象成为团队里的初级开发者写一份出色的 docstring。当使用许多相似的工具时,这一点尤为重要。
  • 测试模型如何使用你的工具:在我们的 workbench 中运行大量示例输入,看看模型会犯哪些错误,然后迭代。
  • 对你的工具做 Poka-yoke(防呆设计)。修改参数,使其更难出错。

在为 SWE-bench 构建智能体时,我们花在优化工具上的时间其实比优化整体提示词还要多。例如,我们发现,在智能体离开根目录之后,模型使用相对文件路径的工具会出错。为了解决这个问题,我们把工具改为始终要求使用绝对文件路径,结果发现模型用起这个方法来毫无差错。