编写高效工具的最佳实践指南(精华版)

原文来自anthropic:Writing effective tools for agents — with agents

本文概述了为AI代理构建高效工具的关键策略,强调了工具对代理效能的重要性。文章详细介绍了如何通过原型构建、综合评估以及与AI代理(如Claude Code)协作来优化工具。它还阐述了编写高质量工具的原则,包括选择合适的工具、进行命名空间管理、返回有意义的上下文、优化令牌效率以及进行提示工程。最终目标是使代理能够更直观、高效地解决现实世界中的各种任务。

简介

AI代理的效能与其所使用的工具质量息息相关。在传统软件开发中,我们为确定性系统编写软件,例如 getWeather("NYC") 总是以相同方式获取天气信息。然而,工具是连接确定性系统与非确定性代理之间的新型软件契约。代理可能会调用工具、利用通用知识或提出澄清问题来响应用户查询,甚至可能出现幻觉或无法理解如何使用工具。这意味着我们需要从根本上重新思考为代理编写软件的方法,并以代理为中心进行设计

本指南将为您提供一套行之有效的方法和原则,帮助您构建、评估和优化高质量的代理工具,从而扩大代理在解决广泛任务方面的有效性范围

核心方法论:构建、评估与协作优化

编写高效工具是一个迭代过程,涉及构建原型、运行全面评估以及与代理协作优化工具。

  1. 构建原型 (Building a prototype)

    • 快速启动:首先快速建立工具原型,以便亲身体验哪些工具对代理“符合人体工程学”。
    • 提供文档:如果您使用像 Claude Code 这样的代理来编写工具,提供其依赖的任何软件库、API 或 SDK 的文档会非常有帮助,尤其是 LLM 友好的平面文本文档(如 llms.txt 文件)。
    • 本地测试与反馈:将工具包装在本地 MCP 服务器或桌面扩展 (DXT) 中,连接到 Claude Code 或 Claude Desktop 应用进行测试。亲自测试以发现问题,并收集用户反馈,以建立对预期用例和提示的直觉。
  2. 运行评估 (Running an evaluation)

    • 系统性衡量性能:评估能系统地衡量工具性能。
    • 生成评估任务
      • 以真实世界用途为基础:生成大量基于真实世界用例的评估任务。提示应来源于实际数据源和服务(例如内部知识库和微服务),避免过于简单或肤浅的“沙盒”环境,因为它们无法充分测试工具的复杂性。强大的评估任务可能需要多次工具调用。
      • 强任务示例
        • “下周与 Jane 安排一次会议,讨论我们最新的 Acme Corp 项目。附上我们上次项目规划会议的记录并预订一个会议室。”
        • “客户 ID 9182 报告说他们一次购买尝试被收取了三次费用。查找所有相关的日志条目并确定是否有其他客户受到相同问题的影响。”
        • “客户 Sarah Chen 刚刚提交了取消请求。准备一份挽留方案。确定:(1) 他们为什么离开,(2) 什么挽留方案最具吸引力,(3) 在提供方案前我们应该注意哪些风险因素。”
      • 弱任务示例
        • “下周与 [email protected] 安排会议。”
        • “搜索支付日志中的 purchase_completecustomer_id=9182。”
        • “查找客户 ID 45892 的取消请求。”
      • 可验证的响应:每个评估提示都应与一个可验证的响应或结果配对。验证器可以是从精确字符串比较到让 Claude 判断响应的复杂工具。避免过于严格的验证器,它们可能因为格式、标点符号或有效的替代措辞等细微差异而拒绝正确响应。
      • 可选的预期工具调用:您可以选择为每个提示-响应对指定代理在解决任务时预期调用的工具,以衡量代理在评估中是否成功理解每个工具的用途。但要避免过度指定或过度拟合策略,因为可能存在多种解决任务的有效路径。
    • 程序化运行评估:建议使用直接的 LLM API 调用以程序化方式运行评估。对每个评估任务使用简单的代理循环(while 循环封装交替的 LLM API 和工具调用)。
    • 收集多维度指标:除了顶级准确性,还建议收集其他指标,例如单个工具调用和任务的总运行时间、工具调用的总次数、总令牌消耗以及工具错误。跟踪工具调用有助于揭示代理遵循的常见工作流程,并为工具整合提供机会。
    • 系统提示引导思考:在评估代理的系统提示中,建议指示代理不仅输出结构化响应块(用于验证),还输出推理和反馈块。在工具调用和响应块之前输出这些内容,可以通过触发思维链(CoT)行为来提高 LLM 的有效智能。
  3. 分析结果 (Analyzing results)

    • 代理是重要伙伴:代理是发现问题和提供反馈的有用伙伴,反馈内容可以从矛盾的工具描述到低效的工具实现和令人困惑的工具模式。
    • 解读代理行为:观察代理在哪里受阻或困惑。仔细阅读评估代理的推理和反馈(或 CoT)以发现问题。审查原始记录(包括工具调用和工具响应),以捕捉代理 CoT 中未明确描述的任何行为。记住,代理并不一定知道正确答案和策略,需要“字里行间”地理解
    • 分析工具调用指标
      • 过多的冗余工具调用可能表明需要调整分页或令牌限制参数。
      • 因无效参数而导致的工具错误可能表明工具需要更清晰的描述或更好的示例。
      • 示例:Claude 的网页搜索工具曾不必要地在 query 参数中附加“2025”,导致搜索结果偏差和性能下降。通过改进工具描述,引导 Claude 走向正确的方向。
  4. 与代理协作优化 (Collaborating with agents)

    • 让代理分析和改进工具:您可以让代理分析评估结果并自行改进工具。只需将评估代理的记录连接起来,然后粘贴到 Claude Code 中即可。Claude 擅长分析记录并一次性重构大量工具,例如,确保在进行新更改时工具实现和描述保持自洽。
    • Anthropic 团队的大部分建议都来自于使用 Claude Code 反复优化其内部工具实现。他们使用保留测试集来避免对“训练”评估过度拟合,并发现即使在“专家”工具实现(无论是人工编写还是 Claude 生成)之外,也能提取额外的性能改进。

编写高效工具的关键原则

从上述过程中,Anthropic 提炼出以下编写高效工具的指导原则:

  1. 选择正确的工具 (Choosing the right tools for agents)

    • 少即是多,聚焦高影响力:工具并非越多越好。一个常见错误是仅仅封装现有软件功能或 API 端点,而不考虑工具是否适合代理。
    • 理解代理的“可供性”:LLM 代理的“上下文”有限(即它们一次可以处理的信息量有限)。如果一个代理使用返回所有联系人的工具,然后逐个令牌地阅读,它会将有限的上下文空间浪费在不相关的信息上。
    • 优先考虑上下文关联性:例如,在地址簿案例中,应实现 search_contactsmessage_contact 工具,而不是 list_contacts 工具。
    • 整合功能:工具可以整合功能,在底层处理多个离散操作(或 API 调用)。例如,工具可以丰富响应相关的元数据,或者在单个工具调用中处理经常链式调用的多步任务。
      • 示例
        • 与其实现 list_userslist_eventscreate_event 工具,不如考虑实现一个能够查找可用性并安排事件的 schedule_event 工具
        • 与其实现 read_logs 工具,不如考虑实现一个只返回相关日志行和一些上下文的 search_logs 工具
        • 与其实现 get_customer_by_idlist_transactionslist_notes 工具,不如实现一个能够一次性编译客户所有近期和相关信息的 get_customer_context 工具
    • 明确且独特的目标:确保每个工具都有清晰、独特的目标。工具应该使代理能够像人类一样(在访问相同底层资源的情况下)细分和解决任务,同时减少因中间输出而消耗的上下文。
    • 避免冗余和干扰:过多的工具或功能重叠的工具会分散代理的注意力,使其无法采取高效策略。仔细、有选择地规划您构建(或不构建)的工具,可以带来巨大回报。
  2. 命名空间化您的工具 (Namespacing your tools)

    • 解决功能重叠和模糊性:代理可能会访问数十个 MCP 服务器和数百个不同工具。当工具功能重叠或目的模糊时,代理会感到困惑。
    • 使用前缀分组:命名空间(将相关工具分组在公共前缀下)有助于划定工具之间的界限。例如,按服务(如 asana_searchjira_search)和资源(如 asana_projects_searchasana_users_search)对工具进行命名空间化,可以帮助代理在正确的时间选择正确的工具。
    • 考虑前缀与后缀:前缀和后缀命名空间的选择对工具使用评估有显著影响,效果因 LLM 而异。建议根据您自己的评估选择命名方案。
    • 降低代理错误风险:通过有选择地实现名称能反映任务自然细分的工具,您可以同时减少加载到代理上下文中的工具数量和工具描述,并将代理的计算从代理上下文卸载回工具调用本身,从而降低代理犯错的总风险。
  3. 从工具返回有意义的上下文 (Returning meaningful context from your tools)

    • 高信号信息优先:工具实现应注意只向代理返回高信号信息
    • 语境相关性优先于灵活性:应优先考虑语境相关性,避免低级技术标识符(例如:uuid256px_image_urlmime_type)。像 nameimage_urlfile_type 这样的字段更有可能直接影响代理的后续动作和响应。
    • 使用自然语言而非神秘标识符:代理处理自然语言名称、术语或标识符通常比处理神秘标识符成功得多。将任意字母数字 UUID 解析为更具语义意义和可解释性的语言(甚至是 0 索引 ID 方案),能显著提高 Claude 在检索任务中的精确度,减少幻觉。
    • 灵活的响应格式:在某些情况下,代理可能需要灵活性来处理自然语言和技术标识符输出,即使只是为了触发下游工具调用。您可以通过在工具中暴露一个简单的 response_format 枚举参数来实现这一点,允许代理控制工具返回“简洁(concise)”还是“详细(detailed)”的响应。
      • 示例
        • Slack 线程和回复由唯一的 thread_ts 标识,这是获取线程回复所必需的。thread_ts 和其他 ID(channel_iduser_id)可以从“详细”工具响应中检索,以启用需要这些 ID 的进一步工具调用。“简洁”工具响应仅返回线程内容,不包括 ID。在这种情况下,使用“简洁”工具响应可以节省约 ⅓ 的令牌。
    • 优化响应结构:工具响应结构(例如 XML、JSON 或 Markdown)也会影响评估性能。LLM 在与其训练数据匹配的格式下表现更好,因此最佳响应结构会因任务和代理而异。建议根据您的评估选择最佳响应结构。
  4. 优化工具响应的令牌效率 (Optimizing tool responses for token efficiency)

    • 质量与数量并重:优化上下文质量固然重要,但优化工具响应中返回给代理的上下文数量也同样重要。
    • 实现分页、范围选择、过滤和/或截断:对于可能消耗大量上下文的工具响应,建议实现分页、范围选择、过滤和/或截断的某种组合,并设置合理的默认参数值。例如,Claude Code 默认将工具响应限制为 25,000 令牌。
    • 截断后的引导:如果选择截断响应,请务必用有用的指令引导代理。直接鼓励代理采取更节省令牌的策略,例如进行多次小而有针对性的搜索,而不是一次广泛的搜索。
    • 有帮助的错误响应:如果工具调用引发错误(例如,在输入验证期间),应通过提示工程来设计错误响应,以清晰地传达具体且可操作的改进,而不是不透明的错误代码或堆栈跟踪。
      • 示例
        • 无用的错误响应:例如仅返回错误代码。
        • 有用的错误响应:清晰指出参数问题,并提供正确格式的示例,引导代理进行修正。
      • 工具截断和错误响应可以引导代理采取更节省令牌的工具使用行为(使用过滤器或分页),或提供正确格式的工具输入示例。
  5. 提示工程您的工具描述和规范 (Prompt-engineering your tool descriptions)

    • 最有效的方法之一:这是提高工具效率最有效的方法之一。工具描述和规范会加载到代理的上下文中,可以共同引导代理采取有效的工具调用行为。
    • 像描述给新员工一样:编写工具描述和规范时,想象您会如何向团队新员工描述您的工具。明确您可能隐含的上下文——专业的查询格式、特定术语的定义、底层资源之间的关系。
    • 避免歧义:通过清晰描述(并使用严格的数据模型强制执行)预期的输入和输出,避免歧义。特别是,输入参数应明确命名:例如,不要使用 user,尝试使用 user_id
    • 评估验证效果:通过评估可以更自信地衡量提示工程的影响。即使是对工具描述的微小改进,也能带来显著的性能提升。例如,Claude Sonnet 3.5 通过对工具描述进行精确改进,在 SWE-bench Verified 评估中取得了最先进的性能,显著降低了错误率并提高了任务完成度。
    • 查阅更多资源:您可以查阅 Anthropic 的开发者指南了解更多工具定义最佳实践。如果您正在为 Claude 构建工具,还建议阅读关于工具如何动态加载到 Claude 系统提示中的信息。对于 MCP 服务器工具,工具注解有助于披露哪些工具需要开放世界访问或进行破坏性更改。

展望

为了为代理构建高效工具,我们需要将软件开发实践从可预测的确定性模式重新定位到非确定性模式。通过本文描述的迭代、评估驱动的过程,我们发现了一些使工具成功的持续模式:高效的工具是经过有意且清晰定义的,能明智地利用代理上下文,可组合成多样化的工作流程,并使代理能够直观地解决现实世界任务

随着代理能力的增强,我们通过系统化、评估驱动的方法改进工具,可以确保它们所使用的工具也能随之发展。

作者

马克鱼

发布于

2025-09-13

更新于

2025-10-12

许可协议