Writing Effective Tools for Agents—with Agents(用 Agent 为 Agent 写有效的工具)
- 原文标题
- Writing Effective Tools for Agents—with Agents(用 Agent 为 Agent 写有效的工具)
- 原文链接
- https://www.anthropic.com/engineering/writing-tools-for-agents
- 作者
- Ken Aizawa 等(Anthropic)
- 发布日期
- 2025-09-11
🎯 一句话
给模型用的工具和给程序员用的 API 不是一回事。⭐ 核心差别:模型没有文档可查、不能试错、只能靠工具描述和返回值来理解一切。
为 Agent 写高质量工具需要重新思考软件开发实践:工具不是简单的函数封装,而是确定性系统与非确定性 Agent 之间的新契约。「Agent 的能力上限由我们给它的工具决定」。文章给出一套评估驱动的工具改进方法论,包括让 Agent 参与优化自己的工具。
理解 Agent 工具的特殊性
- 传统软件是确定性契约(同输入同输出);Agent 是非确定性的——可能以不同方式调用工具,或根本不调用
- 工具要容纳 Agent 可能采取的多种合理策略
- Agent 会偶尔幻觉或误解用法,设计要考虑其局限而非假设最优使用
- 对 Agent 最顺手的工具,往往对人也直觉友好
工作流:原型 → 评估 → 迭代
1. 快速原型
- 用 Claude Code 编写工具(喂给它官方 API 的 llms.txt 文档)
- 封装成本地 MCP server 或桌面扩展测试;
claude mcp add接入 - 亲手试用找毛边——「很难预判 Agent 觉得哪些工具顺手」
2. 综合评估
生成评估任务: 基于真实工作流的几十个「提示-验证」对,避免过度简化的沙箱。强任务需要多次(甚至数十次)工具调用,例如: - 「客户 ID 9182 反映一笔购买被扣三次款,找出所有相关日志并判断是否影响了其他客户」(强) - 「在支付日志中搜索 purchase_complete 和 customer_id=9182」(弱——步骤已经替 Agent 想好了)
运行评估: 用 API 直接跑简单 Agent 循环;让 Agent 在工具调用前输出推理和反馈块;跟踪准确率之外的指标——运行时间、调用次数、token 消耗、错误率。
分析结果: 读 Agent 的推理找困惑点;读原始转录抓 Agent 不会明说的隐式行为。例子:Anthropic 发现 Claude 会在搜索词后多余地拼接 "2025",根源是工具描述有误导。
3. 让 Claude 改进工具
把评估转录喂给 Claude Code,让它分析模式并系统性重构工具。内部实测:Claude 优化后的 Slack/Asana MCP server 性能超过专家手写版本。
五条工具设计原则
1. 选对工具(而非更多工具)
- Agent 的上下文有限,计算机内存无限——不要把「返回全部联系人列表」这种工具给 Agent
- 围绕高影响工作流构建少量针对性工具:
schedule_event(内部处理找空档+排期)优于拆开的list_users+list_events+create_eventsearch_logs(只返回相关行及上下文)优于read_logsget_customer_context(汇总近期信息)优于三个分立查询工具
2. 命名空间
- 相关工具加统一前缀(按服务:
asana_search、jira_search;或按资源:asana_projects_search) - 减少上下文负担、划清边界;前缀式与后缀式命名对性能有可测量的不同影响
3. 返回有意义的上下文
- 优先语义化字段:
name优于裸user_id,image_url优于256px_image_url,file_type优于mime_type - 用自然语言或索引 ID 替代任意字母数字 UUID,显著减少幻觉
- 提供
response_format枚举参数(concise / detailed)让 Agent 自选详略——省约三分之一 token
4. 为 token 效率优化
- 分页、范围选择、过滤、带指引的截断(Claude Code 默认限制单次响应 25,000 token)
- 错误信息要可行动:不要「Invalid input」,要指明参数要求并附正确格式示例
5. 提示词工程化的工具描述
- 像给新同事写入职说明一样写工具描述;把隐性知识(专门查询格式、行话、资源关系)显式化
- 参数命名无歧义(
user_id优于user) - 小改进大回报:Claude Sonnet 3.5 在精化工具描述后拿下 SWE-bench Verified 的 SOTA
结论
「为 Agent 构建有效工具,需要把软件开发实践从可预测的确定性模式转向非确定性模式。」有效工具的共性:定义清晰无歧义、审慎使用 Agent 上下文、可灵活组合进多种工作流、让 Agent 能直觉地解决真实任务。与其铺开全面的工具集,不如深耕少数高影响工作流的工具,用评估驱动持续进化。
✅ 检查点
- 给模型的工具和给人的 API,设计取向有什么不同?
- 工具命名和参数设计上有哪些实用原则?
- 怎么评估一个工具设计得好不好?
👀 答案
- ⭐ 人可以查文档、可以试错、可以问同事;模型只有你写的那段描述。所以工具描述要自包含:说清用途、边界、参数含义、典型场景、以及什么时候不该用。另外人能容忍复杂签名,模型会被过多可选参数干扰。
- ①命名要表达意图而不是实现(`search_orders` 而不是 `query_db`);②参数尽量少、语义明确,能有默认值就给默认值;③避免需要模型自己拼接的格式(如复杂的查询字符串);④枚举优于自由文本——能列举的就别让它自由发挥;⑤把容易搞错的约束写进参数描述,而不是指望它记住。
- ⭐ 看模型在真实任务里的使用情况:①调用成功率(参数错误率高说明描述不清)②选择正确率(该用时用了吗、不该用时忍住了吗)③重试次数(高说明错误信息没帮上忙)。⚠️ 不要只看「工具本身能不能跑通」——那是最低标准。
🛑 可以停在这里
⚡ 走神救援
⭐核心差别:人可以查文档、试错、问同事,模型只有你写的那段描述,所以工具描述必须自包含(用途、边界、参数含义、典型场景、什么时候不该用),而且人能容忍复杂签名,模型会被过多可选参数干扰。五条实用原则:命名表达意图而非实现(`search_orders` 不是 `query_db`)、参数尽量少且给默认值、避免需要模型自己拼接的格式、枚举优于自由文本、把容易搞错的约束写进参数描述。⭐评估看真实任务里的三个数:调用成功率(参数错误率高=描述不清)、选择正确率(该用时用了吗、不该用时忍住了吗)、重试次数(高=错误信息没帮上忙);⚠️只看「工具本身能不能跑通」是最低标准。