当前位置: 首页 » 资讯 » 新科技 » 正文

Agent不听话、总犯错?Claude官方开发指南:手把手教你打造高效工具,让大模型秒变“靠谱员工”

IP属地 中国·北京 AI寒武纪 时间:2025-09-12 18:22:02


Anthropic 这篇《Writing effective tools for AI agents — with agents》把给智能体写工具从零散经验上升为可复现的方法论:强调以评估驱动的迭代流程、以Agents为中心的工具设计原则(namespacing、简洁响应、token 效率等),并展示用 Claude 自身去分析/优化工具的实战路径——这对工程落地、产品设计和行业标准化都具有立刻可用的价值


过去我们把 API 当成给程序员用的契约,现在要把接口重新设计成能被会思考的模型理解的工具。Anthropic 这篇工程帖子,把这件事从经验总结,推演成一套可执行的工程流程——从原型、评估、到让 Claude 自己参与改进工具。读完它,你会发现:未来的后端接口设计,不再只为了机器——而是为了会推理的机器

Agent的效能取决于提供给它们的工具。本文将分享如何编写高质量的工具和评估方法,以及如何利用 Claude 来为它自己优化工具,从而提升性能

模型上下文协议(Model Context Protocol, MCP)可以为大语言模型代理赋予数百种工具来解决现实世界的任务。但如何使这些工具的效能最大化呢?

本文将介绍在多种代理 AI 系统中提升性能最有效的技巧

首先,本文将涵盖如何:

1.构建和测试工具的原型

2.创建并运行针对代理使用工具的全面评估

3.与像 Claude Code 这样的代理协作,自动提升工具的性能

最后,本文将总结在此过程中总结出的编写高质量工具的关键原则:

选择正确的工具进行实现(以及不实现)

通过命名空间为工具定义清晰的功能边界

从工具向代理返回有意义的上下文

优化工具响应的词元(token)效率

通过提示工程优化工具描述和规范


什么是工具?

在计算领域,确定性系统在给定相同输入时总是产生相同的输出,而非确定性系统——比如代理——即使在起始条件相同的情况下也可能生成不同的响应。

在传统软件编写中,是在确定性系统之间建立一种契约。例如,像 getWeather("NYC") 这样的函数调用,每次执行时都会以完全相同的方式获取纽约市的天气。

工具是一种新型软件,它反映了确定性系统与非确定性代理之间的契约。当用户问“我今天需要带伞吗?”,代理可能会调用天气工具,也可能根据常识回答,甚至可能先询问地点等澄清性问题。偶尔,代理可能会产生幻觉,或者无法理解如何使用某个工具。

这意味着在为代理编写软件时,需要从根本上反思方法:不能像为其他开发者或系统编写函数和 API 那样来编写工具和 MCP 服务器,而是需要为代理进行设计。

目标是通过使用工具来追求各种成功的策略,从而扩大代理能够有效解决各类任务的范围。幸运的是,根据经验,那些对代理而言最“易于使用”的工具,最终对人类来说也出乎意料地直观易懂。

如何编写工具

本节将介绍如何与代理协作来编写并改进提供给它们的工具。首先,快速搭建一个工具原型并在本地进行测试。接着,运行一次全面的评估来衡量后续的改动效果。通过与代理协同工作,可以重复评估和改进工具的流程,直到代理在真实世界任务上取得优异的性能。

构建原型

在没有亲身实践的情况下,很难预见哪些工具对代理来说是易于使用的,哪些不是。首先应快速搭建一个工具原型。如果使用 Claude Code 编写工具(可能是一次性生成),向 Claude 提供工具所依赖的任何软件库、API 或 SDK(可能包括 MCP SDK)的文档会很有帮助。大语言模型友好的文档通常可以在官方文档网站的扁平化 llms.txt 文件中找到。

将工具包装在本地 MCP 服务器或桌面扩展(DXT)中,就可以在 Claude Code 或 Claude 桌面应用中连接并测试工具。

要将本地 MCP 服务器连接到 Claude Code,运行 claude mcp add [args...]

要将本地 MCP 服务器或 DXT 连接到 Claude 桌面应用,分别导航至“设置 > 开发者”或“设置 > 扩展”

工具也可以直接传递到 Anthropic API 调用中进行编程化测试

亲自测试这些工具,找出任何不顺手的地方。收集用户的反馈,以便对工具所要支持的用例和提示建立直观的理解。

运行评估

接下来,需要通过运行评估来衡量 Claude 使用工具的效果。首先,基于真实世界用例生成大量的评估任务。建议与代理协作,帮助分析结果并确定如何改进工具


生成评估任务

利用早期原型,Claude Code 可以快速探索工具并创建数十个提示和响应对。提示应受到真实世界用例的启发,并基于现实的数据源和服务(例如,内部知识库和微服务)。建议避免使用过于简单或肤浅的“沙盒”环境,因为它们无法以足够的复杂性对工具进行压力测试。一个好的评估任务可能需要多次工具调用——甚至可能多达数十次

以下是一些好的任务示例:

安排下周与 Jane 开会,讨论最新的 Acme 公司项目。附上我们上次项目规划会议的纪要,并预订一间会议室

客户 ID 9182 报告称,他们的一次购买尝试被收取了三次费用。找出所有相关的日志条目,并确定是否有其他客户受到同样问题的影响

客户 Sarah Chen 刚刚提交了取消请求。准备一份挽留方案。确定:(1) 他们离开的原因,(2) 哪种挽留方案最具吸引力,以及 (3) 在提出方案前需要注意的任何风险因素。

以下是一些较弱的任务示例:

安排下周与 jane@acme.corp 开会

在支付日志中搜索 purchase_complete 和 customer_id=9182

根据客户 ID 45892 查找取消请求

每个评估提示都应配有一个可验证的响应或结果。验证器可以像基准真相与采样响应之间的精确字符串比较一样简单,也可以像让 Claude 来评判响应一样高级。避免使用过于严格的验证器,它们可能会因为格式、标点或有效的替代表述等无关紧要的差异而拒绝正确的响应。

对于每个提示-响应对,可以选择性地指定期望代理在解决任务时调用的工具,以衡量代理在评估过程中是否成功掌握了每个工具的用途。然而,由于解决任务可能存在多种有效路径,应尽量避免过度指定或对特定策略过拟合。

运行评估

建议通过直接调用 LLM API 以编程方式运行评估。使用简单的代理循环(包裹着交替的 LLM API 和工具调用的 while 循环):每个评估任务一个循环。每个评估代理都应被赋予一个任务提示和相应的工具。

在评估代理的系统提示中,建议不仅指示代理输出结构化的响应块(用于验证),还要输出推理和反馈块。指示代理在工具调用和响应块之前输出这些内容,可能会触发思维链(CoT)行为,从而提高大语言模型的有效智能

如果使用 Claude 运行评估,可以开启“交错思考”(interleaved thinking)功能以获得类似的效果。这将有助于探查代理调用或不调用某些工具的原因,并突出工具描述和规范中需要改进的具体方面。

除了顶层准确率外,还建议收集其他指标,如单个工具调用和任务的总运行时间、总工具调用次数、总词元消耗量和工具错误。跟踪工具调用可以揭示代理常用的工作流程,并为工具的整合提供一些机会


分析结果

代理是发现问题和提供反馈的得力助手,它们能就从矛盾的工具描述到低效的工具实现和令人困惑的工具模式等一切问题提供反馈。但请记住,代理在反馈和响应中遗漏的内容往往比它们包含的内容更重要。大语言模型并不总能言如其意。

观察代理在何处遇到困难或感到困惑。通读评估代理的推理和反馈(或思维链),以找出不顺手的地方。审查原始交互记录(包括工具调用和工具响应),以捕捉代理思维链中未明确描述的任何行为。要读懂言外之意;记住,评估代理不一定知道正确的答案和策略。

分析工具调用指标。大量的冗余工具调用可能表明需要调整分页或词元限制参数;大量因参数无效导致的工具错误可能表明工具需要更清晰的描述或更好的示例。在推出 Claude 的网络搜索工具时,发现 Claude 会不必要地将“2025”附加到工具的查询参数中,这导致搜索结果出现偏差并降低了性能(通过改进工具描述引导 Claude 回到了正确的方向)。

与代理协作

甚至可以让代理来分析结果并改进工具。只需将评估代理的交互记录拼接起来,然后粘贴到 Claude Code 中。Claude 是分析交互记录和一次性重构大量工具的专家——例如,在进行新更改时,确保工具的实现和描述保持自洽。

实际上,本文中的大部分建议都来自于反复使用 Claude Code 优化内部工具实现的过程。这些评估建立在内部工作空间之上,反映了内部工作流程的复杂性,包括真实的项目、文档和消息。

通过使用独立的测试集来确保没有对“训练”用的评估集过拟合。这些测试集表明,即使是基于“专家”编写的工具实现——无论是研究员手动编写的还是由 Claude 自己生成的——也仍然可以获得额外的性能提升。

编写高效工具的原则

本节将把所学到的经验提炼为几个编写高效工具的指导原则。

为代理选择正确的工具

更多的工具并不总能带来更好的结果。一个常见的错误是,工具仅仅是对现有软件功能或 API 端点的简单包装——而不管这些工具是否适合代理。这是因为代理相对于传统软件有不同的“功能可见性”(affordances)——也就是说,它们感知其可以采取的潜在行动的方式不同。

大语言模型代理的“上下文”(即它们一次能处理的信息量)是有限的,而计算机内存则廉价且充足。考虑在地址簿中搜索联系人的任务。传统软件程序可以高效地存储和逐个处理联系人列表,检查完一个再移至下一个。

然而,如果一个大语言模型代理使用的工具返回了所有联系人,然后它必须逐个词元地阅读每个联系人,那么它就是在不相关的信息上浪费其有限的上下文空间(想象一下通过从头到尾阅读每一页来在地址簿中查找联系人——也就是通过暴力搜索)。更好、更自然的方法(对代理和人类都一样)是先跳到相关的页面(也许是按字母顺序查找)。

建议先构建少数几个经过深思熟虑的工具,针对特定的高影响力工作流程,这些工作流程应与评估任务相匹配,然后在此基础上逐步扩展。在地址簿的例子中,可以选择实现一个 search_contacts 或 message_contact 工具,而不是一个 list_contacts 工具。

工具可以整合功能,在底层处理可能多个离散的操作(或 API 调用)。例如,工具可以用相关的元数据丰富工具响应,或者在一个工具调用中处理频繁链式调用的多步任务。

以下是一些示例:

与其实现 list_users、list_events 和 create_event 工具,不如考虑实现一个 schedule_event 工具,该工具可以查找空闲时间并安排事件

与其实现一个 read_logs 工具,不如考虑实现一个 search_logs 工具,它只返回相关的日志行和一些上下文

与其实现 get_customer_by_id、list_transactions 和 list_notes 工具,不如实现一个 get_customer_context 工具,该工具一次性汇编客户所有近期和相关的信息。

确保构建的每个工具都有一个清晰、独特的目的。工具应能让代理像人类在拥有相同底层资源的情况下那样,对任务进行细分和解决,并同时减少本应被中间输出消耗的上下文。

过多的工具或功能重叠的工具也可能分散代理的注意力,使其无法采取高效的策略。谨慎、有选择地规划要构建(或不构建)的工具,可以带来巨大的回报。

为工具使用命名空间

AI 代理可能会接触到数十个 MCP 服务器和数百个不同的工具——包括其他开发者开发的工具。当工具功能重叠或目的模糊时,代理可能会混淆该使用哪个。

命名空间(将相关工具按共同的前缀分组)有助于在众多工具之间划定界限;MCP 客户端有时会默认这样做。例如,按服务(如 asana_search、jira_search)和按资源(如 asana_projects_search、asana_users_search)对工具进行命名空间划分,可以帮助代理在正确的时间选择正确的工具。

实践发现,选择基于前缀还是后缀的命名空间方案,对工具使用评估有不可忽视的影响。这种影响因大语言模型而异,建议根据自己的评估选择命名方案。

代理可能会调用错误的工具,用错误的参数调用正确的工具,调用过少的工具,或错误地处理工具响应。通过有选择地实现其名称能反映任务自然划分的工具,可以同时减少加载到代理上下文中的工具和工具描述的数量,并将代理计算从代理的上下文中转移回工具调用本身。这降低了代理犯错的总体风险。

从工具中返回有意义的上下文

同样地,工具的实现应注意只向代理返回高信息量的信号。它们应优先考虑上下文相关性而非灵活性,并避免使用低级别的技术标识符(例如:uuid、256px_image_url、mime_type)。像 name、image_url 和 file_type 这样的字段更有可能直接为代理的后续行动和响应提供信息。

代理处理自然语言名称、术语或标识符时,也比处理晦涩的标识符要成功得多。实践发现,仅仅将任意的字母数字 UUID 解析为更具语义意义和可解释性的语言(甚至是 0 索引的 ID 方案),就能通过减少幻觉显著提高 Claude 在检索任务中的精确度。

在某些情况下,代理可能需要灵活地与自然语言和技术标识符输出进行交互,哪怕只是为了触发后续的工具调用(例如,search_user(name=’jane’) → send_message(id=12345))。可以通过在工具中暴露一个简单的 response_format 枚举参数来实现这一点,让代理控制工具是返回“简洁”还是“详细”的响应。

可以添加更多格式以获得更大的灵活性,类似于 GraphQL,可以选择确切地想要接收哪些信息。以下是一个用于控制工具响应详细程度的 ResponseFormat 枚举示例:

enum ResponseFormat { DETAILED = "detailed", ConCISE = "concise" }

这是一个详细工具响应的示例(206 个词元):


这是一个简洁工具响应的示例(72 个词元):


即使是工具的响应结构——例如 XML、JSON 或 Markdown——也可能对评估性能产生影响:没有一种万能的解决方案。这是因为大语言模型是基于下一个词元预测进行训练的,它们往往在处理与其训练数据格式相匹配的格式时表现更好。最佳的响应结构会因任务和代理的不同而有很大差异。建议根据自己的评估选择最佳的响应结构。

优化工具响应的词元效率

优化上下文的质量很重要,但优化工具响应中返回给代理的上下文数量也同样重要。

建议为任何可能消耗大量上下文的工具响应,实施分页、范围选择、过滤和/或截断的组合,并设置合理的默认参数值。对于 Claude Code,工具响应默认限制在 25,000 个词元。预计代理的有效上下文长度会随着时间的推移而增长,但对上下文高效的工具的需求将持续存在。

如果选择截断响应,请务必用有用的指令来引导代理。可以直接鼓励代理采取更节省词元的策略,例如在知识检索任务中进行多次小范围、有针对性的搜索,而不是一次大范围的搜索。同样,如果工具调用引发错误(例如,在输入验证期间),可以通过提示工程优化错误响应,以清晰地传达具体且可操作的改进建议,而不是返回不透明的错误代码或追溯信息。

这是一个截断工具响应的示例:


这是一个无益的错误响应示例:


这是一个有益的错误响应示例:


通过提示工程优化工具描述

现在介绍一种最有效的工具改进方法:通过提示工程优化工具的描述和规范。因为这些内容会被加载到代理的上下文中,它们可以共同引导代理采取有效的工具调用行为。

在编写工具描述和规范时,可以想象一下如何向团队中的新成员描述这个工具。考虑那些可能隐含的背景信息——专门的查询格式、小众术语的定义、底层资源之间的关系——并将它们明确化。通过清晰地描述(并用严格的数据模型强制执行)预期的输入和输出来避免歧义。特别是,输入参数应被明确命名:与其使用名为 user 的参数,不如尝试使用名为 user_id 的参数。

通过评估,可以更有信心地衡量提示工程带来的影响。即使是对工具描述进行微小的改进,也可能带来显著的性能提升。在对工具描述进行精确优化后,Claude Sonnet 3.5 在 SWE-bench Verified 评估中取得了业界领先的性能,错误率大幅降低,任务完成率显著提高。

可以在开发者指南中找到有关工具定义的其他最佳实践。如果正在为 Claude 构建工具,也建议阅读关于工具如何动态加载到 Claude 系统提示中的内容。最后,如果正在为 MCP 服务器编写工具,工具注解有助于说明哪些工具需要访问开放世界或会进行破坏性更改。

展望未来

要为代理构建有效的工具,需要将软件开发实践从可预测的、确定性的模式转向非确定性的模式。

通过本文描述的迭代、评估驱动的流程,已经识别出成功工具的一致模式:有效的工具目标明确、定义清晰,能明智地使用代理上下文,可以组合成多样化的工作流程,并能让代理直观地解决真实世界的任务。

未来,预计代理与世界交互的具体机制将会演变——从 MCP 协议的更新到基础大语言模型本身的升级。通过系统化、评估驱动的方法来改进代理工具,可以确保随着代理能力的增强,它们使用的工具也将与之共同进化

参考:

https://www.anthropic.com/engineering/writing-tools-for-agents

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其内容真实性、完整性不作任何保证或承诺。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。