文章目录
原文链接:https://www.anthropic.com/research/building-effective-agents
最近为了自己方便,着手编写一个 Obsibian AI 插件 , 项目地址:https://github.com/lmz2423/obsidian-ai-plugin (刚刚搭建好插件结构,等功能编写完成,再上传 obsibian插件市场)
目前 Obsibian
三方市场的插件没有一个能够满足自己要求 的。在查阅相关资料中,读取到相关资料看了这篇文章。先翻译一下,做个记录。
译文如下
在过去的一年里,我们与来自多个行业的团队合作,帮助他们开发基于大语言模型(LLM)的代理系统。我们发现,那些成功的实现通常不依赖复杂的框架或专用库,而是采用了一些简单、灵活且可组合的设计模式。
本文将结合我们与客户的合作经验和自身实践,向开发者提供一些构建高效代理系统的实用建议。
什么是 Agent?
“Agent” 的定义多种多样。一些客户认为它是可以独立运行较长时间、利用多种工具完成复杂任务的全自主系统。另一些客户则将其看作执行预定义流程的工具。在 Anthropic,我们将这些统称为 agentic 系统,但特别区分了工作流和 Agent 的架构特点:
- 工作流是指通过编程预设的路径,协调大语言模型(LLM)和工具来完成任务。
- Agent则是让 LLM 自主决定任务流程并灵活使用工具,具备更强的任务掌控能力。
我们将在下文详细介绍这两类系统,并在附录 1(“实践中的 Agent”)中列举具体应用案例。
什么时候该用 Agent,又什么时候不该用?
在用大语言模型开发应用时,尽量选择简单的方案,仅在必要时增加复杂性。对于某些应用来说,完全不需要 agentic 系统。Agentic 系统通常在响应速度和运行成本上有所妥协,以提升任务完成质量。需要根据实际情况判断是否值得。
当需要更复杂的功能时,工作流提供了稳定性和一致性,适合规则明确的任务;而当需要更高的灵活性和自主决策能力时,Agent则更胜一筹。然而,对于大多数应用来说,优化单次 LLM 调用(结合检索和上下文示例)往往已经足够。
选择和使用框架的建议
现有框架可以帮助快速搭建 agentic 系统,比如:
- LangChain 的 LangGraph;
- Amazon Bedrock 的 AI Agent 框架;
- Rivet,拖放式的工作流构建工具;
- Vellum,另一种用于设计复杂流程的工具。
这些工具简化了基础任务,如调用 LLM、定义工具和链接任务等。不过,它们也可能隐藏底层的交互逻辑,增加调试难度,或让开发者过度复杂化设计。
建议开发者直接从 LLM API 开始,很多功能用几行代码就能实现。如果使用框架,一定要理解其底层逻辑,对内部构造的错误假设是客户常见错误的根源。
可以 参考我们的 CookBook 来获取实现案例。
构建模块、工作流程和 Agent
在本节,我们探讨了代理 系统的常见实现模式。从最基础的“增强型 LLM”开始,逐步增加复杂性,从简单工作流到完全自主的 Agent。
基础模块:增强型 LLM
代理系统的核心是增强型 LLM,其功能包括信息检索、工具调用和记忆。我们的模型已经可以主动生成搜索请求、选择工具,以及决定哪些信息需要保留。
增强型LLM
我们建议从两个关键点入手来优化实现:一是根据您的具体需求定制功能,二是确保这些功能能够通过一个简单且文档完善的接口支持您的大语言模型(LLM)。虽然增强功能的实现方法多种多样,但我们推荐使用最近推出的模型上下文协议(Model Context Protocol)。通过该协议,开发者可以轻松实现与不断发展的第三方工具生态系统的集成。
接下来,本文将假设每次调用 LLM 时都能使用这些增强功能。
工作流:提示链模式(Prompt Chaining)
提示链是一种将任务分解为多个步骤的方法。每一步的输出会作为下一步的输入由 LLM 处理。为了确保整个流程保持在正确轨道上,您可以在任意中间步骤加入程序化检查(参见下图中的“闸门”)。
适用场景:
当任务可以被清晰地分解为几个固定的子任务时,这种工作流程特别适用。它的核心理念是通过将复杂任务分解为简单步骤来提高准确性,即使会牺牲一些响应速度。
提示链的典型应用场景:
- 创建营销文案后,将其翻译成其他语言。
- 制作文档大纲,验证大纲是否符合要求,然后基于大纲完成文档撰写。
工作流:路由模式(Routing)
路由是一种对输入进行分类的方法,它会将不同类型的输入引导到对应的专门任务。这种工作流程能够有效地分离任务重点,并设计更有针对性的提示。在缺乏路由机制的情况下,针对某类输入进行优化可能会导致其他类型输入的性能下降。
适用场景:
路由模式适合用于复杂任务,尤其是当任务可以分为不同类别,并且能够通过 LLM 或传统分类算法准确分类时。
路由模式的应用示例:
- 将不同类型的客户服务请求(如常见问题、退款申请、技术支持)分配到专门的下游流程或工具,以提高效率。
- 将简单或常见的问题分配给较小模型(如 Claude 3.5 Haiku),而将更复杂或罕见的问题分配给更强大的模型(如 Claude 3.5 Sonnet),从而在成本与速度之间实现平衡。
工作流程:并行化(Parallelization)
并行化是一种通过同时处理任务提高效率的工作流程,其核心思路是并行运行多个任务,然后通过编程汇总输出。具体包括两种方式:
- 分段(Sectioning): 将任务拆解为彼此独立的子任务,并同时处理这些子任务。
- 投票(Voting): 针对同一任务进行多次运行,以生成多样化的结果。
适用场景:
并行化非常适合需要提高效率或可信度的任务场景。通过将任务分解为独立子任务并行处理,可以加快速度;通过采用多种视角或多次尝试,则能确保更高的结果可靠性。对于复杂任务,LLM 在每个子任务由独立调用处理时,通常会有更好的表现,因为这样可以让每个调用专注于特定问题。
并行化的应用示例:
分段处理:
- 在实施内容审查保护措施时,使用一个模型实例专注处理用户查询,另一个模型实例专注筛选不当请求。这比让同一个模型同时完成两项任务更高效。
- 对 LLM 性能进行自动化评估时,每次调用负责评估模型表现的不同方面,例如准确性、连贯性或创造力。
投票机制:
- 对代码进行安全审查,使用多个提示从不同角度检查代码,发现潜在问题时进行标记。
- 判断某段内容是否不当,通过多个提示进行多角度评估,并设置投票门槛,平衡误报(false positive)和漏报(false negative)之间的关系。
工作流程:编排者-工作者(Orchestrator-workers)
在编排者-工作者的流程中,一个中央 LLM 会根据任务的具体需求动态地将任务分解成子任务,并将这些子任务分配给多个工作者 LLM 进行处理,最终将所有结果整合为完整的输出。
适用场景:
这种流程非常适合于任务复杂且子任务难以预先确定的情况。例如:
- 在软件开发中,不同的任务可能涉及多个文件的复杂修改,每个文件的修改需求可能大不相同。
- 搜索和分析任务,需要从多个来源收集信息,并对这些信息进行筛选和整合,以找到最相关的内容。
应用示例:
- 需要对多个文件进行复杂修改的编码工具。
- 涉及从不同信息来源搜集和分析数据的复杂搜索任务。
工作流程:评估者-优化者(Evaluator-optimizer)
在评估者-优化者的工作流程中,一个 LLM 负责生成初始响应,另一个 LLM 对其进行评估并提供反馈,循环往复,直到输出结果满足质量要求。
适用场景:
评估者-优化者流程非常适合那些有明确评价标准,并且通过反复优化能显著提升结果质量的任务。两个主要判断标准是:一方面,LLM 的输出可以通过人类反馈得到明显改进;另一方面,LLM 自身能够提供有价值的反馈。这种工作方式类似于人类作者在编写高质量文档时反复修改的过程。
应用示例:
- 文学翻译任务,初始翻译可能遗漏了一些细腻的语言表达,但评估 LLM 能够指出问题并提出改进建议。
- 复杂的搜索任务,需要多次检索和分析以获得全面信息,由评估 LLM 决定是否需要继续进行更深入的搜索。
代理
随着大语言模型(LLM)在处理复杂输入、推理与规划、可靠工具使用以及错误恢复方面能力的提升,代理(Agents)逐渐在实际生产中得到应用。代理的工作流程通常始于用户的指令或互动。一旦任务目标明确,代理会自主制定计划并执行任务,同时在需要时返回向用户获取额外信息或决策支持。在执行过程中,代理需要从环境中获取真实数据(如工具返回的结果或代码执行的反馈),以便判断当前进度。当代理达到检查点或遇到难题时,可以暂停并寻求用户的反馈。任务通常在完成时结束,但也可以通过设置最大迭代次数等条件来防止任务失控。
虽然代理能够胜任复杂任务,但它们的实现方式通常相对简单。它们本质上是基于环境反馈循环调用工具的 LLM。这使得工具集的设计与文档的清晰性显得尤为重要。在附录 2(“提示工程工具”)中,我们对工具开发的最佳实践进行了深入阐述。
适用场景:
代理非常适合那些开放式任务,尤其是当任务步骤无法预先确定,或者无法通过固定流程解决时。在这些情况下,LLM 需要多轮操作,因此对其决策能力的信任至关重要。代理的自主性使它在可信环境中扩展复杂任务特别高效。
不过,代理的自主性也带来了更高的成本和累积错误的风险。因此,我们建议在沙盒环境中对代理进行充分测试,并设置合适的保护机制以减少风险。
应用示例:
以下是我们在实际中使用代理的两个示例:
- 用于解决 SWE-bench 任务的编码代理,这些任务需要根据描述修改多个文件。
- 一个“计算机使用”的参考实现,Claude 通过模拟计算机操作完成各种任务。
结合与定制这些模式
这些模式是通用的设计思路,并非固定的规则。开发者可以根据实际需求灵活调整和组合它们以适应不同的应用场景。和所有 LLM 功能一样,关键在于持续监测性能表现并不断优化实现过程。再次强调,只有当复杂化能够清楚地提升效果时,才需要增加复杂性。
总结
在 LLM 领域,成功的关键不在于构建最复杂的系统,而是开发出最能满足实际需求的解决方案。从简单的提示入手,通过全面的评估优化设计,只有当简单方法无法达到预期效果时,再考虑引入多步骤的代理系统。
我们在开发代理时坚持以下三大原则:
- 保持设计简单,避免不必要的复杂性;
- 强调透明性,清晰展示代理的每一步规划过程;
- 精心设计代理与计算机的接口(ACI),通过完善的工具文档和测试确保可靠性。
框架能让您快速起步,但在将系统投入实际应用时,可以选择减少抽象层,基于基本模块进行构建。通过坚持这些原则,您可以打造功能强大、可靠性高、易于维护且深受用户信赖的代理系统。
致谢
本文由 Erik Schluntz 和 Barry Zhang 撰写,内容基于我们在 Anthropic 开发代理系统的经验,以及客户分享的宝贵见解。对此,我们深表感谢。
附录 1:实践中的代理
根据与客户的合作经验,我们发现 AI 代理在两个领域具有极大的应用潜力,这充分展示了之前讨论的模式在实践中的实际价值。这些应用表明,代理在需要结合对话与行动的任务中,尤其有助于实现明确的目标、提供反馈机制,并在过程中融入适当的人类监督。
A. 客户支持
在客户支持中,传统的聊天机器人界面结合了工具集成后的增强功能。这种开放式代理在以下方面尤其适用:
- 客户支持的对话流程需要外部数据访问和操作;
- 可以通过工具获取客户数据、订单历史或知识库内容;
- 类似退款或更新工单的任务可以通过编程完成;
- 用户定义的解决方案提供了清晰的成功衡量标准。
一些公司通过基于成功案例收费的定价模式验证了这一方法的可行性,体现了对代理性能的信心。
B. 编码代理
软件开发领域对 LLM 的应用潜力巨大,从代码补全发展到自主问题解决。这些代理的优势包括:
- 自动化测试可以验证代码解决方案的正确性;
- 代理可以利用测试反馈反复改进解决方案;
- 问题空间具有明确的结构化定义;
- 输出质量能够被客观地评估。
在我们的实现中,代理可以根据拉取请求的描述,独立解决 SWE-bench Verified 基准中的 GitHub 问题。不过,虽然自动化测试能验证功能是否正常,但人类审查仍是确保方案符合全局系统需求的重要环节。
附录 2:工具的提示工程
无论您构建何种代理系统,工具往往是不可或缺的一部分。通过在 API 中定义工具的结构和功能,可以使 Claude 调用外部服务和 API。如果 Claude 决定使用工具,它会在 API 响应中包含工具调用的相关信息。因此,工具的设计和定义需要和提示工程一样被高度重视。在这里,我们简要说明如何优化工具提示。
同一任务可以有多种定义方式。例如,文件编辑可以通过“写入差异”或“重写整个文件”实现;对于结构化输出,可以选择 Markdown 或 JSON 格式。这些差异对开发者来说可能无关紧要,但对 LLM 来说却会影响难度。比如,“写入差异”需要提前计算变更的行数,而 JSON 格式要求转义换行符和引号。
以下是我们选择工具格式的建议:
- 确保模型有足够的 token 进行推理,避免在生成内容时受限;
- 格式尽量贴近模型在互联网上见过的自然文本;
- 避免增加不必要的复杂性,例如转义符或行数计数。
一个原则是,像设计人机交互界面(HCI)一样设计良好的代理计算机接口(ACI)。以下是一些具体做法:
- 换位思考工具是否易于使用。如果您需要仔细思考如何使用,模型也可能有同样的困惑。提供示例用法、边界情况和清晰的输入说明会更有效。
- 优化参数名称和描述,尽量清晰明了。想象为团队中的新人编写注释文档,特别是在工具多样时尤为重要。
- 测试工具的使用效果:通过多次测试找到问题并改进。
- 防错设计(Poka-yoke):通过参数设计减少模型犯错的机会。
在开发 SWE-bench 的代理时,我们发现优化工具的设计比总体提示更重要。例如,为了避免使用相对路径的工具出错,我们强制使用绝对路径,结果显著提升了模型的表现。
发表评论