工具描述——让AI"看明白"每个工具的说明书
你有没有好奇过:AI怎么知道该用grep还是find?怎么知道什么时候该读文件、什么时候该执行命令?
答案藏在工具的description里。但这个description不是给人看的文档,而是给模型看的”指令”。今天咱们就聊聊这个”给AI的说明书”该怎么写。
工具描述的本质:给模型的指令
传统软件里,API文档是给人看的——告诉开发者这个接口做什么、参数什么意思、返回值什么格式。
但在AI Agent里,工具描述是给模型看的——告诉模型这个工具做什么、什么时候该用它、参数该怎么填。
这有本质区别。给人看的文档可以详细、可以技术化;给模型看的描述必须简洁、必须明确使用场景。
举个例子,GrepTool的description不是:
GrepTool是一个基于ripgrep的文本搜索工具,支持正则表达式。参数:pattern(正则模式)、path(搜索路径)...
而是:
搜索文件内容,当你需要查找特定文本模式时使用。使用场景:- 查找函数定义在哪里- 搜索所有使用某个变量的地方- 查找包含特定关键词的文件注意:如果搜索结果太多,尝试缩小搜索范围或使用更精确的模式。
看到了吗?第二个版本不只是说”这是什么”,更重要的是说”什么时候用它”。
inputSchema:约束模型的”填空题”
如果说description是”说明书”,inputSchema就是”填空题的格式要求”。
Claude Code使用Zod v4定义inputSchema:
constGrepToolInput = z.object({pattern: z.string().describe('要搜索的正则表达式模式'),path: z.string().optional().describe('要搜索的文件或目录路径'),caseSensitive: z.boolean().optional().describe('是否区分大小写,默认false'),});
这个Schema做了几件事:
类型约束:pattern必须是string,caseSensitive必须是boolean。
必选vs可选:pattern是必选的,path和caseSensitive是可选的。
字段说明:describe()的内容会出现在给模型的JSON Schema中。
严格模式:z.object()默认是严格的,模型不能传入未定义的参数。
图:inputSchema像填空题,约束模型能填什么
模型收到工具列表时,会看到这些信息:
{"name":"GrepTool","description":"搜索文件内容,当你需要查找特定文本模式时使用...","inputSchema":{"type":"object","properties":{"pattern":{"type":"string","description":"要搜索的正则表达式模式"},"path":{"type":"string","description":"要搜索的文件或目录路径"},"caseSensitive":{"type":"boolean","description":"是否区分大小写"}},"required":["pattern"]}}
模型根据description决定”要不要用这个工具”,根据inputSchema决定”参数怎么填”。
动态描述:同一个工具,不同场景
Claude Code的一个高级特性是:description可以动态生成。
description: async (input, options) => {if (options.permissionContext.isToolDenied('BashTool')) {return'执行shell命令(当前被禁用,请使用其他工具)'; }return'执行shell命令,用于运行程序、管理文件等操作';}
这有什么用?
权限感知:当用户禁止了某些操作时,description主动告知模型”不要尝试”。
上下文感知:根据当前项目类型调整描述。比如Python项目强调Python相关功能。
用户偏好:根据用户的使用习惯调整。比如用户喜欢用npm而不是yarn,描述会强调这一点。
这种动态描述让工具能”自适应”不同场景,引导模型做出更合适的选择。
描述优化的实战技巧
如果你想设计自己的工具描述,这些技巧很有用:
以使用场景开头:不要先说”这是什么”,而要说”什么时候用它”。
不好:"FileReadTool用于读取文件内容"好:"当你需要查看文件内容时使用,比如理解代码逻辑、检查配置文件"
举具体例子:模型从例子中学得最好。
使用场景:- 读取配置文件了解项目设置- 查看源代码理解函数实现- 检查日志文件排查问题
说明什么情况下不要用:边界情况同样重要。
注意:- 不要用于搜索,用GrepTool代替- 不要用于大文件(>1MB),可能会超时
保持简洁:描述太长会让模型”困惑”,重点突出。
与inputSchema一致:description中说”用于搜索特定模式”,inputSchema就要有pattern参数。
工具选择的实际案例
看看Claude Code如何处理这个请求:”帮我找一下processRequest函数在哪里”。
模型看到可用工具:
GrepTool:”搜索文件内容,当你需要查找特定文本模式时使用…”FileReadTool:”当你需要查看文件内容时使用…”GlobTool:”列出匹配模式的文件…”BashTool:”执行shell命令…”
模型分析:
-
要找特定函数 → GrepTool的描述匹配”查找特定文本模式” -
不确定文件名 → 不适合直接用FileReadTool -
需要搜索内容 → GlobTool只列文件不搜内容 -
可以用BashTool的grep,但GrepTool更专业
结论:使用GrepTool,pattern=”processRequest”。
这就是description的作用——引导模型做出正确选择。
inputSchema设计的艺术
好的inputSchema不仅要”能用”,还要”好用”。
参数命名清晰:用pattern而不是p,用caseSensitive而不是cs。
提供合理的默认值:让模型可以不填可选参数。
limit: z.number().optional().default(100).describe('最大结果数,默认100')
使用enum限制选择:当参数只有几个固定值时。
order: z.enum(['asc', 'desc']).optional().describe('排序方式')
复杂对象要有描述:嵌套对象的每个字段都要describe。
filter: z.object({type: z.enum(['file', 'directory']).describe('过滤类型'),pattern: z.string().describe('匹配模式'),}).optional().describe('过滤条件')
这对使用Claude Code的启示
理解工具描述,能让你:
理解为什么AI有时候”选错工具”。可能是描述不够清晰,或者场景不够明确。
更好地设计MCP工具。如果你写MCP工具,记住description是给模型看的”指令”。
调试工具调用问题。如果AI总是用错工具,检查description是否准确描述了使用场景。
优化CLAUDE.md中的工具偏好。在CLAUDE.md中说明”我更喜欢用X工具做Y事”,会影响模型的选择。
总结
工具描述不是文档,是指令。好的描述不只告诉模型”这是什么”,更重要的是”什么时候用它”。inputSchema则是参数的”格式要求”,约束模型怎么填。
Claude Code通过动态描述、精心设计的Schema和明确的场景说明,让AI能准确选择和使用工具。这是”活系统”的关键一环——模型不仅是工具的使用者,还是根据描述决定”用什么、怎么用”的决策者。
下一篇,咱们聊聊200K上下文窗口——AI的”记忆宫殿”管理术。
文章写到这儿,希望对你理解工具描述有所帮助。觉得有收获的话,欢迎点赞转发。关注梦兽编程,咱们下篇见。
夜雨聆风