为 Agent 编写高效工具——与 Agent 协作¶
原文发布于 2025 年 9 月 11 日,作者 Ken Aizawa
什么是工具?¶
工具代表一种全新的软件形态——它是确定性系统与非确定性 Agent 之间的契约。 与传统函数调用不同,Agent 对工具的使用具有不可预测性:它可能调用工具,也可能直接从已有知识中作答,还可能追问澄清性问题,甚至产生幻觉。
我们的目标是"扩大 Agent 能有效解决各类真实任务的能力边界"。
如何编写工具¶
构建原型¶
快速搭建原型,然后在真实场景中迭代验证。 你可以用 Claude Code 一次性生成一个原型。具体步骤:
- 为你使用的库、API 或 SDK(包括 MCP SDK)提供文档
- 将工具封装为本地 MCP 服务器或桌面扩展(DXT)
- 通过以下命令连接到 Claude Code:
claude mcp add <name> <command> [args...]
工具也可以直接通过 Anthropic API 调用传入。
运行评估¶
生成评估任务¶
评估任务应基于真实场景,具备足够的复杂度,可能需要数十次工具调用才能完成。
| 质量 | 示例 | 为什么 |
|---|---|---|
| 好 | 安排下周与 Jane 关于 Acme Corp 项目的会议,附上笔记并预订会议室 | 涉及多步操作、需要检索上下文、组合多个工具 |
| 好 | 查找客户 ID 9182 被收费三次的日志条目,判断是否有其他客户受影响 | 需要搜索、过滤、跨记录关联分析 |
| 好 | 为一个取消订阅请求准备挽留方案:列出取消原因、提出有吸引力的报价、评估流失风险 | 需要理解业务逻辑并生成结构化输出 |
| 差 | 安排下周与 [email protected] 的会议 | 太简单,一次调用即可完成 |
| 差 | 搜索支付日志中的特定字段 | 没有上下文,不需要推理 |
| 差 | 通过 ID 查找取消请求 | 纯粹的查找操作,无需 Agent 能力 |
运行评估的方式¶
使用编程方式的直接 API 调用,构建简单的 Agent 循环来执行评估。
- 用 while 循环交替调用 API 和工具
- 让 Agent 在调用工具和返回响应之前输出推理/反馈块
- 开启 interleaved thinking 获取思维链
- 收集关键指标:运行时间、工具调用次数、token 消耗量、错误数

内部 Slack 工具在留出测试集上的表现

内部 Asana 工具在留出测试集上的表现
分析结果¶
关注 Agent 在哪里卡住,阅读推理过程比阅读最终输出更有价值。
- 观察 Agent 在哪些环节受阻
- 阅读推理/思维链,识别工具定义中的粗糙边缘
- 审查原始记录,包括工具调用和响应
- "Agent 在反馈和响应中省略的内容,往往比它包含的内容更重要"
- 分析工具调用指标,找出冗余调用或错误
一个实际案例:在发布 Claude 网页搜索工具时,团队发现 Claude 总是在 query 参数后多余地拼接 2025,导致搜索结果有偏差。
与 Agent 协作¶
将评估记录喂给 Claude Code,让它分析模式并重构工具。 具体做法是把评估记录拼接起来粘贴到 Claude Code 中,让它分析 Agent 行为模式并重构工具以确保一致性。团队使用留出测试集避免过拟合,并发现这种方法能够取得超越人类专家实现的性能提升。
编写高效工具的原则¶
选择正确的工具¶
工具不是越多越好,不要简单地把每个 API 端点包装成一个工具。 关键是把多个离散操作整合为有意义的高层功能。
| 不推荐(简单 API 包装) | 推荐(整合高层功能) |
|---|---|
list_users + list_events + create_event |
schedule_event——整合用户查找、事件创建等操作 |
read_logs |
search_logs——返回相关日志行及上下文 |
get_customer_by_id + list_transactions + list_notes |
get_customer_context——一次性返回客户全景信息 |
工具应当在底层处理多个离散操作,对外暴露符合任务直觉的接口。
命名空间¶
为相关工具添加统一前缀,帮助 Agent 理解工具之间的关系。 例如 asana_search、jira_search、asana_projects_search。
需要注意的是,前缀式命名(asana_search)和后缀式命名(search_asana)对评估结果有"非平凡的影响",且效果因 LLM 而异。
返回有意义的上下文¶
返回高信噪比信息,优先考虑语义相关性而非底层技术细节。
| 避免 | 推荐 |
|---|---|
uuid |
语义化名称或 0-indexed ID |
256px_image_url |
image_url |
mime_type |
file_type |
| 字母数字型 UUID | 解析为有意义的语言 |
可以使用 ResponseFormat 枚举来控制响应详细程度:
enum ResponseFormat {
DETAILED = "detailed",
CONCISE = "concise"
}

详细模式:206 tokens

精简模式:约为详细模式的 1/3 token 量
为 Token 效率优化工具响应¶
通过分页、范围选择、过滤和截断来控制响应大小,引导 Agent 使用高效的查询策略。
关键实践:
- 实现分页、范围选择、过滤和/或截断
- Claude Code 默认将工具响应限制在 25,000 tokens
- 引导 Agent 采用"多次小范围精确搜索"而非"单次大范围搜索"的策略
- 错误响应要具体且可操作——避免不透明的错误码或堆栈跟踪

截断响应示例:引导 Agent 使用过滤器/分页

反面示例:无用的错误响应

正面示例:包含正确格式示例的错误响应
用 Prompt 工程优化工具描述¶
像给新入职的同事介绍工作一样来描述工具——把隐性知识显性化。
具体原则:
- 明确查询格式(如日期格式、搜索语法)
- 解释领域术语和资源之间的关系
- 使用严格的数据模型避免歧义
- 参数命名要无歧义:用 user_id 而不是 user
实际案例:Claude Sonnet 3.5 在 SWE-bench Verified 上达到 SOTA,关键突破之一就是"对工具描述的精确打磨"。
展望¶
高效的工具是被有意且清晰地定义的,它们审慎地利用 Agent 上下文,能在多样化的工作流中组合使用,并让 Agent 能够直觉地解决真实世界的任务。
致谢¶
本文由 Ken Aizawa 撰写,Anthropic 研究团队、MCP 团队、产品工程团队、市场团队、设计团队和应用 AI 团队均有贡献。