Lazy loaded image
Agent丨为什么工具描述中“什么时候该用”比“能做什么”更重要?工具描述设计有哪些关键原则?
字数 5496阅读时长 14 分钟
2026-5-19
type
Post
status
Published
date
May 19, 2026
slug
agent44
summary
tags
Agent
category
icon
password

一、核心结论

在 Agent 系统里,工具描述不是写给人看的 API 文档,而是写给模型看的“决策边界”。
传统 API 文档强调“这个函数能做什么”,因为调用者是程序员,程序员会根据业务上下文自己判断是否调用。但 Agent 工具调用的调用者是 LLM,它需要从自然语言任务中判断:
现在需不需要调用工具?
该调用哪个工具?
应该传哪些参数?
工具结果回来后,下一步继续调用工具还是结束?
因此,工具描述中最重要的不是“能做什么”,而是“什么时候该用、什么时候不该用、和哪些工具相比应该优先/避免使用”。
Anthropic 的 Claude 工具定义文档也明确要求工具描述说明工具做什么、何时使用和不使用、参数含义、限制与行为细节,并建议复杂工具至少写 3-4 句话;Claude API 会把这些工具定义构造成特殊 system prompt,让模型基于这些描述决定工具调用。(Claude Platform)

二、为什么“什么时候该用”比“能做什么”更重要?

1. Agent 面临的是“工具选择问题”,不是“函数调用问题”

OpenAI 的 function calling 流程本质上是:请求时给模型一组工具,模型判断是否需要工具并生成 tool call,应用侧执行工具,再把结果返回给模型继续生成最终答案。(OpenAI开发者)
也就是说,模型不是直接执行函数,而是在一堆候选工具中做选择。这个选择过程更像路由:
在这个流程里,“工具描述”影响的是 D、F、G 三个关键节点:是否调用、调用哪个、参数怎么填。
如果工具描述只写:
Search documents.
模型只能知道它“能搜索文档”,但不知道:
是搜索本地知识库,还是搜索网页?
是适合精确文件名,还是适合语义问题?
找不到时是否应该继续 web search?
grep_coderead_fileweb_search 的边界是什么?
这就是为什么很多 Agent 会出现“工具调用幻觉”:不是模型不会调用工具,而是工具边界没有被描述清楚。

2. “能做什么”往往高度重叠,“什么时候用”才提供区分度

在真实 Agent 系统里,工具经常有重叠能力。例如:
工具
都“能做什么”
真正应该区分的“什么时候用”
read_file
读取内容
已知具体文件路径时用
grep_code
查找内容
搜索类名、函数名、关键词时用
glob_files
找文件
不知道路径但知道文件模式时用
rag_search
搜索知识
查询内部文档、历史知识时用
web_search
搜索知识
查询当前事件、外部实时信息时用
task_agent
让子 Agent 工作
多步骤、开放式探索、需要并行调研时用
如果描述只写“读取文件”“搜索代码”“搜索知识”,模型很难知道该选哪个。Anthropic 在高级工具使用文章中提到,工具数量变多时,不仅会产生 token 成本,常见失败还包括工具选择错误和参数错误,尤其是工具名称相似时。(Anthropic)
成熟项目通常会把“什么时候不用”写得非常具体。OpenCode 的 Task 工具描述里不仅说它可以启动子 Agent 处理复杂多步骤任务,还明确写了不该用它的场景:如果只是读取具体文件路径,应使用 Read 或 Glob;如果搜索类定义,应使用 Grep;如果只在 2-3 个文件内找代码,应使用 Read。(GitHub)
这类描述的核心价值不是解释功能,而是帮助模型减少误选。

3. 工具描述其实是 Agent 的“策略层”

MCP 规范中,工具被设计为 model-controlled:模型可以根据上下文和用户提示自动发现并调用工具;但出于安全考虑,应用应让用户看清暴露给 AI 的工具,并在操作时提供确认机制。(Model Context Protocol)
这意味着工具描述承担了三种角色:
第一,它是 capability spec:告诉模型工具能做什么。
第二,它是 routing policy:告诉模型什么时候该选它。
第三,它是 safety hint:告诉系统和用户这个工具是否只读、是否有副作用、是否需要确认。
OpenAI Apps SDK 对 MCP 工具要求标注 readOnlyHintopenWorldHintdestructiveHint 等注解,用来描述工具可能产生的影响,例如是否只读、是否可能写入外部世界、是否有破坏性副作用。(OpenAI开发者)
所以,生产级 Agent 里工具描述不只是“注释”,而是“行为约束”。

三、从成熟项目看工具描述怎么写

1. Claude / Anthropic:工具描述要写成“新员工交接文档”

Anthropic 的工具设计文章提出,工具描述会进入 Agent 上下文,因此会共同影响工具调用行为;写工具描述时应像给团队新人解释工具一样,把专业查询格式、术语、资源关系、输入输出都显式化,并用严格数据模型减少歧义。(Anthropic)
它还强调工具实现和描述应该一起优化:
工具数量过多会增加误选风险;工具返回结果应只包含高信号信息;大结果应支持分页、过滤、截断;错误响应应告诉 Agent 如何修正参数,而不是只返回晦涩错误码。(Anthropic)
这背后的思想是:工具不是越原子越好,而是要让模型“容易选、容易传参、容易从结果继续推理”。

2. OpenCode:在工具描述里直接写 When to use / When NOT to use

OpenCode 的 TodoWrite 工具描述是一个很典型的例子。它不是只说“创建任务列表”,而是明确规定:当任务需要 3 个以上不同步骤、工作非平凡且需要规划、用户提供多个任务、或新指令到来时应主动使用;当任务是单个简单任务、纯信息问答、或任务跟踪没有组织价值时跳过。(GitHub)
这说明成熟 Agent 工具描述会把调用条件写成可判定规则,例如:
3+ distinct steps
non-trivial work
multiple tasks
purely informational
tracking adds no value
这类规则对 LLM 非常友好,因为模型可以把用户请求映射到这些自然语言条件上。
OpenCode 的 websearch 工具描述也明确写了使用场景:用于访问知识截止日期之后的信息、当前事件和近期数据,并要求搜索最新信息时使用当前年份。(GitHub)
这就是“何时使用”的典型设计:它不仅说明“能搜索网页”,还告诉模型“什么时候必须从静态知识切换到动态检索”。

3. OpenClaw:先区分 tool、skill、plugin,再控制模型能看到什么

OpenClaw 文档把工具、技能和插件分得很清楚:tool 是模型可调用的 typed function,用于读取数据、改文件、发消息、调用 provider 或操作外部系统;skill 是加载进 prompt 的指令包,用于提供可复用工作流或约束;plugin 则用于给运行时增加新能力、凭证、生命周期 hooks 或安装包。(OpenClaw)
这对工具描述设计很重要。很多团队会把“工作流说明”也塞进工具描述,导致工具描述越来越长。更合理的做法是:
工具描述负责“能力边界与调用条件”;
Skill 负责“流程、规范、风格、检查清单”;
Plugin 负责“新增能力、凭证、运行时生命周期”。
OpenClaw 还说明,模型只能看到通过 active profile、allow/deny policy、provider restrictions、sandbox state、channel permissions 和 plugin availability 过滤后的工具。(OpenClaw)
也就是说,工具描述不是唯一控制层,还应配合权限策略、沙箱和可见性控制。

四、坏工具描述与好工具描述对比

反例:只写“能做什么”

这个描述的问题是:
没有说明搜索范围:本地知识库、项目文件、网页还是数据库?
没有说明什么时候该用:事实查询、语义检索、精确路径、代码搜索是否都用它?
没有说明什么时候不用:已知文件路径时是否应该直接 read?
没有说明参数策略:query 应该是自然语言、关键词、文件名,还是 SQL-like 表达式?
没有说明结果为空怎么办:换关键词、扩大范围,还是直接告诉用户找不到?

正例:写清“路由边界”

这段描述真正有价值的不是第一句,而是后面的使用条件、排除条件、替代工具和失败恢复策略。

五、工具描述设计的 10 条关键原则

原则 1:先写“用户意图触发器”,再写功能

推荐格式:
当用户想要……时使用
当任务需要……时使用
当信息来源属于……时使用
例如:
Use web_search when the answer depends on current or recently changed public information.
比下面这种更有用:
Search the web.
因为前者告诉模型“何时需要外部实时信息”。

原则 2:必须写 “When NOT to use”

“什么时候不用”比“什么时候用”更能降低误调用。
推荐写法:
Do NOT use this tool when the user provides an exact file path; use read_file.
Do NOT use this tool for current events; use web_search.
Do NOT use this tool for destructive operations unless the user explicitly asks and approval is granted.
OpenCode 的 Task 工具就是这种模式:它明确列出不该用 Task 的场景,并指出替代工具 Read、Glob、Grep。(GitHub)

原则 3:写清和相邻工具的边界

工具描述不能孤立写,要按“工具族”设计。
例如在代码 Agent 里,read_fileglob_filesgrep_codetask_agent 的边界可以这样设计:
工具
使用条件
read_file
已知具体文件路径
glob_files
不知道具体路径,但知道文件模式
grep_code
搜索类名、函数名、字符串、符号
task_agent
多步骤、开放式、需要自主探索
如果不写这种边界,模型会倾向于调用“看起来最强”的工具,比如总是开子 Agent 或总是 web search,导致成本、延迟和错误率上升。

原则 4:参数描述要写“语义”,不是只写类型

坏参数描述:
好参数描述:
Anthropic 的工具设计文章也特别提到,输入参数应避免歧义,例如不要用 user,而应使用更明确的 user_id。(Anthropic)

原则 5:写清数据范围、时效性和可信边界

RAG / 搜索类工具尤其要写清:
数据源是什么
是否包含最新数据
是否包含用户私有数据
是否可能不完整
结果是否需要引用来源
什么时候应切换到 web search
例如:
这可以避免模型把静态知识库当作实时数据库使用。

原则 6:把副作用和权限写进描述,但不要只依赖描述

对于会写文件、发消息、删数据、付款、改配置的工具,要写清:
是否只读
是否会修改外部系统
是否不可逆
是否需要用户确认
是否可以批量操作
是否允许自动重试
OpenAI Apps SDK 要求 MCP 工具提供 impact annotations,例如 readOnlyHintopenWorldHintdestructiveHint,用于描述工具影响范围。(OpenAI开发者)
但要注意:描述和 annotation 只是提示,真正的安全必须由执行层强制。OpenCode 的 write 工具在执行写文件前会走 permission ask,并在写入后触发 LSP diagnostics,把错误信息返回给模型继续修复。(GitHub)

原则 7:工具返回结果也要服务下一步决策

工具描述不能只管调用前,还要约束调用后结果。
Anthropic 建议工具返回高信号信息,避免把大量低层字段塞回上下文;对于大结果,应支持分页、范围选择、过滤、截断,并在截断或错误时给出可操作提示。(Anthropic)
例如搜索工具返回:
比返回一大段无结构文本更利于 Agent 继续规划。

原则 8:为复杂工具提供 examples,但不要用 examples 替代描述

Anthropic 文档明确说,清晰描述最重要;复杂输入、嵌套对象、格式敏感参数可以补充 input_examples。(Claude Platform)
适合加 examples 的场景:
参数很多
有嵌套对象
有日期、金额、时区、过滤表达式
有 mutually exclusive 参数
有复杂枚举组合
但 examples 不能替代规则。模型需要知道为什么这个例子适用,而不是只模仿形状。

原则 9:工具越多,越需要命名空间和动态发现

当工具数量很多时,把所有工具定义一次性塞进上下文会带来 token 成本和选择混乱。Anthropic 的 Tool Search Tool 就是为这个问题设计的:不是预加载所有工具,而是让 Claude 按需搜索工具;其文章提到大规模 MCP 工具定义可能消耗数万到十几万 tokens,而动态工具搜索可以只加载当前任务需要的工具。(Anthropic)
这意味着工具描述还要适合“被搜索”。工具名和描述里要包含可检索关键词:
比下面这种更容易被 Tool Search 命中:

原则 10:用评测驱动工具描述迭代

工具描述不是一次写完的。应把工具调用日志纳入评测:
评测维度
观察问题
工具选择准确率
模型是否选错工具
参数有效率
参数是否缺失、格式错误、语义错误
过度调用率
明明可直接回答却调用工具
漏调用率
需要工具却直接编答案
多步成功率
工具结果回来后是否能继续正确行动
安全拦截率
高风险工具是否正确请求确认
成本/延迟
是否调用过大、过多、过慢工具
一篇 2026 年关于 MCP 工具描述质量的研究指出,MCP Agent 依赖自然语言工具描述来选择工具和传参;如果描述缺陷、过短或误导,模型可能选错工具、传错参数或产生不必要步骤。该研究还发现,在 856 个 MCP 工具描述中,97.1% 至少存在一种“description smell”,常见问题包括缺少使用指南、未说明限制、参数不透明等;增强描述后任务成功率有统计显著提升,但也带来 token 成本权衡。(arXiv)

六、推荐的工具描述模板

生产环境可以把每个工具描述统一成下面结构:

七、一个更完整的工具描述示例:RAG 搜索工具

这个描述覆盖了:
什么时候用:内部文档、PDF、历史决策、会议纪要
什么时候不用:实时信息、精确文件路径、代码符号检索
替代工具:web_searchread_filegrep_code
参数策略:自然语言查询,包含实体和日期
失败恢复:弱结果时改写 query 再试一次
安全属性:只读
可信边界:索引可能过期或不完整
这才是 Agent 真正需要的工具描述。

八、落地建议:把工具描述当成“可测试的 Prompt 接口”

最后可以用一句话总结:
API 文档告诉人“这个函数怎么用”;工具描述告诉模型“什么时候应该选择这个动作”。
在生产级 Agent / RAG / MCP 系统中,工具描述应该像 Prompt 一样被设计、评测、迭代,而不是像普通注释一样随手写。一个成熟工具描述至少要回答:
这个工具解决什么任务?
用户说什么时应该调用?
什么情况下绝对不要调用?
如果不用它,应该用哪个工具?
参数如何从用户意图映射出来?
它是否只读、是否有副作用、是否需要确认?
返回结果如何支持下一步推理?
出错、为空、超时时 Agent 应该怎么恢复?
当这些问题被写清楚后,Agent 的工具调用会从“看起来会用工具”变成“稳定、可控、可评测地调用工具”。这也是 Claude Code、OpenCode、OpenClaw 这类成熟 Agent 系统给我们的核心启发:工具描述不是功能介绍,而是 Agent 行为边界的第一层设计。
回到首页