摘要:Claude 最近的新功能可以直接创建和编辑包括 Excel、文档、PPT 乃至 PDF 在内的多种主流办公文件,进一步拓展了 AI 在实际任务中的应用场景。Anthropic 很早就推出过很多小而美但切中用户需求的客户端工具例如artifact,其目标始终是
Claude 最近的新功能可以直接创建和编辑包括 Excel、文档、PPT 乃至 PDF 在内的多种主流办公文件,进一步拓展了 AI 在实际任务中的应用场景。Anthropic 很早就推出过很多小而美但切中用户需求的客户端工具例如artifact,其目标始终是将 AI 从“聊天机器人”转变为能解决实际问题的强大伙伴。
最近 Anthropic 撰写了一篇文章,分享了其在开发和优化智能体工具方面的经验与方法论。
转变思维:为 AI 智能体设计,而非为代码封装
核心是为不确定的、会推理的 AI 设计直观易用的工具,而不是像传统编程那样只考虑输入输出。
评估驱动:用真实且复杂的任务来衡量和迭代
工具好不好,要靠系统性的评估来验证。评估场景必须接近真实世界,足够复杂,才能发现真正的问题。
少即是多:构建整合工作流的工具,而非零散的功能点
与其提供一堆零散的 API 功能,不如创建一个能处理多步骤任务的强大工具,这能极大减轻 AI 的推理负担。
工具的名称、描述和参数定义是 AI 理解其用途的唯一途径。清晰、准确的描述是提升工具调用成功率最有效的方法之一。
智能体的效能取决于我们为其提供的工具。我们将分享如何编写高质量的工具和评估,以及您如何可以利用 Claude 来为自己优化工具,从而提升性能。
模型上下文协议 (MCP) 可以为大语言模型 (LLM) 智能体提供数百种工具,以解决现实世界的任务。但我们如何使这些工具的效能最大化呢?
在这篇文章中,我们描述了在多种智能 AI 系统中提升性能最有效的技术。
我们首先会介绍您如何能够:
构建并测试您的工具原型
创建并运行针对智能体工具的全面评估
与像 Claude Code 这样的智能体协作,自动提升您工具的性能
最后,我们总结了在此过程中识别出的编写高质量工具的关键原则:
选择合适的工具进行实现(以及不实现)
通过命名空间为工具定义清晰的功能边界
从工具向智能体返回有意义的上下文
为提升 Token 效率而优化工具响应
对工具描述和规范进行提示工程
通过构建评估,您可以系统地衡量工具的性能。您可以使用 Claude Code 自动根据此评估来优化您的工具。
在计算领域,确定性系统在给定相同输入时 每次都会产生相同的输出,而 非确定性 系统——例如智能体——即使在起始条件 相同的情况下也可能生成不同的响应。
当我们传统地编写软件时,我们是在确定性系统之间建立一种契约。例如,一个像 getWeather(“NYC”) 这样的函数调用,每次被调用时都会以完全相同的方式获取纽约市的天气。工具是一种新型软件,它反映了确定性系统与非确定性智能体之间的契约。当用户问“我今天应该带伞吗?”,智能体可能会调用天气工具,根据常识回答,甚至可能先问一个关于地点的澄清问题。偶尔,智能体可能会产生幻觉,甚至无法理解如何使用某个工具。
这意味着在为智能体编写软件时,我们需要从根本上重新思考我们的方法:我们不应像为其他开发者或系统编写函数和 API 那样编写工具和 MCP 服务器 , 而需要为智能体量身设计它们。
我们的目标是通过使用工具来追求多种成功的策略,从而扩大智能体在解决广泛任务方面的有效范围。幸运的是,根据我们的经验,对智能体来说最“顺手”的工具,最终对人类而言也出人意料地直观易懂。
02 如何编写工具在本节中,我们描述了您如何可以与智能体协作,既编写工具又改进您提供给它们的工具。首先,快速搭建一个工具原型并在本地进行测试。接下来,运行一次全面的评估以衡量后续的变更。与智能体并肩工作,您可以重复评估和改进工具的过程,直到您的智能体在真实世界任务中取得优异的性能。
构建原型 如果不亲自动手,很难预料哪些工具智能体会觉得顺手,哪些不会。首先,快速搭建一个工具原型。如果您 正在使用 Claude Code 来编写工具(可能是一次性完成),为 Claude 提供您的工具将依赖的任何软件库、API 或 SDK(可能包括 MCP SDK )的文档会很有帮助。大语言模型友好的文档通常可以在官方文档网站的纯文本 llms.txt 文件中找到(这是我们的 API 的文档)。将您的工具包装在 本地 MCP 服务器 或 桌面扩展 (DXT) 中,将允许您在 Claude Code 或 Claude 桌面应用中连接并测试您的工具。
要将您的本地 MCP 服务器连接到 Claude Code,运行 claude mcp add 。
要将您的本地 MCP 服务器或 DXT 连接到 Claude 桌面应用,请分别导航至 设置 > 开发者 或 设置 > 扩展 。
工具也可以直接传 入 Anthropic API 调用中 进行程序化测试。
亲自测试这些工具,以发现任何不顺手的地方。从您的用户那里收集反馈,以便对您期望工具所能支持的用例和提示建立直观的理解。
运行评估接下来,您需要通过运行评估来衡量 Claude 使用您工具的效果。首先,生成大量基于现实世界用途的评估任务。我们建议与智能体合作,帮助分析您的结果并确定如何改进您的工具。您可以在我们的 工具评估手册 中 看到这一过程的端到端演示。
我们内部 Slack 工具在留出测试集上的性能
生成评估任务借助您的早期原型,Claude Code 可以快速探索您的工具并创建数十个提示和响应对。提示应受现实世界用途的启发,并基于现实的数据源和服务(例如,内部知识库和微服务)。我们建议您避免过于简单或肤浅的“沙盒”环境,因为这些环境无法以足够的复杂度对您的工具进行压力测试。优秀的评估任务可能需要多次工具调用——甚至可能多达数十次。
以下是一些优秀任务的例子:
安排下周与 Jane 开会,讨论我们最新的 Acme Corp 项目。附上我们上次项目规划会议的纪要,并预订一间会议室。
客户 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 运行评估,您可以开启 交错思考 功 能,以“开箱即用”地获得类似的功能。这将帮助您探究智能体为何调用或不调用某些工具,并突显工具描述和规范中需要改进的具体方面。
除了顶层准确率,我们还建议收集其他指标,如单个工具调用和任务的总运行时间、工具调用的总次数、总 Token 消耗量以及工具错误。跟踪工具调用可以帮助揭示智能体追求的常见工作流程,并为工具的整合提供一些机会。
我们内部 Asana 工具在留出测试集上的性能
分析结果智能体是您有用的伙伴,可以帮助发现问题并提供反馈,从相互矛盾的工具描述到低效的工 具实现和令人困惑的工具模式,无所不包。然而,请记住,智能体在其反馈和响应中 省略 的内容往往比它们 包含 的内容更重要。大语言模型并不总是 言如其意 。
观察您的智能体在何处遇到困难或感到困惑。通读您评估智能体的推理和反馈(或 CoT),以识别不顺手之处。审查原始的交互记录(包括工具调用和工具响应),以捕捉智能体 CoT 中未明确描述的任何行为。要读懂言外之意;请记住,您的评估智能体不一定知道正确的答案和策略。
分析您的工具调用指标。大量的冗余工具调用可能表明需要对分页或 Token 限制参数进行适当调整;大量因无效参数导致的工具错误可能表明工具需要更清晰的描述或更好的示例。当我们推出 Claude 的 网络搜索工具 时, 我们发现 Claude 会不必要地将 2025 query 参数上,这会使搜索结果产生偏差并降低性能(我们通过改进工具描述将 Claude 引导到了正确的方向)。与智能体协作您甚至可以让智能体为您分析结果并改进您的工具。只需将您评估智能体的交互记录连接起来,然后粘贴到 Claude Code 中。Claude 是分析交互记录和一次性重构大量工具的专家——例如,确保在进行新更改时,工具的实现和描述保持自洽。
事实上,本文中的大部分建议都来自于与 Claude Code 反复优化我们内部工具实现的过程。我们的评估是在我们内部工作空间之上创建的,反映了我们内部工作流程的复杂性,包括真实的项目、文档和消息。
我们依靠留出测试集来确保我们不会对我们的“训练”评估过拟合。这些测试集显示,即使是相比于“专家”实现的工具——无论是我们的研究人员手动编写的还是由 Claude 自己生成的——我们也能获得额外的性能提升。
在下一节中,我们将分享我们从这个过程中学到的一些经验。
03 编写高效工具的原则在本节中,我们将我们的学习经验提炼为几个编写高效工具的指导原则。
为智能体选择合适的工具更多的工具并不总能带来更好的结果。我们观察到的一个常见错误是,有些工具仅仅是对现有软件功能或 API 端点的简单封装——无论这些工具是否适合智能体。这是因为智能体相对于传统软件有其独特的“可供性”——也就是说,它们感知可以利用这些工具采取的潜在行动的方式是不同的。
大语言模型智能体的“上下文”是有限的(即它们一次能处理的信息量有限),而计算机内存则廉价且丰富。考虑在一个地址簿中搜索联系人的任务。传统软件程序可以高效地存储和逐一处理联系人列表,检查完一个再移至下一个。
然而,如果一个大语言模型智能体使用一个返回 所有 联系人的工具,然后必须逐个 Token 地阅读每个联系人,它就在不相关的信息上浪费了其有限的上下文空间(想象一下通过从头到尾阅读每一页来在地址簿中查找联系人——即通过暴力搜索)。更好、更自然的方法(对智能体和人类都适用)是首先跳到相关的页面(也许是按字母顺序查找)。
我们建议构建少数几个精心设计的工具,针对特定的高影响力工作流程,这些工作流程与您的评估任务相匹配,并以此为基础进行扩展。在地址簿的例子中,您可能会选择实现一个 Contactss 或 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 ,)和按资源(如, asana_users_search )对工具进行命名空间划分,可以帮助智能体在正确的时间选择正确的工具。我们发现,选择基于前缀还是后缀的命名空间方案,对我们的工具使用评估有不小的影响。具体效果因大语言模型而异,我们鼓励您根据自己的评估选择命名方案。
智能体可能会调用错误的工具,用错误的参数调用正确的工具,调用太少的工具,或错误地处理工具响应。通过有选择地实现那些名称反映了任务自然划分的工具,您可以同时减少加载到智能体上下文中的工具和工具描述的数量,并将智能体计算从其上下文中卸载回工具调用本身。这降低了智能体犯错的总体风险。
从您的工具返回有意义的上下文 同样地,工具的实现应注意只向智能体返回高信息量的信号。它们应优先考虑上下文相关性而非灵活性,并避免使用低级别的技术标识符(例如:,, mime_type )。像,, 和这样的字段更有可能直接为智能体的下游行动和响应提供信息。智能体处理自然语言名称、术语或标识符的成功率也远高于处理神秘标识符。我们发现,仅仅将任意的字母数字 UUID 解析为更具语义意义和可解释性的语言(甚至是 0 索引的 ID 方案),就能通过减少幻觉显著提高 Claude 在检索任务中的精确度。
在某些情况下,智能体可能需要灵活地与自然语言和技术标识符输出进行交互,哪怕只是为了触发下游的工具调用,例如
send_message(id=12345)您可以通过在工具中暴露一个简单的 response_format 枚举参数来同时启用这两种方式,让您的智能体控制工具是返回“简洁”还是“详细”的响应(如下图所示)。
您可以添加更多格式以获得更大的灵活性,类似于 GraphQL,您可以精确选择想要接收哪些信息。这是一个控制工具响应详细程度的 ResponseFormat 枚举示例:
enum ResponseFormat {
DETAILED = "detailed",
CONCISE = "concise"
}
复制
这是一个详细工具响应的例子(206 个 Token):
这是一个简洁工具响应的例子(72 个 Token):
甚至您的工具响应结构——例如 XML、JSON 或 Markdown——也会对评估性能产生影响:没有一种万能的解决方案。这是因为大语言模型是基于下一个 Token 预测进行训练的,它们往往在处理与其训练数据格式相匹配的格式时表现更好。最佳的响应结构会因任务和智能体的不同而大相径庭。我们鼓励您根据自己的评估选择最佳的响应结构。
为提升 Token 效率优化工具响应我们建议对任何可能占用大量上下文的工具响应,实施分页、范围选择、过滤和/或截断的某种组合,并设置合理的默认参数值。对于 Claude Code,我们默认将工具响应限制在 25,000 个 Token。我们预计智能体的有效上下文长度会随着时间增长,但对上下文高效工具的需求将持续存在。
如果您选择截断响应,请务必用有帮助的指令来引导智能体。您可以直接鼓励智能体采取更节省 Token 的策略,比如在一个知识检索任务中进行多次小范围、有针对性的搜索,而不是一次宽泛的搜索。同样,如果一个工具调用引发错误(例如,在输入验证期间),您可以通过提示工程设计您的错误响应,以清晰地传达具体且可操作的改进建议,而不是模糊的错误代码或回溯信息。
这是一个截断工具响应的例子:
这是一个无帮助的错误响应例子:
这是一个有帮助的死错误响应例子:
工具的截断和错误响应可以引导智能体采取更节省 Token 的工具使用行为(使用过滤器或分页),或提供格式正确的工具输入示例。
对您的工具描述进行提示工程现在我们来看一种最有效的改进工具的方法:对您的工具描述和规范进行提示工程。因为这些内容会被加载到智能体的上下文中,它们可以共同引导智能体采取有效的工具调用行为。
在编写工具描述和规范时,可以想象您正在向团队中的新成员描述您的工具。考虑您可能会默认带来的一些上下文——专门的查询格式、小众术语的定义、底层资源之间的关系——并将其明确化。通过清晰地描述(并用严格的数据模型强制执行)预期的输入和输出来避免歧义。特别是,输入参数应该被明确命名:不要用一个名为 user 的参数,而是尝试用一个名为的参数。通过您的 评估,您可以更有信心地衡量提示工程的影响。即使是对工具描述的微小改进也能带来显著的性能提升。在我们对工具描述进行精确改进后,Claude Sonnet 3.5 在 SWE-bench Verified 评估中取得了最先进的性能,大幅降低了错误率并提高了任务完成率。
您可以在我们的 开发者指南 中找到其他关于工具定义的最佳实践。如果您正在为 Claude 构建工具,我们还建议您阅读有关工具是如何被动态加载到 Claude 的 系统提示 中的内容。最后,如果您正在为 MCP 服务器编写工具, 工具注解 有助于揭示哪些工具需要访问开放世界或会进行破坏性更改。
04 展望未来要为智能体构建有效的工具,我们需要将我们的软件开发实践从可预测的、确定性的模式转向非确定性的模式。
通过本文中描述的迭代式、评估驱动的过程,我们已经识别出工具成功的普遍模式:有效的工具被刻意地、清晰地定义,审慎地使用智能体上下文,可以被组合在多样化的工作流程中,并使智能体能够直观地解决现实世界的任务。
在未来,我们预计智能体与世界互动的具体机制将会演变——从 MCP 协议的更新到基础大语言模型本身的升级。通过一种系统性的、评估驱动的方法来为智能体改进工具,我们可以确保随着智能体变得越来越强大,它们使用的工具也将与它们一同进化。
来源:晚晚的星河日记一点号