给 AI agent 写工具:让 agent 自己帮你打磨

MCP 让 agent 可以一下接几百个工具,但工具好不好用是另一回事。这篇讲 Anthropic 怎么用 Claude Code 帮自己打磨内部工具:先写原型、再跑 eval、再让 Claude 帮你看 transcript 改 tool。

一、Tool 是一种新型软件 ⭐

写传统软件,你是在两个确定性系统之间签契约 —— getWeather("NYC") 永远以同样方式拿同样的天气。

写 tool 就不一样了:tool 是确定性系统与非确定性 agent 之间的契约。用户问「今天要带伞吗」,agent 可能:

这意味着写 tool 不能照搬给开发者写 SDK 那一套,要重新设计。目标是:让 agent 在更多任务上能用更多策略走通

经验上,agent 觉得”顺手”的工具,人看着也直觉。两种诉求竟然挺一致。


二、写工具的工作流:prototype → eval → 让 agent 改

1. 先建原型

工具好不好用,你自己不上手很难预判

2. 跑 eval ⭐

光看 demo 不够,得系统性测量

好的 eval 任务长什么样

类型例子
✅ 强「下周给 Jane 安排个会议讨论 Acme 项目,附上上次规划会的笔记,订一间会议室」
✅ 强「客户 9182 反馈被重复扣款 3 次,找出所有相关日志,看有没有其他客户遇到同问题」
❌ 弱「给 jane@acme.corp 安排下周会议」
❌ 弱「查 customer_id=9182 的支付日志」

差别在哪?强 eval 任务模拟真实复杂度,常常需要十几次工具调用串起来。弱的就只考一次调用、没有歧义。

怎么验证结果

跑 eval 的姿势

3. 让 agent 自己分析

Agent 是看 transcript 找问题的好搭子。把 eval transcript 串起来贴给 Claude Code,让它分析、找出:

agent 说的不全是它想的。它没说的,往往比它说的更值得注意。亲自读原始 transcript,包括 tool 调用与返回,字里行间找蛛丝马迹

实战例子:他们当初发布 Claude 的 web search tool,发现 Claude 老往 query 里塞 2025,影响搜索结果。改了工具描述就解决了。


三、写好 tool 的 5 条原则

原则 1:别只是包一下已有 API ⭐

最常见的错误:把现成 API 包一层就当工具丢出来

反例正解
list_contacts(返回全部联系人,agent 一个个看)search_contacts / message_contact
list_users + list_events + create_event(三步)schedule_event(一步搞定可用性查 + 安排)
read_logs(吐全日志)search_logs(只返相关行 + 上下文)
get_customer_by_id + list_transactions + list_notesget_customer_context(一次拿齐)

为什么:agent 的 context 是稀缺资源;传统软件的内存是廉价资源。让 agent 像人翻地址簿一样跳到相关页,别让它逐页扫。

少而精的 tool,胜过多而冗。工具集臃肿会让 agent 在选择中迷失

原则 2:命名空间区分边界

Agent 可能同时挂几十个 MCP server、几百个 tool。重叠和模糊的功能会让 agent 选错。

用前缀分组

前缀 vs 后缀的命名风格,在他们的 eval 里确实有非平凡影响,建议各自跑 eval 看自己模型偏好

原则 3:返回有意义的上下文

只返高信号信息,别堆底层技术字段

别返多返
uuidname
256px_image_urlimage_url
mime_typefile_type

Agent 对自然语言标识符的处理远好于神秘的字母数字 UUID。仅仅把 UUID 换成语义化名字(或 0-indexed ID),就能显著降低幻觉。

进阶:开放 response_format 参数让 agent 自己选「concise / detailed」。例如 Slack 工具:concise 模式只返 thread 内容(72 token),detailed 模式附上 thread_ts / channel_id 等 ID 给后续调用用(206 token)—— 节省 2/3 的 token

格式(XML / JSON / Markdown)也影响表现 —— LLM 在训练数据里见过的格式上表现更好。没有 one-size-fits-all,用你自己的 eval 来选

原则 4:token 效率

关键设置:分页、范围选择、过滤、截断 —— 给所有可能吐大量 context 的工具加上合理默认值

Claude Code 内部默认把工具返回限制在 25,000 token。即便未来 context 变大,token 高效仍是必需

截断时要引导 agent

❌ 无效错误✅ 有效错误
抛 raw error code / traceback「输入超出范围,尝试缩小日期窗 + 加 filter」
静默截断「结果被截断,做 N 个小搜索而不是一次大搜索」

报错信息也是 prompt,专门 prompt-engineer 一下

原则 5:把工具描述当 prompt 来 engineering

这是最有效的优化点之一。工具描述和 schema 会被加载进 agent 的 context,它们会直接 steer agent 的调用行为

写工具描述时像在给新人写交接文档

Claude Sonnet 3.5 在 SWE-bench Verified 上拿到 SOTA,就是靠精修工具描述把错误率打下去的


总结:直觉

给 agent 写工具不是给 SDK 写接口的延续,是个新工种

核心切换

随着模型变强,工具与 agent 之间的协议(MCP)也会变。但**「按非确定性系统的视角去设计接口」**这条底层方法不会过时。

本译文采用 CC BY-NC-SA 4.0 协议发布,仅供学习交流。

原作品版权归 Anthropic(Anthropic Engineering)所有,原文请见 这里