工具的 schema 和描述怎么设计,模型才能选得准、填得对?
谁在问:有生产经验的面试官必问;工具集上过规模的团队用这题区分「接过 API」和「设计过工具」
口语化问法
- 你们的工具描述怎么写的?有没有什么让模型选得更准的经验?
- 后端已经有一堆 REST 接口了,是不是直接包一层就能当工具用?
- 模型老是选错工具,你会先动哪儿?
考察意图
这题的门槛比看上去高,因为工具设计是提示词工程,不是接口封装。模型能看到的只有工具名、描述、参数 schema——你的实现它一个字都看不见。面试官在验三件事:
- 有没有意识到"选得准"和"填得对"是两类失败。 混着谈的人,通常没做过工具级评测,因为这两类根因和修法完全不同。
- 是不是按后端接口一比一映射。 这是转型工程师最典型的踩法,也是工具集迅速膨胀到失控的起点。
- 改了描述之后怎么证明变好了。 说不出评测方法的,本质是在凭感觉调提示词。
参考答案
60 分答案(及格线)
工具描述就是给模型看的说明书,写法上我遵循几条:
- 名字自解释:
search_orders_by_user好过get_data,避免多个工具名字听起来都像。 - 描述写清三件事:这个工具干什么、什么时候用、什么时候不要用。第三条最容易被忽略,但对减少误选最有效。
- 参数能收窄就收窄:枚举值用 enum 而不是自由字符串;必填字段尽量少;每个参数给格式说明和示例(日期写清
YYYY-MM-DD)。 - 不要求模型知道它不可能知道的东西:内部 uid、数据库主键这种,要么在服务端补,要么先提供一个查询工具。
- 返回值也要设计:只返回模型决策需要的字段,别把数据库行原样吐出去。
出问题时先分清是选错工具还是参数填错,再对症下药。
90 分答案(有生产经验的回答)
在此基础上补五层。
1. 两类失败分开度量,这是分水岭。
| 失败类型 | 典型根因 | 修的地方 |
|---|---|---|
| 选错工具 | 名字含糊、职责重叠、边界没写、工具太多 | 描述的负向边界、合并/拆分工具、按需装载 |
| 参数填错 | 参数描述缺格式、枚举没收窄、上下文里根本没有这个信息、需要模型推断 | 参数 schema、默认值、前置查询工具、工具容错 |
我会各自建一个小评测集(query → 期望工具 / 期望参数),分别报工具选择准确率和参数正确率。不分开量,改一版描述以后根本说不清是哪边好了。
2. 按意图切分工具,不按后端接口切。 一个工具应该对应"用户会单独说出口的一件事"。后端 40 个 REST 接口通常应该收敛成十几个工具:多步固定组合(查用户 → 查该用户订单 → 查订单明细)合并成一个复合工具;参数复杂的接口包一层做默认值和校验;高危写接口干脆不暴露给模型,走确认流。代价要说清楚:复合工具灵活性下降,粒度太粗时模型没法自由组合——所以边界要卡在"稳定复现的组合"上。
3. 工具要"宽进严出"。 入参容错(能接受"上周"就在工具里做时间归一,别指望模型永远给 ISO 格式),出参严格结构化。返回体里我会额外带两样东西:命中数量和是否还有更多(让模型知道要不要翻页);无结果时的下一步提示("未匹配到该型号,可尝试去掉后缀重试或改用模糊搜索工具")——这一条能显著降低模型在空结果上原地打转的概率。
4. 描述是有成本的资产。 工具定义每一轮都随请求重发,描述写得越细固定开销越高,还会挤占上下文。所以细节要分层放:核心边界写进 description,长篇的使用规范挪到手册层。截至 2026-08,Agent Skills 的四级渐进式披露就是干这个的——每个 skill 的"广告"只占约 100 token,模型判断相关后才加载 SKILL.md(控制在 5000 token 以内、约 500 行),需要细节再读 references,要执行才跑 scripts。三段式看它:解决工具/规范膨胀与选择准确率的矛盾;代价是多一跳读取延迟、手册要维护、模型也可能判断失误不去读;不该用在工具只有十几个、或单轮低延迟要求极高的场景,那种情况直接写进描述更省事。
5. 工具清单本身是会变的。 MCP 2026-07-28 规范给 list 结果加了 ttlMs / cacheScope,工具清单可以缓存也可以过期刷新。工程上要注意两件事:一是缓存过期后模型看到的工具集会变,行为可能突变,要有版本记录;二是改工具定义等于改上下文前缀,会击穿 prompt 缓存,成本会短期上涨——所以工具描述应该像代码一样版本化、走 review、批量发布,而不是随手改。
追问链
模型行为不对,怎么判断是选错工具还是参数填错?分别怎么修?
期望trace里看tool_call的名字和参数哪个错。选错多是边界模糊(职责重叠、名字都像)→ 补负向边界、合并改名、减工具数。填错再拆三种:格式类(补示例、工具侧归一)、取值类(enum收窄)、信息缺失类(要user_id但只有手机号),改描述无用,得加前置查询工具信号能把参数错再往下拆一层、指出「信息缺失类改描述无效」→ 真调过;笼统答「把描述写详细点」→ 还没分清问题类别你说描述要写「什么时候不要用」,举个具体例子
期望要给成对的实际写法:search_orders里写明「只返订单级信息,不含明细;问买了什么商品改用search_order_items」。时效互斥:「T+1 离线数据,问『刚刚/今天』改用实时接口」。前置:「先用lookup_user拿user_id,别猜手机号」信号给得出成对的、带互斥指引与时效说明的例子 → 维护过工具集;只复述「要写清楚不要用的场景」这句原则 → 是背来的后端有 40 个 REST 接口,是不是注册 40 个工具就行?
期望不行:①接口按资源切、工具按意图切,粒度不同 ②40 个描述每轮重发,固定 token 开销 ③越多边界越模糊(2026-08 多数模型超 20 个退化,要自测)。收敛:稳定组合合成复合工具、相近的合并带type参数、高危写不暴露、分批装载;过头丧失组合能力,只合并稳定复现的信号同时说出收敛的收益和过度收敛的代价 → 做过取舍;只答「太多了要精简」→ 没落地过你把工具描述改了一版,怎么证明它更好?
期望评测先于修改:标注集(几十到几百条 query → 期望工具 + 期望参数)→ 改前改后各跑,看选择与参数正确率 → 全量回归:改 A 常让 B 被误选 → 有随机性,每条重复几次看分布 → 灰度上线。工具定义在前缀里,改了击穿 prompt 缓存,成本短期跳一下别当 bug信号提到全量回归(防改 A 崩 B)和缓存击穿 → 上过线;答「改完试几条看看感觉」→ 凭手感取消订单这个高危写工具本月误调用 3 次,产品要保自动化率、法务要零误操作,怎么设计?
期望零误操作做不到,描述提示词只降概率 → 目标改成零不可逆损失,四层:①代码判定的前置校验(状态、金额上限、时间窗)②按金额分档:自动/用户确认/人工审核 ③先标「待取消」,N 分钟内可回滚 ④影子模式(只记录不执行)→ 配套:误调进回归集、补负向边界(改用check_cancel_policy)、高危调用告警 → 人工确认覆盖 5% 单量挡住 95% 损失信号把「零误操作」改写成零不可逆损失、给不依赖模型自觉的代码闸、用分档调和两方 → 设计过高危场景;只答「提示词里强调谨慎」→ 没面对过双方施压
评分要点
- 明确「模型只能看见 name / description / 参数 schema」
- 区分「选错工具」和「参数填错」两类失败及各自修法
- 描述包含负向边界(什么时候不要用)与互斥指引
- 参数设计:enum 收窄、格式与示例、必填最小化、不要求模型知道它拿不到的信息
- 工具按意图切分而非按后端接口一比一映射
- 返回值也是设计对象:字段裁剪、结构化、带下一步提示
- 知道工具定义有 token 成本,且改动会击穿 prompt 缓存
- 加分:有工具级评测集,改描述必做回归
- 加分:知道渐进式披露 / Agent Skills 的分层思路及其代价(截至 2026-08)