Appearance
让模型稳定调用 Tool:Schema、Examples 与 Registry
前置:什么才是好 Tool:Contract、Granularity 与 Naming
核心问题:为什么一个“看起来正确”的 Tool schema 仍可能让模型频繁调错,Schema、Examples 和 Registry 分别解决什么问题?
日期范围可以定义为两个 ISO 字段,而不是一个自由文本 filters 字符串,Runtime 再做 start<=end 的 domain validation。展示 search logs(query, limit=20) 和分页 cursor 的用法,比 description 里堆一段抽象说明更易让模型稳定调用。
Mental Model
Tool 系统把模型的“调用意图”转换为受 schema、权限、deadline 和副作用策略约束的真实执行;ToolResult 再以受控表示回到 Context。
JSON Schema Engineering
Tool schema 应最小化歧义,使用明确类型/枚举/required/description,避免让模型构造深层自由 JSON。Schema 变更还需版本和兼容策略。
Tool Use Examples
Examples 用具体输入输出展示 schema 难以表达的语义,尤其边界值和“不该调用”的情况。但示例不能取代 validation/policy。
Tool Registry
Registry 维护 capability metadata,而不只是 function dict;namespace 支持来源/权限治理,schema/version 应进入 Run Manifest。
全局注册与当前 Run 暴露是两步,注册绝不等于授权。
🔍 源码对照:Discovery 后先形成稳定 Registry,再允许 Call
完整源码与通用分析见 06-03 Tool Metadata / Dynamic Discovery。这里不重复代码;这里关注 Registry:discovery 先建立稳定的 identity 与 metadata,真正执行时仍需要 Registry lookup、schema validation 与 authorization。
源码说明
在 tools/list 路径中,bridge 先取得内部 tool rows,验证必要 identity 字段,再投影 name / description / inputSchema。这说明 Registry 的职责不只是 dict[name] = func:它还承担“哪些定义有资格对外暴露”和“内部结构如何转换为模型/协议 schema”的边界。
工程边界
源码对缺失 schema 使用宽松 object fallback,是案例实现而不是推荐默认值。生产系统更应在注册期尽早拒绝不完整 contract,避免把输入错误拖到执行期。
Shadow Harness 对照
- Registry registration 时做 schema validation,并产生 immutable/versioned ToolSpec。
- Exposure layer 从 Registry 读取只读 snapshot,不直接修改注册表。
验证
向 Registry 注册缺少 required/type 或 incompatible version 的 Tool,验证错误在注册/构建 catalog 阶段暴露,而不是等模型调用后才失败。
一个 Schema 设计差异会怎样改变模型行为
假设要暴露“读取文件”的能力。下面这种接口虽然程序能执行,但对模型并不友好:
json
{"name":"file_op","arguments":{"mode":"r","p":"...","x":true}}模型必须猜 mode/p/x 的含义,也无法从 schema 看出路径是否必填、能不能一次读多个文件。更好的 contract 会把语义直接编码进名称、字段和约束:
json
{
"name": "read_file",
"arguments": {
"path": "src/auth/token.py",
"start_line": 120,
"end_line": 180
}
}Registry 的作用也不只是 dict[name] -> function。它至少要能回答:这个 tool 的稳定 identity 是什么、当前暴露哪个版本、参数如何校验、风险级别是什么、由哪个 executor 执行。 这样 Runtime 才能在执行前确定性地拒绝未知 Tool,而不是把模型输出当作任意函数名去反射调用。
Failure Modes
Tool 名称/Schema 语义重叠导致选择混乱
症状: 多个 Tool 名称接近、参数含糊或 schema 过宽,模型经常选错或构造无效参数。
为什么危险: Tool choice error 增加,Runtime 需要更多 retry,风险 Tool 可能收到错误参数。
处理: 收窄职责、清晰 namespace/description、严格 schema,并用 examples/eval 验证。
Tool Catalog Cache 与真实版本不一致
症状: 远程 MCP/plugin schema 已更新,但 Registry 仍返回旧定义或旧权限元数据。
为什么危险: 模型按旧 schema 调用,甚至复用过期 risk/permission。
处理: catalog cache 绑定 server/catalog/version/TTL,变化时 invalidation;RunManifest 记录实际暴露版本。
如何验证
| Case | 断言 |
|---|---|
| Tool 名称/Schema 语义重叠导致选择混乱 | 建立 expected-tool 数据集,观察 confusion matrix 与 invalid-args rate。 |
| Tool Catalog Cache 与真实版本不一致 | 模拟远端 schema 变更,断言旧 cache 失效后新 Run 使用新定义。 |
关联源码
自测
- 两个 Tool 名称和参数几乎一样,模型经常选错。你会先改 naming、schema 还是 examples?如何用 confusion matrix 验证?
- Registry 中的 schema 已更新,但 Context 里仍暴露旧描述。为什么这会形成比“模型不会调用”更危险的 contract drift?