什么是工具?
在计算领域,确定性系统在给定相同输入时每次会产生相同输出,而非确定性系统,如智能体即使在相同起始条件下也能产生不同的响应。
当我们传统地编写软件时,是在建立确定性系统之间的契约。例如,像getWeather(“NYC”)这样的函数调用,每次被调用时都用完全相同的方式获取纽约市的天气信息。
工具是新型软件,反映了确定性系统与非确定性智能体之间的契约。当用户询问”我今天应该带伞吗?”时,智能体会调用天气工具,根据一般知识回答,甚至首先提出关于位置的澄清问题。智能体可能出现幻觉,无法掌握如何使用工具。
在为智能体编写软件时,我们需要从根本上重新思考我们的方法:我们需要为智能体设计工具和MCP服务器,不是像为其他开发人员或系统编写函数和API那样编写它们。
我们的目标是通过使用工具追求各种成功策略,增加智能体能有效解决广泛任务的范围。
如何编写工具
在本节中,我们将提供如何与智能体协作编写和改进提供给它们的工具。首先快速搭建工具原型、在本地进行测试。运行全面评估衡量后续更改。与智能体协同工作,能重复评估和改进工具的过程,直到智能体在现实任务中实现强劲性能。
构建原型
若不亲自实践,很难预测智能体觉得哪些工具符合人体工程学,哪些不会。快速搭建工具原型。如果使用Claude Code编写工具(可能一次性完成),最好为工具将依赖的任何软件库、API或SDK(包括MCP SDK)提供文档说明。在官方文档网站上能找到适合LLM的扁平化llms.txt文件(这是我们的API文档)。
将工具包装在本地MCP服务器或桌面扩展(DXT)中,将能在Claude Code或Claude桌面应用中连接和测试工具。
要将本地MCP服务器连接到Claude Code,请运行 claude mcp add <名称> <命令> [参数…]。
要将本地MCP服务器或DXT连接到Claude桌面应用,请分别导航至设置 > 开发者或设置 > 扩展。
工具能直接传入Anthropic API调用中进行程序化测试。
亲自测试工具识别不足之处。收集用户反馈,围绕期望工具能支持的用例和提示建立直观理解。
运行评估
接下来,需要通过运行评估衡量Claude使用工具的效果。基于实际使用场景生成大量评估任务。建议与智能体协作帮助分析结果、确定如何改进工具。请在我们的工具评估指南中查看此端到端过程。

1.生成评估任务
使用早期原型,Claude Code能快速探索工具、创建数十个提示和响应对。提示应受到实际使用场景的启发,基于真实的数据源和服务(例如,内部知识库和微服务)。我们建议避免使用过于简单或肤浅的”沙盒”环境,这些环境无法用足够的复杂性对工具进行压力测试。强大的评估任务需要多次工具调用——可能达到数十次。
以下是一些强大任务的示例:
- 与Jane安排下周会议讨论我们最新的Acme Corp项目。附上我们上次项目规划会议的记录、预订会议室。
- 客户ID 9182报告称他们在一次购买尝试中被收取了三次费用。查找所有相关日志条目并确定是否有其他客户受到同一问题影响。
- 客户Sarah Chen刚刚提交了取消请求。准备保留优惠。确定:(1)他们离开的原因,(2)哪种保留优惠最具吸引力,以及(3)在提供优惠前我们应该注意的任何风险因素。
以下是一些较弱任务的示例:
- 与jane@acme.corp安排下周会议。
- 在支付日志中搜索purchase_complete和customer_id=9182。
- 查找客户ID 45892的取消请求。
每个评估提示都应配有一个可验证的响应或结果。验证器能简单到对真实答案和抽样响应进行精确字符串比较,或复杂到请Claude判断响应。避免使用过于严格的验证器,验证器会因格式、标点或有效的替代表述等虚假差异拒绝正确响应。
对于每个提示-响应对,选择指定期望智能体在解决任务时调用的工具,衡量智能体在评估期间是否成功掌握每个工具的用途。由于可能存在多个正确解决任务的有效路径,请尽量避免过度指定或过度拟合策略。
2.运行评估
我们建议通过直接的LLM API调用以编程方式运行评估。使用简单的智能体循环(包装交替的LLM API和工具调用的while循环):每个评估任务一个循环。每个评估智能体被赋予单个任务提示和工具。
在评估智能体的系统提示中,建议指示智能体输出结构化响应块(用于验证),还要输出推理和反馈块。指示智能体在工具调用和响应块之前输出这些内容,通过触发思维链(CoT)行为提高LLM的有效智能。
如果使用Claude运行评估,开启交错思考获得类似的”开箱即用”功能。将帮助探究智能体为何调用或不调用某些工具,突出显示工具描述和规范中需要改进的具体领域。
除顶级准确性外,建议收集其他指标,如单个工具调用和任务的总运行时间、工具调用总数、总令牌消耗量以及工具错误。跟踪工具调用能帮助揭示智能体追求的常见工作流程,为工具整合提供机会。

3.分析结果
智能体是发现问题和提供反馈的有用伙伴,涵盖从相互矛盾的工具描述到低效的工具实现和令人困惑的工具模式等各个方面。智能体在反馈和响应中省略的内容通常比包含的内容更重要。LLM不总是准确表达出它们的真实含义。
观察智能体在哪些地方卡主或困惑。通读评估智能体的推理和反馈(或思维链)识别不足之处。审查原始记录(包括工具调用和工具响应)捕捉智能体思维链中未明确描述的任何行为。读懂字里行间的含义;记住评估智能体不一定知道正确答案和策略。
分析工具调用指标。大量冗余的工具调用可能表明需要适当调整分页或令牌限制参数;大量无效参数的工具错误可能表明工具需要使用更清晰的描述或更好的示例。当我们推出Claude的网络搜索工具时,我们发现Claude不必要地在工具查询参数后附加2025,这偏斜了搜索结果、降低了性能(我们通过改进工具描述将Claude引导到正确方向)。
4.与智能体协作
您甚至可以让智能体分析结果、改进工具。只需将评估智能体的记录连接起来,粘贴到Claude Code中。Claude是分析记录和一次性重构大量工具的专家——例如,确保在进行新更改时工具实现和描述保持自一致。
事实上,本文中的大部分建议都来自于使用Claude Code反复优化我们的内部工具实现。我们的评估建立在内部工作空间之上,反映我们内部工作流程的复杂性,包括真实项目、文档和消息。
我们依赖保留的测试集确保不会过度拟合我们的”训练”评估。测试集表明,即使超越”专家”工具实现的性能,我们能提取额外的性能改进——无论工具是由我们的研究人员手动编写还是由Claude自身生成。
在下一节中,我们将分享从这一过程中学到的一些经验。
编写高效工具的原则
在本节中,我们将所学知识提炼为一些编写高效工具的指导原则。
为智能体选择合适的工具
更多工具不总能带来更好的结果。我们观察到的一个常见错误是工具只包装了现有的软件功能或API端点——无论工具是否适合智能体。这是因为智能体与传统软件具有不同的”功能可见性”——他们感知并使用工具的方式与传统软件截然不同。
LLM智能体具有有限的”上下文”(即它们一次能处理的信息量有限),计算机内存廉价且充足。以在地址簿中搜索联系人的任务为例。传统软件程序可以高效地逐个存储和处理联系人列表,在继续之前检查每个联系人。
如果LLM智能体使用返回所有联系人的工具,必须逐个令牌地阅读每个联系人,它就在无关信息上浪费有限的上下文空间(想象一下通过从上到下阅读每一页来在地址簿中搜索联系人——即通过暴力搜索)。更好更自然的方法(对智能体和人类 alike)是首先跳到相关页面(也许按字母顺序找到它)。
我们建议先构建少量经过深思熟虑的工具,针对高价值的工作流,这些工具与评估任务相匹配,在此基础上进行扩展。在地址簿案例中,选择实现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枚举参数来实现两者,让智能体控制工具返回”简洁”还是”详细”响应(下图)。
您能添加更多格式以获得更大灵活性,类似于GraphQL,选择确切想要接收的信息片段。以下是一个控制工具响应详细程度的ResponseFormat枚举示例:
enum ResponseFormat {
DETAILED = "detailed",
CONCISE = "concise"
}
以下是详细工具响应的示例(206 个 token):