为 AI Agent 编写有效工具
原文:Writing Effective Tools for AI Agents
来源:Anthropic Engineering Blog
翻译整理:2026-06-16
核心洞察
工具是一种全新类型的软件,它反映的是确定性系统与非确定性 Agent 之间的契约。
这一定义揭示了工具设计区别于传统 API 设计的本质:API 的调用方是另一段代码(行为确定),而 Agent 工具的调用方是 LLM(行为非确定)。这意味着工具设计必须优先考虑 LLM 的理解能力和决策特点,而非仅仅封装底层 API 的能力。
最常见的错误:把 API 端点直接封装成工具
“仅封装现有 API 端点”是工具设计中最常见的错误。
反例:GitHub MCP server
GitHub MCP server 将 GitHub 的每个 API 端点都暴露为一个独立工具,结果工具定义本身就消耗了 40,000-55,000 tokens 的上下文窗口。
这直接造成两个问题:
- Agent 的可用上下文空间被工具定义大幅压缩
- 工具数量过多,Agent 无法准确判断在特定场景应该调用哪个工具
正确方向:针对高价值工作流构建精炼工具
不要问「这个 API 端点要不要封装?」,而要问「Agent 最常需要完成哪些任务?」针对这些任务设计工具,而不是机械地映射 API。
工具设计三步法
第一步:构建原型
基于 API 文档和 SDK,创建工具的初始实现,通过 MCP server 或 Desktop 扩展在本地进行测试。
目标:快速构建可运行的原型,不追求完美,先让 Agent 能用起来。
第二步:运行评估
围绕真实工作流设计测试用例,系统性地衡量 Agent 表现:
- 准确率:Agent 是否正确完成了任务?
- Token 消耗:每次任务消耗了多少上下文?
- 工具错误率:Agent 选错工具或调用失败的频率?
关键:测试用例必须基于「真实工作流」,而非人为构造的边缘情况。
第三步:用 AI 迭代优化
使用 Claude Code 分析评估结果中的 transcript(执行日志),自动识别瓶颈并优化工具实现。
这一步的核心是让 AI 来优化 AI 使用的工具,而非依赖工程师的直觉手动调整。
五大设计原则
原则 1:工具少而精,而非多而全
“更多的工具不总是带来更好的结果。”
推荐做法:构建少数能处理多步操作的强力工具,而非把每个 API 端点单独封装。
示例对比:
❌ 错误做法:
check_calendar_availability(date, time)
create_calendar_event(title, date, time, attendees)
send_calendar_invite(event_id, attendees)
✅ 正确做法:
schedule_event(title, date, time, attendees)
# 内部自动处理:检查可用性 → 创建事件 → 发送邀请
合并成单一工具的好处:Agent 只需做一次决策,而不是链式调用三次,大幅降低出错概率。
原则 2:用命名空间防止工具混淆
当 Agent 同时接入多个系统时,使用一致的前缀进行分组:
asana_search # Asana 相关
asana_create_task
asana_update_task
jira_search # Jira 相关
jira_create_issue
jira_update_issue
这使 Agent 在选择工具时能快速定位到正确的系统,减少「混用工具」的决策错误。
原则 3:返回高信息密度的响应
工具的返回值应该让 Agent「一眼看懂」,而不是返回需要二次解析的原始数据。
示例对比:
❌ 低质量返回(返回内部 ID):
{"task_id": "TASK-4721934", "assignee_id": "USR-001923"}✅ 高质量返回(返回语义化信息):
{"task": "Fix login bug", "assignee": "Alice Chen", "due": "2026-06-20"}进阶技巧:提供 response_format 参数,让 Agent 按需选择详细程度:
summary:只返回关键字段(省 token)full:返回完整信息(需要细节时)
原则 4:Token 优化——分页、过滤、截断
工具返回值过大是上下文污染的主要来源之一。
最佳实践:
- 默认返回分页结果,而非一次性返回所有数据
- 支持过滤参数,让 Agent 只获取相关数据
- 对超长文本进行截断,并在响应中说明「已截断,可通过 X 获取完整内容」
- 通过有用的错误信息引导 Agent 向正确的查询模式靠拢
示例:
# 错误信息不应该是:
"Error: too many results"
# 而应该是:
"返回了 1000+ 条结果,建议添加时间范围过滤(参数:start_date, end_date)
以缩小结果集。当前仅返回前 20 条。"
原则 5:工具描述即指令,而非文档
工具描述对 Agent 性能的影响远超大多数工程师的预期。
心智模型转变:不要把工具描述当「API 文档」来写,要把它当「给新团队成员的操作指南」来写。
差异对比:
❌ 文档风格(描述「是什么」):
search_emails: Searches the email database using the provided query string.
Parameters:
- query: Search query
- limit: Max results
✅ 指令风格(描述「怎么用」和「什么时候用」):
search_emails: 在用户邮件中搜索相关内容。
适用场景:用户询问某封邮件是否存在、需要找特定人发的邮件、
或需要根据邮件内容采取行动时。
注意:对于"最近的邮件",使用 date_filter="last_7_days";
对于发件人搜索,使用 from="email@example.com" 而非在 query 中写名字。
关键结论
通过这套「原型 → 评估 → AI 迭代」的流程,Anthropic 内部评估显示工具性能有可量化的显著提升,远优于依靠工程师直觉手动调优的结果。
工具设计的根本原则只有一条:工具是为 LLM 设计的,不是为人类设计的。所有设计决策——少而精、命名清晰、返回语义化、描述像指令——都是这一原则的不同侧面。
与其他文章的关联
- 本文工具设计原则与 Context Engineering 强关联:精炼的工具集是有效上下文管理的前提条件
- GitHub MCP server 的反例同时出现在两篇文章中,印证了「工具膨胀 → 上下文污染 → Agent 性能下降」的完整链条