构建高效智能体(Building Effective Agents)

引言

这是在2024年12月20日发布的文章《Building Effective Agents》,Anthropic公司分享了他们在过去一年中与多个行业团队合作开发大型语言模型(Large Language Model, LLM)智能体的经验。文章的核心观点令人深思:最成功的智能体实现并非依赖于复杂的框架或专门的库,而是通过简单、可组合的模式构建而成。

以下是原文的翻译:

开篇

在过去的一年里,我们与各行各业的几十个团队合作,构建大型语言模型(LLM)智能体。成功的实施通常不依赖于复杂的框架或专用的库,而是采用简单、可组合的模式。

在这篇文章中,我们将分享与客户合作以及我们自己构建智能体的经验,并为开发人员提供构建高效智能体的实用建议。

什么是智能体?

"智能体"可以有多种定义。一些客户将智能体定义为能够独立运行较长时间的全自动系统,这些系统使用各种工具来完成复杂任务。另一些客户则用该术语来描述遵循预定义工作流的更具指导性的实现。在Anthropic,我们将所有这些变体归类为智能体系统,但在架构上对工作流和智能体进行了重要区分:

  • 工作流:指通过预定义代码路径来协调大型语言模型(LLMs)和工具(Tools)的系统
  • 智能体:指大型语言模型动态地指导自己的工作过程和工具使用,保持对任务完成方式的控制。

接下来,我们将详细探讨这两种类型的智能体系统。

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

在构建基于大语言模型(LLMs)的应用程序时,我们建议尽可能寻找最简单的解决方案,只有在需要时才增加复杂性。这可能意味着根本不需要构建智能体系统。智能体系统通常以延迟和成本为代价换取更好的任务性能,因此您需要权衡这种代价是否值得。

当确实需要更高的复杂性时,工作流(workflows)为定义明确的任务提供了可预测性和一致性,而智能体(agents)则是在需要灵活性和模型驱动的决策时更好的选择。然而,对于许多应用场景来说,通过检索和上下文示例优化,只使用大语言模型(LLM)调用通常已经足够。

何时以及如何使用框架

有许多框架可以简化智能体系统的实现,包括:

  • LangChain 的 LangGraph;
  • Amazon Bedrock 的 AI Agent 框架;
  • Rivet,一种拖放式 GUI LLM 工作流构建器;
  • Vellum,另一个用于构建和测试复杂工作流的 GUI 工具。

这些框架通过简化标准的底层任务(如调用 LLM、定义和解析工具以及链接调用)使入门变得容易。然而,它们通常会创建额外的抽象层,可能会掩盖底层的提示和响应,使其更难调试。此外,它们也可能让人倾向于增加不必要的复杂性,而简单的设置就已足够。

我们建议开发者首先直接使用 LLM API:许多模式可以通过几行代码实现。如果使用框架,请确保理解其底层代码。对底层机制的错误假设是客户错误的常见来源。

构建模块、工作流与智能体(Building blocks, workflows, and agents)

在本节中,我们将探讨在生产环境中常见的智能体系统(agentic systems)模式。我们将从基础构建模块------增强型大语言模型(augmented LLM)开始,逐步增加复杂性,从简单的组合工作流(compositional workflows)到自主智能体(autonomous agents)。

构建模块:增强型大语言模型(Building block: The augmented LLM)

智能体系统的基本构建模块是一个通过功能(如检索、工具和记忆)增强大语言模型(LLM)。我们当前的模型能够主动利用这些能力------生成自己的搜索查询、选择合适的工具,并决定保留哪些信息。

我们建议关注实现的两个关键方面:一是将这些功能定制化以适应您的特定用例,二是确保它们为您的 LLM 提供一个简单且文档齐全的接口。

虽然有多种实现这些增强功能的方法,但其中一种方法是通过我们最近发布的模型上下文协议(Model Context Protocol),该协议允许开发者通过简单的客户端实现与日益增长的第三方工具生态系统进行集成。

在本文的剩余部分中,我们将假设每次 LLM 调用都可以访问这些增强功能。

工作流:提示词链(Prompt Chaining)

提示链(Prompt Chaining)是一种将任务分解为一系列步骤的方法,其中每个大语言模型(LLM)调用都处理前一个步骤的输出。你可以在任何中间步骤中添加程序化检查(如下图所示中的"gate"),以确保整个流程仍在正确的轨道上。

何时使用此类工作流:此类工作流程非常适合那些可以轻松且清晰地将任务分解为固定子任务的情况。其主要目标是通过让每个LLM调用处理更简单的任务,以牺牲一定的响应速度来换取更高的准确性。

提示词链(Prompt Chaining)适用的示例

  • 生成营销文案(Marketing Copy),然后将其翻译成另一种语言。
  • 编写文档大纲(Outline),检查大纲是否符合特定标准,然后根据大纲撰写文档。

工作流:路由(Routing)

路由(Routing)是一种对输入进行分类并将其引导至专门的后续任务的工作流程。这种方法实现了关注点分离(Separation of Concerns),并允许构建更专业化的提示词(Specialized Prompts)。如果没有这种工作流,针对某一种输入的优化可能会损害其他输入的性能。

何时使用此类工作流:路由(Routing)适用于复杂任务,这些任务中存在需要分别处理的不同类别,并且分类可以通过 LLM 或更传统的分类模型/算法准确处理。

路由(Routing)适用的示例

  1. 将不同类型的客户服务查询(一般问题、退款请求、技术支持)引导到不同的下游流程、提示和工具。
  2. 将简单/常见问题路由到较小的模型如 Claude 3.5 Haiku,而将困难/不常见问题路由到更强大的模型如 Claude 3.5 Sonnet,以优化成本和速度。

工作流:并行化(Parallelization)

大语言模型(LLMs)有时可以同时处理多个任务,并通过程序化方式聚合它们的输出。这种工作流,即并行化(Parallelization),主要体现在两种关键形式中:

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

何时使用此工作流:当分解的子任务可以并行化以提高速度,或需要多个视角或尝试以获得更高置信度的结果时,并行化是有效的。对于有多个考虑因素的复杂任务,通常每个考虑因素由单独的 LLM 调用处理时效果更佳,这样可以专注于每个具体方面。

并行化(Parallelization)适用的示例

分段:

  1. 实施保护措施时,一个模型实例处理用户查询,而另一个则筛选不当内容或请求。这通常比让同一个 LLM 调用同时处理保护措施和核心响应要表现更好。
  2. 自动化评估 LLM 性能,其中每个 LLM 调用评估模型在给定提示下性能的不同方面。

投票:

  1. 审查代码中的漏洞,通过多个不同的提示审查代码,并在发现问题时标记。
  2. 评估给定内容是否不当,通过多个提示评估不同方面,或设置不同的投票阈值以平衡误报和漏报。

工作流:协调器-工作者(Orchestrator-Workers)

在协调器-工作者(Orchestrator-Workers)工作流中,一个中央大语言模型(LLM)动态地分解任务,将其分配给工作者大语言模型(Worker LLMs),并综合它们的结果。

何时使用此工作流:这种工作流非常适合复杂任务,尤其是当你无法预先预测所需的子任务时(例如在编程中,可能需要更改的文件数量以及每个文件中更改的性质通常取决于具体任务)。虽然在结构上与并行化相似,但其关键区别在于灵活性------子任务不是预先定义的,而是由指挥者根据特定输入来确定。

指挥者-工作者(Orchestrator-Workers)工作流适用的示例

  1. 编程产品需要每次对多个文件进行复杂更改。
  2. 搜索任务涉及从多个来源收集和分析信息,以寻找可能相关的信息。

工作流:评估器-优化器(Evaluator-Optimizer)

在评估器-优化器(Evaluator-Optimizer)工作流程中,一个大语言模型(LLM)调用生成响应,而另一个大语言模型(LLM)在循环中提供评估和反馈。

何时使用此工作流:当我们有明确的评估标准,并且迭代改进能够提供可衡量的价值时,这种工作流特别有效。适用的两个标志是:首先,当人们表达他们的反馈时,LLM 的响应可以显著改进;其次,LLM 能够提供这样的反馈。这类似于人类作者在创作精炼文档时可能经历的迭代写作过程。

评估器-优化器(Evaluator-Optimizer)适用的示例

  1. 文学翻译,其中翻译模型可能无法初步捕捉到细微差别,但评估模型可以提供有用的批评。
  2. 复杂的搜索任务,需要多轮搜索和分析以收集全面的信息,此时评估者决定是否需要进一步搜索。

智能体(Agents)

随着大语言模型(LLMs)在关键能力上的成熟------理解复杂输入(Understanding Complex Inputs)、进行推理和规划(Reasoning and Planning)、可靠地使用工具(Using Tools Reliably)以及从错误中恢复(Recovering from Errors)------智能体(Agents)正在生产中逐渐崭露头角。智能体(Agents)通常从人类用户的命令或交互式讨论开始工作。一旦任务明确,智能体(Agents)会独立规划和操作,并可能返回向人类用户请求更多信息或判断。在执行过程中,智能体(Agents)必须在每一步从环境中获取"真实数据"(Ground Truth)(例如工具调用结果或代码执行结果)以评估其进展。智能体(Agents)可以在检查点(Checkpoints)或遇到阻碍时暂停以获取人类反馈。任务通常在完成后终止,但也常见设置停止条件(Stopping Conditions)(例如最大迭代次数)以保持控制。

智能体(Agents)能够处理复杂的任务,但其实现通常较为直接。它们通常只是大语言模型(LLMs)在循环中基于环境反馈使用工具。因此,清晰且深思熟虑地设计工具集(Toolsets)及其文档至关重要。

何时使用智能体(Agents) :智能体适用于难以或无法预测所需步骤数量的开放性问题,以及无法硬编码固定路径的情况。LLM 可能需要进行多轮操作,因此您必须对其决策能力有一定程度的信任。智能体的自主性使其在可信环境中扩展任务时非常理想。

智能体的自主性意味着更高的成本和潜在的累积错误风险。我们建议在沙盒环境中进行广泛测试,并设置适当的防护措施。

智能体(Agents)有用的示例

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

  1. 一个用于解决 SWE-bench 任务的编码智能体,这些任务涉及根据任务描述编辑多个文件;
  2. 我们的"Computer Use",Claude 使用计算机来完成任务。

结合和定制这些模式

这些构建模块并不是规定性的。它们是开发人员可以根据不同用例塑造和组合的常见模式。与任何 LLM 功能一样,成功的关键在于衡量性能并对实现进行迭代。再次强调:只有在明确改善结果的情况下,才应考虑增加复杂性。

总结

在 LLM 领域取得成功并不是要构建最复杂的系统,而是要构建适合您需求的系统。首先使用简单的提示,通过全面评估进行优化,只有在简单解决方案不足时才添加多步骤的智能体系统。

在实现智能体时,我们尝试遵循三个核心原则:

  1. 保持智能体设计的简单性。
  2. 优先考虑透明度,明确展示智能体的规划步骤。
  3. 通过详尽的工具文档和测试,仔细设计智能体-计算机接口(ACI)。

框架可以帮助您快速入门,但在进入生产阶段时,不要犹豫减少抽象层,使用基本组件进行构建。通过遵循这些原则,您可以创建不仅强大而且可靠、可维护且受用户信任的智能体。

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

我们与客户的合作揭示了两个特别有前景的 AI 智能体应用,这些应用展示了上述模式的实际价值。这两个应用说明了智能体如何在需要对话和行动的任务中增加最大价值,具有明确的成功标准,能够实现反馈循环,并整合有意义的人类监督。

A. 客户支持

客户支持将熟悉的聊天机器人界面与通过工具集成增强的功能相结合。这对于更开放式的智能体来说是一个自然的契合,因为:

  • 支持交互自然遵循对话流程,同时需要访问外部信息和执行操作;
  • 可以集成工具以提取客户数据、订单历史和知识库文章;
  • 可以通过编程方式处理诸如退款或更新工单等操作;
  • 成功可以通过用户定义的解决方案清晰地衡量。

一些公司通过基于使用的定价模型(仅对成功解决方案收费)证明了这种方法的可行性,显示出对其智能体有效性的信心。

B. 编程智能体

软件开发领域在 LLM 功能方面显示出显著潜力,其能力从代码补全发展到自主问题解决。智能体特别有效,因为:

  • 代码解决方案可以通过自动化测试进行验证;
  • 智能体可以使用测试结果作为反馈来迭代解决方案;
  • 问题空间定义明确且结构良好;
  • 输出质量可以客观衡量。

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

附录 2:工具的提示工程

无论您构建哪种智能体系统,工具可能都是您的智能体的重要组成部分。工具使 Claude 能够通过在我们的 API 中指定其确切结构和定义来与外部服务和 API 交互。当 Claude 响应时,如果计划调用工具,它将在 API 响应中包含一个工具使用块。工具定义和规格应该像整体提示一样得到提示工程的关注。在这个简短的附录中,我们描述了如何进行工具的提示工程。

通常有多种方法可以指定相同的操作。例如,可以通过编写差异(diff)或重写整个文件来指定文件编辑。对于结构化输出,可以在 markdown 或 JSON 中返回代码。在软件工程中,这些差异是表面的,可以无损地相互转换。然而,某些格式比其他格式更难让 LLM 编写。编写差异需要在新代码编写之前知道块头中有多少行正在更改。相比于 markdown,在 JSON 中编写代码需要额外的换行和引号转义。

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

  1. 给模型足够的 token 以便在写入之前"思考",避免陷入困境。
  2. 保持格式接近模型在互联网上自然看到的文本。
  3. 确保没有格式"开销",例如保持数千行代码的准确计数或对其编写的代码进行字符串转义。

一个经验法则是,考虑在人机界面(HCI)上投入了多少精力,并计划在创建良好的智能体-计算机界面(ACI)上投入同样多的精力。以下是一些实现方法的想法:

  • 设身处地为模型着想。根据描述和参数,使用这个工具是否显而易见,还是需要仔细思考?如果是这样,那么对模型来说可能也是如此。一个好的工具定义通常包括使用示例、边界情况、输入格式要求以及与其他工具的明确界限。
  • 如何更改参数名称或描述以使其更明显?可以将其视为为团队中的初级开发人员编写优秀的文档字符串。这在使用许多相似工具时尤为重要。
  • 测试模型如何使用您的工具:在我们的工作台中运行许多示例输入,观察模型犯的错误并进行迭代。
  • Poka-yoke(防错)您的工具。更改参数以使其更难出错。

在为 SWE-bench 构建智能体时,我们实际上花费了更多时间优化工具而非整体提示。例如,我们发现模型在智能体移出根目录后使用相对文件路径的工具时会出错。为了解决这个问题,我们更改了工具以始终要求绝对文件路径------我们发现模型使用这种方法时表现得非常出色。

相关推荐
dong_junshuai3 小时前
每天一个开源项目#99 OpenResearch:2.2K星的本地研究Agent工作台
开源·github·agent
花椒技术3 小时前
把 AI 视频接进直播:提前生成、按次生成、持续生成怎么选?
agent·音视频开发
用户8082598666873 小时前
用 LangGraph 重写自己手写的 Agent:框架替你解决了什么,什么它不管
agent
能不能静下心来看3 小时前
从 RAG 到 Agent:跑通两个 Demo 后,我终于分清了这两个词
agent
ZGi.ai3 小时前
知识库权限变了,怎样避免答错?
agent·权限管理·知识库·工作流·zgi·客服运营
大模型真好玩3 小时前
DeepSeek Harness 入门很简单(四)——DeepSeek Harness接入插件
人工智能·agent·deepseek
掰头战士3 小时前
MCP、Skill、Plugin,都是给agent拓展能力,到底有何区别?
typescript·llm·agent
嘟嘟嘟95275 小时前
AI Agent 的边缘困境
人工智能·架构·agent
HYDtomako5 小时前
Agent checkpoint设计
ai·agent·checkpoint·claude code
梦在远山后5 小时前
从需求到架构:我的企业研发 Agent 整体设计
langchain·agent