Claude Code 学习站

给 AI 代理写好工具:Claude Code 官方实践要点

摘要 Anthropic 官方文章,讲解如何通过评估驱动的方法与 Claude 协作设计、命名和优化代理工具,提升 Claude Code 等代理系统的可靠性。

本页目录3
要点速览
  • 工具是「确定性系统与非确定性代理之间的契约」,数量多不等于效果好,应优先整合高频工作流为少量针对性工具
  • 用真实、多步骤的任务构建评估集,记录工具调用次数、token 消耗、错误率等指标,再据此迭代
  • 返回语义化字段(如 name、file_type)而非 uuid 等技术标识符,可显著降低代理幻觉
  • 支持 concise/detailed 等响应格式并做好分页截断,能大幅节省上下文 token
  • 工具描述本身就是提示工程对象,把它当作「给新同事的说明书」来写,小改动可能带来大提升
  • 可以把评估记录直接丢给 Claude Code 让它自动分析并重写工具定义,但要留一部分保留测试集防止过拟合

本文是对 Anthropic 官方文章「Writing effective tools for AI agents — with agents」的中文要点摘要,完整内容以原文为准:https://www.anthropic.com/engineering/writing-tools-for-agents

这篇工程博客(2025-09-11 发布,作者 Ken Aizawa)讨论了一个核心问题:代理(agent)的表现很大程度上取决于它可用工具的质量。文章提出工具是「确定性系统与非确定性代理之间的契约」——代理可能以设计者没预料到的方式调用工具,甚至误用或产生幻觉,因此工具设计的目标是让代理「凭直觉」就能正确使用。

方法论:原型 → 评估 → 迭代

先搭原型。 把软件库、API、SDK 文档喂给 Claude(推荐 llms.txt 这种 LLM 友好格式),用 claude mcp add <name> <command> [args...] 接入本地 MCP server,或在 Claude Desktop 的 Settings > Developer/Extensions 中连接,或直接走 Anthropic API。先手动测试,摸清代理适应的边界。

再做评估。 好的评估任务要贴近真实工作流、用真实数据源、需要多步骤(可能几十次工具调用)。例如「客户 ID 9182 反映被重复扣款三次,查找所有相关日志条目并判断是否有其他客户受影响」这种任务,比「在支付日志里搜 purchase_completecustomer_id=9182」这种过度简化的单步任务更有价值。验证真值时不要用过严的校验器,应容忍格式/措辞上的合理差异。

评估执行可以很朴素:写个 while 循环交替调用 LLM API 和工具,让系统提示要求代理输出结构化的推理块和反馈块(配合 extended thinking 效果更好)。需要跟踪的指标包括:任务完成精度、单次工具调用与整体任务耗时、工具调用总次数、token 消耗、工具错误率。

分析结果时重点看代理卡顿/困惑的地方、推理链中的模式、原始记录里的隐性行为,以及代理「没做」的事情(往往比做错的事更能说明问题)。比如文中提到 Claude 的网络搜索工具曾在查询里多余地附加「2025」,通过改写工具描述就纠正了。一个有意思的实践是:把评估记录直接粘给 Claude Code,让它自动分析并重构多个工具定义——只要留出一份保留测试集防止过拟合,即便是「专家」手工写的工具,往往也还能再挤出性能提升。

编写有效工具的五条原则

1. 选对工具,而不是工具越多越好。 常见错误是简单包装现有 API 端点。代理的上下文是稀缺资源,而服务端计算相对便宜——与其返回全部数据让代理逐条筛选,不如做一个 search_contacts 这样的针对性工具。建议把多个离散操作整合成高层工具,比如用 schedule_event 替代 list_users+list_events+create_event 的组合,用 get_customer_context 替代分别拉客户信息、交易记录、备注的三个工具。

2. 给工具加命名空间。 当代理能访问来自多个 MCP server 的成百上千个工具时,重名或功能重叠会造成混淆。可以按服务分组(asana_searchjira_search)或按资源分组(asana_projects_search)。文章特别提醒:前缀 vs 后缀命名对不同 LLM 的效果「非平凡地」不同,需要靠自己的评估来定,没有放之四海而皆准的方案。

3. 返回有意义的上下文,而非灵活但晦涩的数据。 优先高信号信息、语义清晰的字段(namefile_type)而非技术标识符(uuidmime_type)——自然语言标识符能显著降低代理幻觉率。同时可以设计 ResponseFormat 枚举(如 detailed / concise),文中给出一个 Slack 场景的例子:详细格式 206 token、简洁格式仅 72 token(约三分之一),需要 ID 做后续调用时才用详细格式。响应用 XML、JSON 还是 Markdown 也会影响表现,同样建议靠评估决定。

4. 优化 token 效率。 通过分页、范围选择、过滤、截断来控制工具返回的上下文量,并设置合理默认值(Claude Code 默认把单次工具响应限制在 25,000 token)。截断时不要只报一个不透明错误,而要给出具体、可操作的下一步建议,例如(本站示意,非原文用例):「结果超过 500 条,可尝试:(1) 按名字搜索 (2) 加日期范围 (3) 用 page 参数翻页」,这比一句 TypeError: invalid_parameter 有用得多。

5. 把工具描述当提示工程来写。 这是最容易见效的优化点之一,因为描述会被加载进代理的上下文,直接影响它的调用行为。建议把工具描述想象成「给团队新人讲解这个工具怎么用」,把隐含的上下文(专用查询格式、术语定义、资源间关系)显式写出来,参数命名也要明确(比如把 user 改成 user_id)。文中提到 Claude Sonnet 3.5 在 SWE-bench Verified 上刷新 SOTA 的过程里,精细打磨工具描述显著降低了错误率。开发者还可以参考 Anthropic 开发者指南里关于工具定义的最佳实践,以及 MCP 的工具注解(tool annotations)机制,用来标注哪些工具需要开放世界访问权限或有破坏性副作用。

小结

文章的落脚点是:软件开发正从「可预测的确定性模式」转向「非确定性模式」,好工具的共性是目的清晰、审慎使用代理上下文、能在多样工作流中自由组合。随着 MCP 协议和底层模型持续演进,评估驱动、与代理协作迭代的方法能确保工具设计跟上代理能力的成长。