type
status
date
slug
summary
tags
category
icon
password
AI智能体的效能依赖于高质量工具的开发和评估。通过构建原型、运行评估和与代理协作,可以优化工具性能。关键原则包括选择合适的工具、明确功能边界、返回有意义的上下文、优化响应效率以及进行提示工程优化。有效的工具应具备明确目的,并能直观地帮助智能体解决实际任务。
AI 智能体的效能取决于我们提供给它们的工具。我们分享如何编写高质量的工具和评估方法,以及如何通过使用 Claude 来优化其自身工具,从而提升性能。
模型上下文协议 (MCP) 可以为 LLM 代理配备数百种工具来解决实际任务。但我们如何使这些工具发挥最大效用?
在本文中,我们描述了在各种代理式 AI 系统中提高性能的最有效技术 1。
我们首先介绍如何:
- 构建和测试您的工具原型
- 使用代理创建并运行对工具的全面评估
- 与 Claude Code 等代理协作,自动提升工具的性能
最后,我们总结了我们在此过程中发现的编写高质量工具的关键原则:
- 选择要实现(和不实现)的正确工具
- 为工具定义命名空间以明确功能边界
- 从工具向代理返回有意义的上下文
- 优化工具响应以提高tokens效率
- 对工具描述和规格进行提示工程优化
构建评估体系可以让你系统地衡量工具的性能。你可以使用 Claude Code 根据这个评估自动优化你的工具。

什么是工具?
在计算领域,确定性系统在给定相同输入的情况下每次都会产生相同的输出,而非确定性系统——如智能体——即使在相同的起始条件下也可能产生不同的响应。
当我们传统地编写软件时,我们是在确定性系统之间建立一种契约。例如,像
getWeather("NYC") 这样的函数调用,每次调用时都会以完全相同的方式获取纽约市的天气。工具是一种新型软件,它反映了确定性系统与非确定性智能体之间的契约。当用户问"我今天应该带伞吗?"时,智能体可能会调用天气工具,从一般知识中回答,甚至先询问一个关于位置的澄清问题。偶尔,智能体可能会产生幻觉,甚至无法掌握如何使用工具。
这意味着在为智能体编写软件时,我们需要从根本上重新思考我们的方法:我们不应该像为其他开发者或系统编写函数和 API 那样来编写工具和 MCP 服务器 ,而是需要为智能体设计它们。
我们的目标是通过使用工具来追求各种成功的策略,从而扩大智能体在解决广泛任务方面的有效范围。幸运的是,根据我们的经验,那些对智能体来说最"符合人体工程学"的工具,最终对人类来说也出奇地直观易懂。
如何编写工具
在本节中,我们描述了如何与代理协作来编写和改进您提供给他们的工具。首先,快速构建您的工具原型并在本地进行测试。接下来,运行全面评估以衡量后续的更改。通过与代理一起工作,您可以重复评估和改进工具的过程,直到您的代理在现实世界任务中取得强大的性能。
构建原型
如果不亲自实践,很难预测哪些工具会让代理觉得舒适易用,哪些不会。首先快速搭建你的工具原型。如果你使用 Claude Code 来编写工具(可能是一次性完成),给 Claude 提供你的工具所依赖的任何软件库、API 或 SDK(包括可能的 MCP SDK)的文档会很有帮助。LLM 友好的文档通常可以在官方文档网站的平面
llms.txt 文件中找到(这是我们 API 的文档)。将您的工具包装在本地 MCP 服务器或桌面扩展 (DXT)中,将使您能够在 Claude Code 或 Claude 桌面应用中连接和测试您的工具。
要将本地 MCP 服务器连接到 Claude Code,请运行
claude mcp add <name> <command> [args...] 。要将本地 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 以编程方式运行评估。使用简单的代理循环(
while-循环包裹交替的 LLM API 和工具调用):每个评估任务一个循环。每个评估代理应被赋予单一任务提示和您的工具。在评估代理的系统提示中,我们建议指示代理不仅输出结构化响应块(用于验证),还要输出推理和反馈块。指示代理在工具调用和响应块之前输出这些内容,可能会通过触发思维链(CoT)行为来提高 LLM 的有效智能。
如果您使用 Claude 运行评估,可以开启交错思考功能以获得类似的"现成"功能。这将帮助您探究代理为何调用或不调用某些工具,并突出工具描述和规范中需要改进的具体领域。
除了顶层准确率外,我们建议收集其他指标,如单个工具调用和任务的总运行时间、工具调用总次数、总tokens消耗量以及工具错误。跟踪工具调用可以帮助揭示代理追求的常见工作流程,并为工具整合提供一些机会。
我们内部 Asana 工具的留出测试集性能

分析结果
智能体是你有用的合作伙伴,能帮助你发现问题并提供反馈,从矛盾的工具描述到低效的工具实现和令人困惑的工具架构。然而,请记住,智能体在反馈和回应中省略的内容往往比他们包含的内容更重要。LLMs 并不总是言为心声 。
观察你的智能体在哪里遇到困难或感到困惑。仔细阅读评估智能体的推理和反馈(或思维链)以识别问题所在。查看原始记录(包括工具调用和工具响应)以捕捉任何未在智能体思维链中明确描述的行为。读懂言外之意;请记住,你的评估智能体不一定知道正确的答案和策略。
分析你的工具调用指标。大量冗余的工具调用可能表明需要对分页或tokens限制参数进行适当调整;大量因无效参数导致的工具错误可能表明工具需要更清晰的描述或更好的示例。当我们推出 Claude 的网络搜索工具时,我们发现 Claude 不必要地在工具的
query 参数中附加了 2025,这影响了搜索结果并降低了性能(我们通过改进工具描述引导 Claude 朝正确方向发展)。与代理协作
你甚至可以让代理分析你的结果并为你改进工具。只需将评估代理的转录内容连接起来,然后粘贴到 Claude Code 中。Claude 擅长分析转录内容并一次性重构大量工具——例如,确保在进行新更改时工具实现和描述保持自洽。
事实上,本文中的大部分建议都来自于我们通过 Claude Code 反复优化内部工具实现的过程。我们的评估是在我们的内部工作空间之上创建的,反映了我们内部工作流程的复杂性,包括真实的项目、文档和消息。
我们依赖保留的测试集来确保我们没有过度拟合到我们的"训练"评估中。这些测试集表明,即使在我们使用"专家"工具实现所达到的性能之外,我们仍能提取额外的性能改进——无论这些工具是由我们的研究人员手动编写的,还是由 Claude 本身生成的。
在下一节中,我们将分享我们从这一过程中学到的一些经验。
编写有效工具的原则
在本节中,我们将我们的经验提炼为编写有效工具的几项指导原则。
为代理选择合适的工具
工具越多并不总是带来更好的结果。我们观察到的一个常见错误是,工具仅仅包装了现有的软件功能或 API 端点——而不管这些工具是否适合代理使用。这是因为代理与传统软件有着不同的"可用性"——也就是说,它们感知这些工具可能采取的行动的方式是不同的
LLM 代理的"上下文"有限(即它们一次能处理的信息量有限),而计算机内存则便宜且丰富。考虑在地址簿中搜索联系人的任务。传统软件程序可以高效地存储和处理联系人列表,一次处理一个,在移动到下一个之前检查每一个。
然而,如果一个 LLM 代理使用返回所有联系人的工具,然后必须逐个tokens地阅读每个联系人,它就是在将有限的上下文空间浪费在无关信息上(想象一下通过从上到下阅读每一页来在地址簿中搜索联系人——即通过暴力搜索)。更好、更自然的方法(对代理和人类都适用)是首先跳到相关页面(也许按字母顺序找到它)。
我们建议构建几个针对特定高影响力工作流程的精心设计的工具,这些工具应与您的评估任务相匹配,并在此基础上进行扩展。在通讯录案例中,您可能会选择实现
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)对工具进行命名空间划分,可以帮助代理在适当的时间选择正确的工具。我们发现选择基于前缀还是后缀的命名空间对我们的工具使用评估有显著影响。这种影响因 LLM 而异,我们鼓励您根据自己的评估结果选择命名方案。
代理可能会调用错误的工具,使用错误的参数调用正确的工具,调用工具数量过少,或错误处理工具响应。通过有选择地实现那些名称反映任务自然细分部分的工具,你可以同时减少加载到代理上下文中的工具和工具描述数量,并将代理计算从代理上下文转移回工具调用本身。这降低了代理整体犯错的风险。
从工具返回有意义的上下文
同样地,工具实现应当注意只向代理返回高价值信息。它们应优先考虑上下文相关性而非灵活性,并避免使用低级技术标识符(例如:
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 枚举参数来实现这一点,允许您的代理控制工具是返回 “concise” 还是 “detailed” 响应(下图)。您可以添加更多格式以获得更大的灵活性,类似于 GraphQL,您可以在其中精确选择想要接收的信息片段。以下是一个用于控制工具响应详细程度的 ResponseFormat 枚举示例:
复制
以下是一个详细工具响应的示例(206个标记):

这是一个简洁工具响应的示例(72个标记):
Slack 线程和线程回复由唯一的
thread_ts 标识,这是获取线程回复所必需的。thread_ts 和其他 ID(channel_id、user_id)可以从 “detailed” 工具响应中检索,以启用需要这些 ID 的进一步工具调用。“concise” 工具响应仅返回线程内容,不包含 ID。在此示例中,我们使用 “concise” 工具响应时仅消耗了约 ⅓ 的tokens。
即使是你的工具响应结构——例如 XML、JSON 或 Markdown——也会影响评估性能:没有一刀切的解决方案。这是因为 LLMs 是基于下一tokens预测进行训练的,并且在与训练数据相匹配的格式下表现更好。最佳响应结构会因任务和代理而有很大差异。我们鼓励你根据自己的评估选择最佳的响应结构。
优化工具响应以提高tokens效率
优化上下文的质量很重要。但优化在工具响应中返回给代理的上下文数量也同样重要。
我们建议对于任何可能占用大量上下文的工具响应,都应实现分页、范围选择、过滤和/或截断的某种组合,并设置合理的默认参数值。对于 Claude Code,我们默认将工具响应限制在 25,000 个tokens。我们预计代理的有效上下文长度会随时间增长,但对上下文高效工具的需求将一直存在。
如果你选择截断响应,一定要通过有用的指令来引导代理。你可以直接鼓励代理采用更节省tokens的策略,例如在知识检索任务中,进行多次小而精确的搜索,而不是一次广泛的搜索。同样,如果工具调用引发错误(例如在输入验证期间),你可以通过提示工程来设计错误响应,以清晰地传达具体且可操作的改进建议,而不是提供晦涩的错误代码或跟踪信息。
这是一个被截断的工具响应示例:

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

这是一个有帮助的错误响应示例:
工具截断和错误响应可以引导代理采用更节省tokens的工具使用行为(使用过滤器或分页),或者提供正确格式工具输入的示例。

优化你的工具描述提示
现在我们来介绍改进工具的最有效方法之一:对你的工具描述和规格进行提示工程。因为这些内容会被加载到你的智能体上下文中,它们可以共同引导智能体实现有效的工具调用行为。
在编写工具描述和规范时,想象你会如何向团队中的新成员描述你的工具。考虑你可能隐含带来的上下文——专门的查询格式、专业术语的定义、底层资源之间的关系——并将其明确化。通过清晰描述(并通过严格的数据模型强制执行)预期的输入和输出来避免歧义。特别是,输入参数的命名应该明确无误:不要使用名为
user 的参数,而应尝试使用名为 user_id 的参数。通过评估,您可以更有信心地衡量提示工程的效果。即使是对工具描述的小幅优化也能带来显著改善。在我们对工具描述进行精确优化后,Claude Sonnet 3.5 在 SWE-bench Verified 评估中实现了最先进的性能,大幅降低了错误率并提高了任务完成度。
您可以在我们的开发者指南中找到有关工具定义的其他最佳实践。如果您正在为 Claude 构建工具,我们还建议您阅读有关工具如何动态加载到 Claude 的系统提示中的内容。最后,如果您正在为 MCP 服务器编写工具, 工具注释有助于揭示哪些工具需要开放世界访问权限或会进行破坏性更改。
展望未来
要为智能体构建有效的工具,我们需要将软件开发实践从可预测的确定性模式重新调整为非确定性模式。
通过本文中描述的迭代、评估驱动的过程,我们已经识别出使工具成功的一致模式:有效的工具是有意且明确定义的,审慎地使用智能体上下文,可以在多样化的工作流程中组合使用,并使智能体能够直观地解决现实世界的任务。
未来,我们期望代理与世界互动的具体机制将不断发展——从 MCP 协议的更新到底层 LLMs 本身的升级。通过采用系统化、评估驱动的方法来改进代理的工具,我们可以确保随着代理变得更加强大,它们使用的工具也将随之发展。
本文翻译自Langchain官方的《how-to-turn-claude-code-into-a-domain-specific-coding-agent》原文作者:Ken Aizawa
- 作者:SupraYou
- 链接:http://blog.suprayou.com/%E5%89%8D%E6%B2%BF%E6%8A%80%E6%9C%AF/writing-tools-for-agents
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
