文章深入探讨了为 AI 代理开发和优化工具的实践方法。首先,强调了工具在连接确定性系统与非确定性智能体之间的关键作用,并指出需改变传统软件开发思维。接着,文章提出了一套迭代式开发流程:从快速构建工具原型、运行全面的评估体系,到与智能体(如 Claude Code)协作进行工具的自动优化。此外,文章详细阐述了编写高效工具的五大原则:选择合适的、高价值工具;通过命名空间明确工具功能边界;返回对智能体有意义的上下文信息;优化工具响应的 Token 使用效率;以及通过提示工程优化工具描述。这些实践旨在帮助智能体更智能、高效地完成现实世界任务,并强调了以评估为导向的开发方法的重要性。
src="https://api.eyabc.cn/api/picture/scenery/?k=004733e0&u=https%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2FmeG6Vo0MevhEUgK3l6DzkB5BahTeR3xl87ZNCcVH9e4t2aU8YzwFg3Eia5ia6Kp5UmIFWCE3G3HXSZDAKo1noSXA%2F0%3Fwx_fmt%3Djpeg">
前言
探讨了如何为AI代理(agents)开发高质量的工具,并通过评估和优化提升其性能。通过详细的步骤和案例,展示了如何开发和优化AI代理工具,以提高其在现实世界任务中的性能和效率。这种以评估为导向的开发方法,有助于确保工具随着代理能力的提升而不断进化。今日前端早读课文章由@Ken Aizawa分享,@飘飘编译。
译文从这开始~~
智能体的能力取决于我们提供的工具。本篇文章分享了如何编写高质量的工具和评估方法,以及如何借助 Claude 让它自己优化自己的工具,从而提升整体表现。
Model Context Protocol (MCP)可以为大语言模型智能体接入上百种工具,帮助解决各种现实任务。但问题是,如何让这些工具发挥最大的效用呢?
在这篇文章里,我们总结了在不同智能体系统中提升性能的实用技巧:
我们将首先介绍如何:
-
构建和测试工具的原型
-
借助智能体创建并运行全面的工具评估
-
与 Claude Code 等智能体协作,让工具的性能自动提升
最后,我们归纳了编写高质量工具的一些关键原则:
-
选择哪些工具该做,哪些不该做
-
通过命名空间明确工具的功能边界
-
工具要向智能体返回有意义的上下文信息
-
优化工具的响应,提高 Token 使用效率
-
在工具的描述和规格中运用提示工程
工程师如何使用 Claude Code 来评估智能体工具的效果。
通过建立评估体系,你可以系统化地衡量工具的表现,并利用 Claude Code 自动优化工具,让其更符合评估标准。
什么是工具?
在计算机领域,确定性系统在相同输入下总会产生相同的输出;而非确定性系统(例如智能体)即使在相同条件下,也可能生成不同的结果。
传统的软件开发,就是在两个确定性系统之间建立契约。例如,调用 getWeather("NYC") 这个函数,每次都会返回纽约的天气,结果完全一致。
而工具则是一种新型软件,它体现了确定性系统和非确定性智能体之间的契约。比如当用户问「今天要带伞吗?」时,智能体可能会调用天气工具,也可能凭常识作答,或者先追问用户所在位置。但有时,智能体可能会出现幻觉,甚至无法正确使用工具。
这意味着,给智能体编写工具时,我们需要彻底改变思路。我们不能像为其他开发者或系统编写工具和 MCP 服务器那样去编写,而是要为代理进行设计。
我们的目标,是通过工具让智能体能够解决更广泛的任务,并探索多样化的成功路径。幸运的是,在实践中,那些对智能体「友好」的工具,往往对人类来说也非常直观、好理解。
如何编写工具
在这一部分,我们将介绍如何与智能体协作,共同编写并改进它所使用的工具。
-
首先,快速做一个工具原型,并在本地进行测试。
-
接着,运行全面的评估,衡量工具的改进效果。
-
最后,通过与智能体的持续协作,反复进行评估和优化,直到智能体能够在真实任务中表现出色。
构建原型
在没有亲自尝试之前,很难预判哪些工具对智能体来说好用,哪些不好用。最好的办法是先快速做一个工具的原型。
如果你用 Claude Code 来写工具(甚至可能一次就能生成),最好提前提供相关的文档,比如工具会依赖的软件库、API 或 SDK(包括 MCP SDK)。对大模型友好的文档通常可以在官方文档站点的扁平化 llms.txt 文件中找到(例如我们 API 的文档)。
把工具封装在本地 MCP 服务器或桌面扩展(DXT)中,就能在 Claude Code 或 Claude Desktop 应用里直接连接和测试。
-
要把本地 MCP 服务器连接到 Claude Code,可以运行:
claude mcp add <name> <command> [args...] -
要把 MCP 服务器或 DXT 接入 Claude Desktop 应用,可以进入 Settings > Developer 或 Settings > Extensions。
-
工具也可以直接传入 Anthropic API,用于编程化测试。
你可以先自己测试工具,找出不够顺手的地方。再收集用户的反馈,逐渐形成直觉,明确你希望工具支持的使用场景和提示模式。
运行评估
接下来,你需要通过评估来衡量 Claude 使用工具的效果。第一步是生成大量贴近真实应用的评估任务。我们建议你和智能体协作,一起分析结果,找出改进方向。完整的流程可以参考我们的 工具评估手册。
工具评估手册:https://github.com/anthropics/anthropic-cookbook/blob/main/tool_evaluation/tool_evaluation.ipynb
人工编写的 Slack MCP 服务器 vs Claude 优化后的 Slack MCP 服务器的测试集准确率对比。我们内部 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) 行为,从而提升智能体的有效智力水平。
如果你在 Claude 中运行评估,可以直接开启 interleaved thinking(交错思维),就能获得类似的功能。这能帮助你分析智能体为什么会(或不会)调用某个工具,并发现工具描述和规格中的改进空间。
除了整体准确率,我们还建议收集以下指标:
-
单个工具调用和任务的总运行时间
-
工具调用的总次数
-
Token 消耗总量
-
工具报错情况
跟踪工具调用模式,可以揭示智能体常用的工作流,并帮助发现工具合并或优化的机会。
人工编写的 Asana MCP 服务器 vs Claude 优化后的 Asana MCP 服务器的测试集准确率对比。我们内部 Asana 工具的保留测试集表现
分析结果
智能体可以成为你可靠的伙伴,帮助发现问题并提供反馈,从工具描述相互矛盾、实现效率低下,到工具结构设计让人困惑。但需要注意,智能体在反馈和回答中遗漏的内容,往往比它明确说出的更重要。大模型并不总是能准确表达其真实意图。
你需要观察智能体在什么地方卡壳或困惑。仔细阅读评估智能体的推理与反馈(CoT),找出边缘问题。同时查看完整的对话记录(包括工具调用与返回结果),捕捉 CoT 里未明确提及的行为。要学会“读懂字里行间”,因为评估智能体并不一定知道正确答案或最佳策略。
还要分析工具调用的相关指标。
-
如果工具调用重复率很高,可能需要优化分页或 Token 限制参数;
-
如果频繁因参数无效而报错,说明工具需要更清晰的描述或更好的示例。
例如,当我们推出 Claude 的网页搜索工具时,发现 Claude 会无意义地在查询参数里追加“2025”,结果导致搜索结果出现偏差,性能下降。我们通过改进工具描述,才让 Claude 回到了正确的使用方式。
与智能体协作
你甚至可以让智能体帮你分析结果,并直接改进工具。只需把评估智能体的对话记录拼接后粘贴进 Claude Code。Claude 擅长分析这类对话记录,并能一次性重构多个工具,例如确保当工具更新后,其实现和描述仍保持一致。
事实上,本篇文章的大部分经验,都是我们多次借助 Claude Code 优化内部工具实现而得出的。我们的评估任务基于内部工作区,反映了内部工作流的复杂度,涵盖真实的项目、文档和消息。
为了避免“过拟合”评估,我们还保留了一部分测试集不参与训练。测试结果显示,即使在“专家”级的工具实现(无论是研究人员手写的,还是 Claude 自动生成的)基础上,我们仍然能继续挖掘额外的性能提升。
【第3280期】从 Lerna 到现代化:原生 Workspaces 和 Changesets 的高效协作
编写高效工具的原则
下面我们把经验提炼成几条指导原则,帮助你编写更有效的工具。
选择合适的工具
更多的工具,并不一定意味着更好的结果。我们常见的错误是:把现有软件功能或 API 端点简单包装成工具,而不考虑这些工具是否真的适合智能体。
因为智能体的“使用方式”不同于传统软件。举例来说:
-
计算机内存廉价而充足,传统程序可以逐个高效地检查通讯录中的联系人。
-
智能体的上下文有限,如果工具一次性返回所有联系人,让智能体逐个阅读(相当于逐页翻阅通讯录),就会浪费大量上下文空间。
更自然、更高效的做法是:先跳到相关页(比如按字母顺序定位)。
因此,我们推荐从少量精心设计的高价值工具开始,这些工具要能匹配你的评估任务,再逐步扩展。例如:
-
在通讯录场景下,比起
list_contacts,更合适的是实现search_contacts或message_contact。
工具还可以整合功能,把多个步骤隐藏在一个调用里。例如,工具可以丰富工具响应的相关元数据,或者在单个工具调用中处理经常串联的多步骤任务。
-
与其分别实现一个
list_users、list_events、create_event,不如实现schedule_event,直接查找空闲时间并安排会议。 -
与其实现一个
read_logs,不如实现一个实现search_logs,仅返回相关日志行及上下文。 -
与其实现一个
get_customer_by_id、list_transactions、list_notes,不然实现get_customer_context,一次性汇总客户的近期关键信息。
要确保构建的每个工具要有清晰、独立的用途。工具应当帮助智能体像人类一样拆解和完成任务,同时减少中间输出对上下文的消耗。
工具太多或功能重叠,会分散智能体注意力,让它更难找到高效策略。经过精挑细选的工具组合,往往效果更好。
给工具命名空间
智能体可能会接入几十个 MCP 服务器、上百个不同工具,其中还有其他开发者编写的。如果工具功能重叠,或用途模糊,智能体就可能混淆选择。
命名空间(把相关工具用统一前缀分组)能有效划清边界。有些 MCP 客户端会默认这样做。例如:
-
按服务命名:
asana_search、jira_search -
按资源命名:
asana_projects_search、asana_users_search
我们发现,前缀式命名与后缀式命名,在工具使用评估中有显著差异,效果因模型而异。因此建议你根据自己的评估结果选择合适的命名规则。
智能体可能会:
-
调用错误的工具
-
用错误参数调用正确的工具
-
调用次数太少
-
或错误地处理工具响应
通过谨慎设计工具,并让名字反映任务的自然分工,不仅能减少加载到上下文中的工具数量和描述,还能把一部分推理计算转移到工具调用中,降低出错风险。
返回有意义的上下文
工具实现时,应该优先返回高价值信息,而不是泛泛的内容。要突出上下文相关性,而不是追求灵活性。
避免输出低层级的技术标识(如:uuid、256px_image_url、mime_type),而应该提供更直观的字段(如:name、image_url、file_type),这样更容易被智能体用于后续决策和响应。
实践表明,智能体在处理自然语言的名称、术语或标识时,远比处理复杂的符号 ID 更可靠。比如,把一串 UUID 转换成可读的名称,甚至简单的数字索引,都能显著减少幻觉现象,提高 Claude 在检索任务中的精度。
当然,有些场景下,智能体需要同时使用自然语言标识和技术 ID(例如 search_user(name="jane") → send_message(id=12345))。你可以在工具里设计一个 response_format 枚举参数,让智能体自行选择返回“简洁”或“详细”模式(类似 GraphQL 按需选择字段)。
这样不仅能兼顾灵活性,还能更好地满足不同上下文的需要。
响应格式枚举示例
enum ResponseFormat { DETAILED = "detailed", CONCISE = "concise"}
详细响应(206 tokens 示例):

简洁响应(72 tokens 示例):

在 Slack 中,主题帖与回复由唯一的 thread_ts 标识,要获取回复必须依赖它。类似的 ID(如 channel_id、user_id)可以通过“详细”响应返回,用于后续工具调用;而“简洁”响应则只返回内容,不含这些 ID。在这个例子里,使用简洁模式只消耗约三分之一的 Token。
即使是工具响应的结构(XML、JSON、Markdown 等),也会影响评估表现,因为大模型是基于下一个 Token 的预测来训练的。某些格式可能更符合训练分布,从而表现更好。最佳结构会因任务和智能体而异,建议根据自己的评估结果来选择。
优化工具响应的 Token 效率
除了优化信息的质量,还要优化返回上下文的数量。
建议在可能占用大量上下文的工具响应中,结合使用 分页、范围选择、过滤或截断,并设置合理的默认参数。Claude Code 默认将工具响应限制在 25,000 tokens。虽然未来智能体的上下文长度会不断增长,但对“上下文高效”的工具需求将一直存在。
如果选择截断响应,一定要配合明确的提示来引导智能体。例如:
-
鼓励智能体通过多次小范围、精确的查询来完成任务,而不是一次性进行宽泛的大查询。
-
当工具调用报错(比如输入校验失败),要通过提示工程把错误响应设计得清晰、可操作,而不是返回含糊的错误码或追踪栈。
截断响应示例:

无帮助的错误响应示例:

有帮助的错误响应示例:

通过合理的截断和错误信息,工具可以引导智能体养成更高效的调用方式(如使用过滤或分页),并提供正确输入格式的示例。
提示工程:优化工具描述
提升工具效果的关键方法之一,就是对工具描述和规格进行提示工程。因为这些内容会加载进智能体的上下文,它们能直接影响智能体的调用行为。
写工具描述时,可以想象你在向一位新同事介绍工具:
-
把你平时隐含的上下文说清楚,比如特殊的查询格式、专业术语的定义、底层资源的关系。
-
避免含糊,明确规定输入与输出,并通过严格的数据模型加以约束。
-
输入参数命名要清晰:不要用
user,而要用user_id。
通过评估,你可以量化提示工程带来的影响。哪怕是细微的优化,都可能带来巨大改进。例如,我们在优化工具描述后,让 Claude Sonnet 3.5 在 SWE-bench Verified 评测中达到了最新的 SOTA 水平,大幅降低了错误率并提升了任务完成率。
更多工具定义的最佳实践,可以在我们的 开发者指南 中找到。如果你在为 Claude 构建工具,建议阅读关于工具如何动态加载到 Claude 系统提示中的部分。如果你在写 MCP 服务器的工具,可以利用工具注解(annotations)来说明哪些工具需要开放访问,或会进行破坏性操作。
展望未来
要为智能体构建高效工具,我们需要把软件开发实践从可预测的确定性模式,转变为面向非确定性的模式。
通过本文介绍的迭代、评估驱动的流程,我们发现优秀的工具通常具备以下特征:
-
设计有意图且定义清晰
-
合理利用智能体的上下文
-
能在多样化的工作流中组合使用
-
让智能体直观地完成真实任务
未来,智能体与世界交互的方式还会不断演化:MCP 协议会更新,底层大模型也会升级。通过系统化、以评估为导向的改进方法,我们能确保工具与智能体能力的提升同步发展。
关于本文译者:@飘飘作者:@Ken Aizawa原文:https://www.anthropic.com/engineering/writing-tools-for-agents
