智能体的效能取决于我们为其配备的工具。本文将分享如何编写高质量的工具与评估方案,以及如何借助 Claude 优化工具,进而提升智能体性能。

来源: https://www.anthropic.com/engineering Anthropic 工程团队出品

模型上下文协议(Model Context Protocol,简称 MCP)能为大语言模型(LLM)智能体提供多达数百种工具,助力其解决现实世界中的任务。但如何让这些工具发挥最大效用呢?

在本文中,我们将介绍在各类智能体人工智能系统中提升性能的有效技术 。首先,我们会涵盖以下内容:
  • 构建并测试工具原型
  • 借助智能体创建并执行全面的工具评估
  • 与 Claude Code 等智能体协作,自动提升工具性能
最后,我们会总结在实践过程中总结出的编写高质量工具的核心原则:
  • 选择应实现(及不应实现)的工具
  • 对工具进行命名空间划分,明确功能边界
  • 工具向智能体返回有意义的上下文信息
  • 优化工具响应,提升令牌(token)使用效率
  • 对工具描述与规格进行提示工程(Prompt-Engineering)

 

1 什么是工具?

在计算机领域,确定性系统在输入相同的情况下,每次输出结果都完全一致;而像智能体这样的非确定性系统,即便初始条件相同,也可能产生不同的响应。
传统软件开发中,我们实则是在确定性系统之间建立一种 “契约”。例如,调用 getWeather("NYC") 函数时,每次都会以完全相同的方式获取纽约市的天气数据。
工具是一种新型软件,它反映的是确定性系统与非确定性智能体之间的 “契约”。当用户问 “今天我需要带伞吗?” 时,智能体可能会调用天气工具,也可能凭借已有常识回答,甚至会先追问用户所在位置。有时,智能体还可能出现 “幻觉”(输出与事实不符的内容),甚至无法理解如何使用工具。
这意味着,为智能体编写软件时,我们需要从根本上转变思路:不能再像为其他开发者或系统编写函数与 API 那样设计工具和 MCP 服务器,而要以智能体的需求为核心进行设计。
我们的目标是,通过工具让智能体能够采用多种有效策略,扩大其在解决各类任务时的有效作用范围。幸运的是,根据我们的经验,对智能体而言 “易用” 的工具,对人类来说往往也同样直观易懂。

2 如何编写工具

在本节中,我们将介绍如何与智能体协作,完成工具的编写与优化。首先,快速搭建工具原型并在本地测试;接着,开展全面评估以衡量后续改进效果;最后,与智能体配合,反复进行评估与优化,直到智能体在现实任务中达到出色性能。

 

2.1 搭建原型

若不亲自动手尝试,很难预判哪些工具对智能体而言 “易用”,哪些则不然。因此,首先要快速搭建工具原型。如果借助 Claude Code 编写工具(可能只需一次交互即可生成),建议向 Claude 提供工具所需依赖的所有软件库、API 或 SDK(包括可能用到的 MCP SDK)的文档。通常可在官方文档网站的扁平式 llms.txt 文件中找到适合大语言模型读取的文档(示例:我们的 API 文档)。
将工具封装到本地 MCP 服务器或桌面扩展程序(Desktop Extension,简称 DXT)中,即可连接并在 Claude Code 或 Claude 桌面应用中测试工具:
  • 若要将本地 MCP 服务器连接到 Claude Code,运行命令 claude mcp add <名称> <命令> [参数...] 即可。
  • 若要将本地 MCP 服务器或 DXT 连接到 Claude 桌面应用,分别进入 设置 > 开发者(Settings > Developer)或 设置 > 扩展程序(Settings > Extensions)页面操作。
  • 此外,也可将工具直接传入 Anthropic API 调用中,进行程序化测试。
亲自测试工具,找出潜在问题;收集用户反馈,深入了解工具的预期使用场景与提示词(prompt)设计需求。

 

2.2 开展评估

接下来,需要通过评估衡量 Claude 使用工具的效果。首先,基于真实场景生成大量评估任务。建议与智能体协作,分析评估结果并确定工具改进方向。可在我们的工具评估指南中查看完整流程。 tool evaluation cookbook

2.2.1 生成评估任务

借助初步原型,Claude Code 可快速探索工具功能,并生成数十组 “提示词 – 响应” 对。提示词需基于真实使用场景设计,并依托实际数据源与服务(如内部知识库、微服务),避免使用过于简单或表面化的 “沙盒” 环境 —— 这类环境无法充分测试工具在复杂场景下的表现。优质的评估任务可能需要多次(甚至数十次)调用工具才能完成。
以下是优质任务示例:
  1. 下周与 Jane 安排一次会议,讨论我们最新的 Acme 公司项目,附上上次项目规划会议的纪要,并预订会议室。
  2. 客户 ID 为 9182 的用户反馈,一次购买尝试被收取了三次费用。请查找所有相关日志条目,并判断是否有其他客户受同一问题影响。
  3. 客户 Sarah Chen 刚提交了取消服务请求。请制定挽留方案,并明确:(1)客户取消服务的原因;(2)最具吸引力的挽留方案;(3)提出挽留方案前需注意的风险点。
以下是劣质任务示例:
  1. 下周与 jane@acme.corp 安排一次会议。
  2. 在支付日志中搜索 purchase_complete 和 customer_id=9182
  3. 查找客户 ID 为 45892 的取消服务请求。
每个评估提示词都需搭配可验证的响应或结果。验证方式可简单到对比基准结果与样本响应的字符串是否完全一致,也可复杂到让 Claude 对响应进行判断。注意避免使用过于严格的验证规则 —— 例如因格式、标点符号不同或存在合理替代表述而误判正确响应。
对于每组 “提示词 – 响应” 对,还可选择性地指定智能体解决任务时应调用的工具,以评估智能体在测试过程中是否能正确理解各工具的用途。但需注意,解决任务的有效路径可能不止一条,因此应避免过度指定工具或让策略过度拟合。

2.2.2 执行评估

建议通过直接调用 LLM API 以程序化方式执行评估。使用简单的智能体循环(用 while 循环包裹交替进行的 LLM API 调用与工具调用):每个评估任务对应一个循环。每个评估智能体需获取一个任务提示词和全套工具。
在评估智能体的系统提示词中,建议要求智能体不仅输出结构化响应块(用于验证),还要输出推理块与反馈块。若要求智能体在输出工具调用和响应块之前先输出这些内容,可触发思维链(Chain-of-Thought,简称 CoT)行为,提升大语言模型的实际 “智能” 表现。
若使用 Claude 执行评估,可直接开启 “交错思考”(interleaved thinking)功能以实现类似效果。该功能有助于探究智能体调用或不调用某些工具的原因,并明确工具描述与规格中需改进的具体方向。
除了整体准确率,还建议收集其他指标,如单个工具调用与任务的总运行时间、工具调用总次数、令牌总消耗量以及工具错误率。跟踪工具调用情况,可发现智能体常用的工作流程,进而找到工具功能整合的机会

2.3 与智能体协作

你甚至可以让智能体直接分析评估结果并优化工具:只需将评估智能体的记录拼接后粘贴到 Claude Code 中即可。Claude 擅长分析记录并批量重构工具,例如在工具新增功能后,确保其实现与描述保持一致性。
事实上,本文中的大部分建议,都源自我们通过 Claude Code 反复优化内部工具实现的实践。我们的评估基于内部工作环境构建,还原了内部工作流程的复杂性,涵盖真实项目、文档与消息。
我们借助预留测试集(held-out test sets)避免评估结果过度拟合 “训练型” 评估任务。这些测试集显示,即便采用 “专家级” 工具实现(无论是由研究人员手动编写,还是由 Claude 自动生成),我们仍能进一步提升工具性能。
在下一节中,我们将分享从这一过程中总结的经验。

3 编写高效工具的原则

在本节中,我们将实践经验提炼为几条编写高效工具的指导原则。

3.1 为智能体选择合适的工具

工具并非越多越好。我们发现一个常见误区:无论工具是否适合智能体,都一味地用其封装现有软件功能或 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(通过 ID 获取客户信息)、list_transactions(列出交易记录)和 list_notes(列出备注)工具,可实现 get_customer_context(获取客户上下文)工具,一次性整合客户的所有近期相关信息。
确保每个工具都有清晰、独特的用途。工具应能让智能体像人类一样,在获取相同底层资源的情况下拆分并解决任务,同时减少原本因中间输出而消耗的上下文。
过多工具或功能重叠的工具,也可能让智能体难以选择高效策略。因此,对工具的构建(或不构建)进行审慎、有选择的规划,能带来显著成效。

3.2 对工具进行命名空间划分

AI 智能体可能会访问数十个 MCP 服务器和数百种不同工具(包括其他开发者开发的工具)。若工具功能重叠或用途模糊,智能体可能会困惑于该选择哪一个。
命名空间划分(将相关工具归类到统一前缀下)有助于在大量工具中明确边界,MCP 客户端有时会默认执行此操作。例如,按服务(如 asana_searchjira_search)或资源(如 asana_projects_searchasana_users_search)对工具进行命名空间划分,能帮助智能体在合适的场景选择合适的工具。
我们发现,选择前缀式命名空间还是后缀式命名空间,会对工具使用评估结果产生显著影响。不同大语言模型的表现差异较大,因此建议根据自身评估结果选择命名方案。
智能体可能会出现调用错误工具、用错误参数调用正确工具、调用工具次数不足或错误处理工具响应等问题。通过选择性地实现名称能反映任务自然划分的工具,可同时减少加载到智能体上下文的工具数量与工具描述,将智能体上下文内的计算任务转移到工具调用本身,从而降低智能体出错的整体风险。

3.3 工具返回有意义的上下文

同理,工具实现时应注意仅向智能体返回高价值信息:优先保证上下文相关性,而非灵活性;避免返回底层技术标识符(例如:uuid256px_image_urlmime_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 个令牌)

    1111

  • 简洁版工具响应示例(72 个令牌)

2222

Slack 线程及线程回复通过唯一的 thread_ts 标识,获取线程回复需用到该标识。thread_ts 及其他 ID(如 channel_iduser_id)可从 “详细版” 工具响应中获取,以支持后续需这些标识的工具调用;“简洁版” 工具响应仅返回线程内容,不包含 ID。在该示例中,“简洁版” 响应仅消耗约 1/3 的令牌。
此外,工具响应结构(如 XML、JSON、Markdown)也可能影响评估性能,不存在 “万能” 结构。这是因为大语言模型基于 “下一个令牌预测” 训练,对与训练数据匹配度高的格式表现更优。最佳响应结构会因任务与智能体不同而有很大差异,建议根据自身评估结果选择

 

3.4 优化工具响应的令牌效率

优化上下文质量固然重要,但优化工具响应返回给智能体的上下文 “数量” 也同样关键。
对于可能消耗大量上下文的工具响应,建议结合分页、范围选择、过滤和 / 或截断功能,并设置合理的默认参数值。以 Claude Code 为例,我们默认将工具响应限制在 25,000 个令牌以内。尽管未来智能体的有效上下文长度可能会增加,但对 “上下文高效型” 工具的需求仍将持续存在。
若选择截断响应,需向智能体提供明确指引。例如,可直接鼓励智能体采用更高效的令牌使用策略:在知识检索任务中,进行多次小型定向搜索,而非单次大范围搜索。同样,若工具调用出错(如输入验证失败),可通过提示工程优化错误响应,清晰传达具体、可操作的改进建议,而非返回晦涩的错误代码或堆栈跟踪信息。
  • 截断工具响应示例:(注:原文此处包含截断响应数据图表,此处略去。)

    1

  • 无用错误响应示例:

    2

  • 有效错误响应示例:

    3

工具截断与错误响应可引导智能体采用更高效的令牌使用方式(如使用过滤或分页功能),或提供工具输入的正确格式示例。

3.5 对工具描述进行Prompt-engineering

提升工具性能的最有效方法之一,就是对工具描述与规格进行提示工程。由于这些内容会加载到智能体的上下文当中,因此能从整体上引导智能体形成有效的工具调用行为。
编写工具描述与规格时,可设想如何向团队新成员介绍该工具:梳理你可能默认掌握的背景信息(如特殊查询格式、专业术语定义、底层资源间的关系),并将其明确化;通过清晰描述(并借助严格的数据模型强制执行)预期输入与输出,避免歧义。尤其要注意,输入参数的命名需清晰无歧义 —— 例如,用 user_id 代替模糊的 user 作为参数名。
借助评估,你能更有把握地衡量提示工程的效果。即便对工具描述进行微小调整,也可能带来显著性能提升。例如,我们对工具描述进行精准优化后,Claude Sonnet 3.5 在 SWE-bench 验证评估中实现了最先进(state-of-the-art)的性能,错误率大幅降低,任务完成度显著提升。
你可在《开发者指南》中查看工具定义的其他最佳实践。若为 Claude 开发工具,还建议阅读工具如何动态加载到 Claude 系统提示词的相关说明。最后,若为 MCP 服务器编写工具,工具注解有助于说明哪些工具需要开放世界访问权限,或哪些工具会执行有破坏性的操作。

4 展望未来

要为智能体构建高效工具,我们需将软件开发思路从可预测的确定性模式,转向非确定性模式。
通过本文介绍的 “迭代式、评估驱动” 流程,我们总结出工具成功的共性特征:高效工具需具备明确的设计目标与清晰的定义,合理利用智能体上下文,能在多样化工作流中灵活组合,并让智能体直观地解决现实世界中的任务。
未来,智能体与世界交互的具体机制(从 MCP 协议更新到底层大语言模型升级)必将不断演进。而通过 “系统化、评估驱动” 的工具改进方法,我们能确保:随着智能体能力的提升,其所用工具也能同步进化。

分类&标签