Agent 的7 中设计模式
这里写自定义目录标题
- 建立有效的Agent
- 什么是Agent?
- 何时(以及何时不使用)使用代理
- 何时以及如何使用框架
- 构建块、工作流和Agent
- 构建模块:增强型LLM(The augmented LLM)
- 工作流程:提示链接(Prompt chaining)
- 工作流程:并行化(Parallelization)
- 工作流程:路由(Routing)
- 工作流程:评估器-优化器(Evaluator-optimizer)
- 工作流程:Orchestrator-workers
- 代理商(Agent)
code: https://github.com/daiyizheng/DL/tree/master/08-llms/Agent_
建立有效的Agent
什么是Agent?
“代理” 有多种定义。一些客户将代理定义为完全自主的系统,能够在较长时间内独立运行,使用各种工具完成复杂任务。另一些客户则用该术语来描述遵循预定义工作流程的更具规范性的实现。在 Anthropic,我们将所有这些变体归类为代理系统,但在工作流程和代理之间划出了一个重要的架构区别:
工作流是通过预定义代码路径协调 LLM 和工具的系统。
另一方面,代理是 LLM 动态指导其自身流程和工具使用的系统,可以控制其完成任务的方式。
下面,我们将详细探讨这两种代理系统。在附录1(“代理实践”)中,我们描述了客户发现这类系统在两个领域中具有特殊价值。
何时(以及何时不使用)使用代理
使用 LLM 构建应用程序时,我们建议寻找尽可能简单的解决方案,并且仅在需要时增加复杂性。这可能意味着根本不要构建代理系统。代理系统通常会牺牲延迟和成本来换取更好的任务性能,您应该考虑这种权衡何时合理。
当需要处理更多复杂性时,工作流可以为定义明确的任务提供可预测性和一致性;而当需要大规模灵活性和模型驱动的决策时,代理则是更好的选择。然而,对于许多应用而言,使用检索和上下文示例来优化单个 LLM 调用通常就足够了。
何时以及如何使用框架
有许多框架可以使代理系统更易于实现,包括:
- LangChain 的LangGraph ;
- Amazon Bedrock 的AI Agent 框架;
- Rivet,一个拖放式 GUI LLM 工作流构建器;
- Vellum,另一个用于构建和测试复杂工作流程的 GUI 工具。
这些框架简化了标准的低级任务,例如调用 LLM、定义和解析工具以及链接调用,从而简化了入门流程。然而,它们通常会创建额外的抽象层,这可能会掩盖底层的提示和响应,使其更难调试。此外,它们还可能让人倾向于增加复杂性,而实际上更简单的设置就足够了。
我们建议开发者从直接使用 LLM API 开始:许多模式只需几行代码即可实现。如果您确实使用框架,请确保您了解底层代码。对底层机制的错误假设是客户常见的错误来源。
请参阅我们的食谱来了解一些示例实现。
构建块、工作流和Agent
在本节中,我们将探讨在生产环境中常见的代理系统模式。我们将从基础构建块——增强型 LLM 开始,逐步增加复杂性,从简单的组合工作流到自主代理。
构建模块:增强型LLM(The augmented LLM)
代理系统的基本构建模块是 LLM,并通过检索、工具和记忆等功能进行增强。我们当前的模型可以主动使用这些功能——生成自己的搜索查询、选择合适的工具并确定要保留的信息。
我们建议重点关注实现的两个关键方面:根据您的具体用例定制这些功能,并确保它们为您的 LLM 提供简单易用且文档齐全的界面。虽然实现这些增强功能的方法有很多,但其中一种方法是通过我们最近发布的模型上下文协议,它允许开发人员通过简单的客户端实现与不断增长的第三方工具生态系统集成。
对于本文的其余部分,我们假设每个 LLM 调用都可以访问这些增强功能。
工作流程:提示链接(Prompt chaining)
提示链将任务分解为一系列步骤,其中每个 LLM 调用都会处理前一个步骤的输出。您可以在任何中间步骤上添加程序化检查(参见下图中的“门”),以确保流程仍在正常进行。
何时使用此工作流程:此工作流程非常适合任务可以轻松清晰地分解为固定子任务的情况。其主要目标是通过简化每次 LLM 调用,以降低延迟并提高准确率。
提示链有用的示例:
- 生成营销文案,然后将其翻译成不同的语言。
- 撰写文档大纲,检查大纲是否符合某些标准,然后根据大纲撰写文档。
工作流程:并行化(Parallelization)
LLM 有时可以同时处理一项任务,并以编程方式聚合其输出。这种工作流程(并行化)体现在两个关键变化中:
- 分段:将任务分解为并行运行的独立子任务。
- 投票:多次运行相同的任务以获得不同的输出。
何时使用此工作流程:当拆分后的子任务可以并行化以提高速度,或者需要多个视角或尝试以获得更高置信度的结果时,并行化非常有效。对于涉及多个考量的复杂任务,当每个考量都由单独的 LLM 调用处理时,LLM 通常表现更好,从而能够专注于每个特定方面。
并行化有用的示例:
- 切片:
实现防护机制,其中一个模型实例处理用户查询,而另一个模型实例则筛选不适当的内容或请求。这通常比使用同一个 LLM 调用同时处理防护机制和核心响应效果更好。
自动评估 LLM 性能,其中每次 LLM 调用都会评估模型在给定提示上性能的不同方面。 - 投票:
审查一段代码是否存在漏洞,如果发现问题,几个不同的提示会审查并标记代码。
评估给定的内容是否不适当,使用多个提示评估不同的方面或要求不同的投票阈值来平衡误报和误报。
工作流程:路由(Routing)
路由会对输入进行分类,并将其定向到专门的后续任务。此工作流程允许分离关注点,并构建更专业的提示。如果没有此工作流程,针对一种输入进行优化可能会损害其他输入的性能。
何时使用此工作流程:路由非常适合复杂任务,其中存在不同的类别,最好分别处理,并且可以通过 LLM 或更传统的分类模型/算法准确处理分类。
路由有用的示例:
- 将不同类型的客户服务查询(一般问题、退款请求、技术支持)引导到不同的下游流程、提示和工具中。
- 将简单/常见问题路由到较小的模型(如 Claude 3.5 Haiku),将困难/不寻常的问题路由到功能更强大的模型(如 Claude 3.5 Sonnet),以优化成本和速度。
工作流程:评估器-优化器(Evaluator-optimizer)
在评估器-优化器工作流中,一个 LLM 调用生成响应,而另一个调用在循环中提供评估和反馈。
何时使用此工作流程:当我们拥有清晰的评估标准,并且迭代改进能够提供可衡量的价值时,此工作流程尤其有效。良好契合的两个标志是:首先,当人类清晰地表达反馈时,LLM 的答案可以得到显著的改进;其次,LLM 能够提供这样的反馈。这类似于人类作家在撰写一篇精良文档时可能经历的迭代写作过程。
评估器-优化器有用的示例:
- 文学翻译中存在一些细微差别,翻译人员(LLM)最初可能无法捕捉到,但评估人员(LLM)可以提供有用的批评。
- 复杂的搜索任务需要多轮搜索和分析才能收集全面的信息,评估人员将决定是否需要进一步搜索。
工作流程:Orchestrator-workers
在协调器-工作者工作流中,中央 LLM 动态分解任务,将其委托给工作者 LLM,并综合其结果。
何时使用此工作流程:此工作流程非常适合无法预测所需子任务的复杂任务(例如,在编码过程中,需要更改的文件数量以及每个文件的更改性质可能取决于任务本身)。虽然它在拓扑结构上与并行化类似,但其与并行化的关键区别在于灵活性——子任务并非预先定义,而是由编排器根据具体输入确定。
Orchestrator-workers 有用的示例:
- 每次对多个文件进行复杂更改的编码产品。
- 搜索任务涉及从多个来源收集和分析信息以获取可能相关的信息。
代理商(Agent)
随着 LLM 在关键能力(理解复杂输入、进行推理和规划、可靠地使用工具以及从错误中恢复)方面的日趋成熟,代理正在投入生产。代理可以通过人类用户的命令或与人类用户的互动讨论开始工作。一旦任务明确,代理就会独立规划和操作,并可能返回给人类以获取更多信息或判断。在执行过程中,代理必须从每一步(例如工具调用结果或代码执行)的环境中获取“基本事实”以评估其进度。然后,代理可以在检查点或遇到阻碍时暂停以等待人类的反馈。任务通常在完成后终止,但通常也会包含停止条件(例如最大迭代次数)以保持控制。
代理可以处理复杂的任务,但它们的实现通常很简单。它们通常只是基于环境反馈循环使用工具的LLM。因此,清晰周到地设计工具集及其文档至关重要。我们将在附录2(“快速设计你的工具”)中详细阐述工具开发的最佳实践。
何时使用代理:代理可用于解决开放式问题,这类问题难以甚至无法预测所需的步数,并且无法硬编码固定路径。LLM 可能会运行多轮,您必须对其决策有一定程度的信任。代理的自主性使其成为在可信环境中扩展任务的理想选择。
代理的自主性意味着更高的成本,以及出现复合错误的可能性。我们建议在沙盒环境中进行广泛的测试,并采取适当的防护措施。
代理有用的示例:
以下示例来自我们自己的实现:
- 一个编码代理,用于解决SWE-bench 任务,该任务涉及根据任务描述对许多文件进行编辑;
我们的“计算机使用”参考实现,其中 Claude 使用计算机来完成任务。