工具描述:低质量带来的问题与高质量编写方法
一、工具描述为什么是最关键的字段
在整个工具定义中,模型能看到的只有三个信息:name、description、parameters。其中description 是模型判断"要不要用这个工具"的首要依据。
模型的决策过程: 用户输入: "帮我查一下最近有什么科技新闻" │ ▼ 模型扫描可用工具列表: ┌──────────────────────────────────────────────────┐ │ 工具1: search_web "搜索互联网网页" │ │ 工具2: search_news "搜索新闻" │ │ 工具3: search_database "搜索本地数据库" │ │ 工具4: get_weather "查询天气" │ └──────────────────────────────────────────────────┘ │ │ 模型逐一对比 description 与用户意图 │ ▼ "科技新闻" 最匹配 → search_news("搜索新闻") 如果 description 写得不好,这一步就会出错二、低质量描述带来的六大问题
问题一:工具误选(选错工具)
───────────────────────────────────────────────────── 场景: 有两个搜索类工具 工具A: search_web description: "搜索" ← 太模糊 工具B: search_local_docs description: "搜索" ← 也太模糊 用户: "帮我找一下公司内部的报销制度文档" 模型: 两个都叫"搜索" → 随机选了 search_web 实际: 应该选 search_local_docs(本地文档搜索) 结果: 去互联网搜"报销制度",返回无关网页 ─────────────────────────────────────────────────────根因:description 没有区分使用边界,模型无法判断该用哪个。
问题二:过度调用(不该调时调了)
───────────────────────────────────────────────────── 工具: send_email description: "发送邮件" ← 没说适用场景 用户: "帮我写一封给客户的道歉邮件" 模型理解: "写邮件" → 涉及邮件 → 调用 send_email 实际: 用户只是想让你帮忙"写",不是"发" 结果: 邮件被直接发出去了,但用户还没确认内容 ─────────────────────────────────────────────────────根因:description 没有说明适用场景,模型把"提到关键词"等同于"需要调用"。
问题三:漏调(该调时没调)
───────────────────────────────────────────────────── 工具: calculate_tax description: "计算个人所得税" ← 过于狭窄 用户: "帮我算一下这个项目要交多少增值税" 模型理解: 这个工具是算"个人所得税"的 → 增值税不匹配 → 不调用 实际: 这个工具支持所有税种计算,但 description 没写 结果: 模型回答"我无法计算增值税",实际工具完全可用 ─────────────────────────────────────────────────────根因:description 过于狭窄,缩小了模型对工具适用范围的理解。
问题四:参数提取错误
───────────────────────────────────────────────────── 工具: create_event description: "创建日历事件" parameters: start_time: description: "开始时间" ← 没说格式 attendees: description: "参与者" ← 没说是邮箱还是姓名 用户: "帮我创建一个明天下午3点的会议,邀请张三和李四" 模型生成: start_time: "明天下午3点" ← 非标准格式 attendees: ["张三", "李四"] ← 传了姓名而非邮箱 系统执行: 函数报错——start_time 需要 ISO 8601 格式 ─────────────────────────────────────────────────────根因:参数级 description 没有说明格式要求,模型用了自然语言格式。
问题五:多工具场景下的混淆(工具越多越严重)
───────────────────────────────────────────────────── 10个工具,description 都很模糊: 工具1: "查询数据" 工具2: "搜索信息" 工具3: "获取详情" 工具4: "检索记录" 工具5: "查找内容" ... 用户: "帮我看看昨天有多少新注册用户" 模型: 这些工具的 description 几乎一样 → 无法区分 → 随机选一个 → 大概率选错 准确率可能降到 30%-50% ───────────────────────────────────────────────────── 同样10个工具,description 写得好: 工具1: "查询用户增长指标,返回注册数、活跃数等" 工具2: "搜索互联网公开信息,返回网页标题和摘要" 工具3: "获取订单详情,包括商品、金额、状态" 工具4: "检索用户行为日志,支持按时间筛选" 工具5: "全文检索知识库文档,返回匹配段落" ... 模型: "新注册用户" → 精确匹配 工具1 准确率可达 90%-98% ─────────────────────────────────────────────────────问题六:安全风险
───────────────────────────────────────────────────── 工具: delete_file description: "删除文件" ← 没有风险提示和限制说明 用户: "帮我把这些临时文件清理一下" 模型: 调用 delete_file(path="./temp") 实际: 该函数递归删除,可能波及目录下非临时文件 如果 description 写了: "删除指定路径的文件。⚠️ 此操作不可恢复。仅支持删除 /tmp 目录下的文件,不支持删除目录。" 模型会: 更谨慎地构造参数,限制在 /tmp 范围内 ─────────────────────────────────────────────────────三、高质量描述的编写框架
3.1 五要素模型
一个生产级的工具 description 应包含以下五个要素:
┌──────────────────────────────────────────────────────┐ │ │ │ ① 功能说明 — 这个工具做什么 │ │ ② 适用场景 — 什么情况下该用 │ │ ③ 排除场景 — 什么情况下不该用 │ │ ④ 输出概要 — 返回什么 │ │ ⑤ 限制与注意 — 有哪些约束条件 │ │ │ └──────────────────────────────────────────────────────┘3.2 逐要素详解
① 功能说明
写法:一句话说清"这个工具能做什么动作,作用在什么对象上"。
公式: [动词] + [操作对象] + [核心能力] ✅ "查询指定城市的实时天气信息" 动词: 查询 对象: 指定城市的实时天气 能力: 获取信息 ✅ "从业务数据库中查询结构化数据并返回汇总统计结果" 动词: 查询 对象: 业务数据库中的结构化数据 能力: 查询+汇总 ❌ "天气功能" ← 不是句子,没有动作 ❌ "获取数据" ← 过于宽泛,什么数据 ❌ "这个工具可以用来查询天气相关信息等" ← "相关信息等"是模糊表述② 适用场景
写法:列举 2-3 种典型的用户意图模式。
✅ "适用于用户询问某地当前天气、需要获取温度或天气状况的场景" ✅ "适用于: - 查询特定商品的库存数量 - 按条件筛选库存列表 - 检查某商品是否缺货" ❌ "适用于天气场景" ← 太笼统 ❌ "适用于需要天气信息时" ← 循环定义③ 排除场景
写法:明确指出"虽然看起来相关但不该用这个工具"的情况。
✅ "不适用于查询未来几天的天气预报(请使用 get_forecast)" → 指向替代工具,帮模型做正确选择 ✅ "不适用于查询历史天气数据(请使用 get_weather_history)" ✅ "不适用于数学计算(请使用 calculate 工具), 也不适用于本地文档搜索(请使用 search_docs 工具)" ❌ 不写排除场景 ← 模型可能在边界情况下误调 ❌ "不适用于其他用途" ← "其他"是什么?没有信息量④ 输出概要
写法:简述返回的数据结构,帮模型理解"拿到结果后怎么用"。
✅ "返回JSON格式,包含字段:temp(温度)、condition(天气状况)、 wind(风速风向)、humidity(湿度)" ✅ "返回航班列表,每个航班包含航班号、价格、起飞时间、 到达时间。最多返回20条。" ❌ "返回结果" ← 没说返回什么 ❌ "返回天气数据" ← 什么数据?结构是什么⑤ 限制与注意
写法:频率限制、权限要求、风险提示等。
✅ "每次调用消耗1次API配额,每日上限100次" ✅ "此操作不可撤销,调用前应确认用户意图" ✅ "仅支持查询最近90天内的数据,更早的数据请联系管理员" ✅ "收件人数量不超过10个,超出将报错"3.3 完整示例:五要素组装
工具: search_flights description: "搜索航班信息并返回可用航班列表,包括航班号、价格、 起飞时间、到达时间和舱位等级。 〔①功能说明 + ④输出概要〕 适用于用户查询机票价格、比较航班、查找特定航线 可用航班的场景。 〔②适用场景〕 不适用于预订机票(请使用 book_flight)或查询 已有订单状态(请使用 get_order_status)。 〔③排除场景〕 单次查询最多返回20条结果,仅支持查询未来30天 内的航班。日期参数需使用YYYY-MM-DD格式。 〔⑤限制与注意〕"四、参数级描述的编写方法
工具级 description 决定"选不选",参数级 description 决定"怎么填"。
4.1 参数描述的四要素
┌──────────────────────────────────────────────┐ │ │ │ ① 含义 — 这个参数代表什么 │ │ ② 格式 — 值应该是什么形式 │ │ ③ 示例 — 给一个具体例子 │ │ ④ 约束 — 有什么限制条件 │ │ │ └──────────────────────────────────────────────┘4.2 逐类示例
// ──────────── 字符串类型 ────────────// ❌ 差"city":{"type":"string","description":"城市"}// ✅ 好"city":{"type":"string","description":"城市名称,使用中文全称,如'北京市'、'上海市'、'广州市'"// ↑含义 ↑格式 ↑示例}// ──────────── 日期时间类型 ────────────// ❌ 差"start_date":{"type":"string","description":"开始日期"}// ✅ 好"start_date":{"type":"string","format":"date","description":"查询开始日期,格式 YYYY-MM-DD,如 2026-09-01。仅支持查询最近90天内的日期。"// ↑含义 ↑格式 ↑示例 ↑约束}// ──────────── 枚举类型 ────────────// ❌ 差"region":{"type":"string","enum":["north","south","east","west"],"description":"地区"}// ✅ 好"region":{"type":"string","enum":["north","south","east","west"],"description":"地区筛选:north=华北,south=华南,east=华东,west=华西。不传则默认查询全国。"// ↑含义 ↑每个枚举值的语义 ↑默认行为}// ──────────── 数组类型 ────────────// ❌ 差"tags":{"type":"array","items":{"type":"string"},"description":"标签"}// ✅ 好"tags":{"type":"array","items":{"type":"string"},"description":"筛选标签列表,每个标签为字符串。多个标签之间为AND关系(需同时满足)。如 ['urgent', 'bug']。最多5个标签。"// ↑含义 ↑元素说明 ↑逻辑关系 ↑示例 ↑约束}// ──────────── 数值类型 ────────────// ❌ 差"limit":{"type":"integer","description":"数量"}// ✅ 好"limit":{"type":"integer","minimum":1,"maximum":1000,"description":"返回结果的最大条数,默认100,最大1000。值越大响应越慢。"// ↑含义 ↑默认值 ↑约束 ↑注意事项}4.3 参数描述的"陷阱词"清单
这些词没有信息量,模型无法据此正确填参数:
❌ "相关数据" → 什么数据?相关是什么意思? ❌ "必要信息" → 哪些信息是必要的? ❌ "适当值" → 什么范围算适当? ❌ "可选参数" → 可选但没说默认行为是什么 ❌ "其他" → 其他包括什么? ❌ "等" → 等后面还有什么? ❌ "详见文档" → 模型看不到你的文档 ❌ "同上" → 模型不会关联上下文五、多工具场景下的描述设计
5.1 描述差异化原则
当工具数量超过 5 个时,description 之间的区分度比单个 description 的质量更重要。
关键规则: 相似工具的 description 必须有明确的"区分信号词" 一组相似工具的描述设计: 工具A: search_web "搜索互联网公开网页内容,返回网页标题、摘要和链接。 适用于查找公开资讯、技术文档、百科知识。 不适用于搜索公司内部文档或本地数据。" 区分信号: "互联网" "公开" "网页" 工具B: search_internal_docs "搜索公司内部文档库,包括制度文件、项目文档、 会议纪要。适用于查找公司内部资料。 不适用于搜索互联网公开信息。" 区分信号: "公司内部" "文档库" "制度文件" 工具C: search_chat_history "搜索当前用户的历史对话记录,返回之前的问答内容。 适用于查找之前讨论过的话题或结论。 不适用于搜索文档或网页。" 区分信号: "历史对话" "之前讨论" 工具D: search_database "从业务数据库中查询结构化数据,支持按条件筛选 和聚合统计。适用于查询业务指标、统计数据。 不适用于全文搜索或文档检索。" 区分信号: "业务数据库" "结构化数据" "统计"5.2 区分信号词设计
策略: 在 description 开头就给出"身份标签" "搜索互联网网页..." → 身份标签: 互联网 "查询业务数据库..." → 身份标签: 数据库 "检索知识库文档..." → 身份标签: 知识库 "搜索历史对话..." → 身份标签: 历史对话 模型在匹配时,首先抓"身份标签"做粗筛,再做精细匹配5.3 工具数量与准确率的关系
工具选择准确率 100% ┤ │ ● description 写得好的情况 95% ┤ ● ● │ ● ● 90% ┤ ● ● │ 85% ┤ ● │ ● description 写得差的情况 80% ┤ ● │ 75% ┤ │ ● 70% ┤ ● └──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──→ 工具数量 1 3 5 8 10 15 20 30 50 100 关键结论: - 10个工具以内: 好描述和差描述差距约 5-10% - 20个工具: 差距扩大到 15-25% - 50个工具: 差距可达 30%+ - 100个工具: 差描述几乎不可用六、高质量描述的对照案例库
案例一:查询类工具
─────────── 差 ─────────── "name": "query", "description": "查询数据" 问题: 查什么数据?什么场景用?怎么查?全不知道。 ─────────── 好 ─────────── "name": "query_sales_data", "description": "从销售数据库中查询销售数据,支持按时间范围、 地区、产品类别筛选,返回销售额、订单数、客单价等汇总指标。 适用于生成销售报表、分析销售趋势、查看区域业绩。 不适用于查询库存数据(请使用 query_inventory)或 客户信息(请使用 get_customer)。 单次查询时间跨度不超过12个月,超出请分次查询。"案例二:操作类工具
─────────── 差 ─────────── "name": "update", "description": "更新记录" 问题: 更新什么?什么条件才能更新?有什么风险? ─────────── 好 ─────────── "name": "update_order_status", "description": "更新指定订单的状态。仅支持在以下状态间转换: 待付款→已付款、已付款→已发货、已发货→已完成。 不支持回退状态(如已完成→已发货)。 此操作不可撤销,调用前需确认用户已知晓状态变更。 适用于订单履约流程中的状态推进。 如果需要修改订单内容(如商品、收货地址),请使用 update_order_detail。"案例三:通知类工具
─────────── 差 ─────────── "name": "notify", "description": "发送通知" 问题: 通知谁?什么渠道?什么场景? ─────────── 好 ─────────── "name": "send_sms_notification", "description": "向指定手机号发送短信通知。 适用于订单状态变更通知、验证码发送、预约提醒等场景。 不适用于营销推广短信(受法律限制,需使用 send_marketing_sms 并确认用户已同意接收)。 单条短信正文不超过70个字符(含签名),超出将自动拆分 为多条计费。发送频率限制:同一手机号每分钟最多1条、 每小时最多5条。"案例四:分析类工具
─────────── 差 ─────────── "name": "analyze", "description": "分析数据" 问题: 分析什么?怎么分析?返回什么? ─────────── 好 ─────────── "name": "analyze_sentiment", "description": "对给定文本进行情感分析,返回正面、负面、 中性三种情感标签及各自的置信度分数(0-1)。 适用于分析用户评论、客服对话、社交媒体内容的 情感倾向。 不适用于多语言文本(仅支持中文和英文)或 长度超过5000字的文本(请先截断或分段)。 单次分析耗时约1-3秒。"七、描述编写检查清单
7.1 工具级描述检查
□ 是否说明了工具做什么(功能) □ 是否说明了什么情况下用(适用场景) □ 是否说明了什么情况下不用(排除场景) □ 是否指出了替代工具(如有) □ 是否说明了返回什么(输出概要) □ 是否标注了重要限制条件 □ 是否与相似工具有明确区分 □ 长度是否在 30-150 词之间(过短信息不足,过长注意力分散) □ 是否避免了"等""相关""其他"等模糊词7.2 参数级描述检查
□ 是否说明了参数含义 □ 是否说明了值格式(含示例) □ 是否说明了默认值(如为可选参数) □ 是否说明了取值范围或枚举语义 □ 是否说明了与其他参数的依赖关系(如有) □ 是否说明了单位(如为数值类型) □ 是否避免了"适当值""必要信息"等陷阱词7.3 整体一致性检查
□ name 与 description 是否语义一致 □ description 与 parameters 是否对应(没有描述中提到 的参数在 schema 中缺失) □ required 中的参数是否都有 description □ 有 enum 的参数是否在 description 中解释了每个值 □ 相似工具的 description 是否有区分度一句话总结
工具描述是模型选择工具的唯一决策依据——写得差会导致误选、漏选、过度调用、参数错误,工具越多问题越严重。高质量描述的核心是五要素齐全(功能+适用场景+排除场景+输出概要+限制注意),相似工具之间必须有明确的区分信号词,参数级描述必须包含含义、格式、示例和约束。检验标准很简单:把你的 description 拿给一个不了解这个工具的人看,他能否准确判断"什么情况下该用、什么参数怎么填",如果能,模型大概率也能。