先记住这个答案
JSON Schema 能声明工具参数的对象结构、字段类型、必填项、枚举和范围,让模型、客户端和工具服务端围绕同一份契约工作。自然语言描述负责解释字段含义、选择依据和使用场景,两者应相互配合。收到合法 JSON 只说明语法成立,符合 Schema 也只说明声明过的结构约束成立;目标是否存在、调用者能否访问、当前状态能否修改仍需业务校验。即使提供商支持受约束的参数生成,工具服务端也不能因此跳过自己的输入检查。
- 结构规则适合机器检查,字段语义仍需清楚描述
- 合法 JSON、符合 Schema 与允许执行是三个判断
- 服务端按实际支持的 Schema 方言验证输入
哪些错误适合直接用结构规则挡住
如果搜索工具只接受字符串查询和有上限的结果条数,就没有必要让模型从一大段描述里猜数字范围。结构校验可以返回稳定的字段路径与错误类型,便于修正参数,也便于统计是哪一个字段最常出错。
下面把条数限定为整数,并拒绝未知字段。properties 本身不会让字段必填,required 需要明确写出;根对象禁止额外属性也不会自动递归约束所有子对象。契约必须按真实输入结构逐层设计。
{
"type": "object",
"properties": {
"query": { "type": "string", "minLength": 1, "maxLength": 200 },
"limit": { "type": "integer", "minimum": 1, "maximum": 20 }
},
"required": ["query", "limit"],
"additionalProperties": false
}query 不能为空字符串,limit 必须是 1 到 20 之间的整数。Schema 没有声明目录权限,也没有保证查询一定命中;空白字符串是否允许还要通过额外规则或归一化策略处理。
把结构失败和业务失败分开反馈
请求把 limit 写成字符串属于参数类型错误;目录不存在属于资源问题;目录存在但调用者无权访问则属于授权问题。把三者都返回为参数错误,会诱导 Agent 反复改写本来正确的字段,既浪费轮次,也掩盖真正的阻塞原因。
工程上可以给错误返回稳定代码、可公开的字段路径和下一步建议。需要修正输入时允许重新调用;权限不足时应回到已授权范围。不要把内部路径、密钥或完整校验上下文一起回传,也不要让模型通过修改身份字段获得更多权限。
Schema 不是任意实现都完整支持的语言
JSON Schema 有不同版本,模型接口也可能只支持其中一部分关键词。工具发布时应验证实际声明能被当前客户端接受,再用服务端校验器检查正常与错误样本。不要把某个平台接受的结构直接假定为所有平台的共同能力。
描述中的约束若无法用当前支持的关键词表达,应由业务代码落实。修改字段类型或默认语义属于契约变化,需要同步消费者和评估样本。把约束只加在提示词里而不改执行端,会形成看似严格、实际仍可绕开的双重标准。
容易答错的地方
- 模型生成受约束 JSON 后无需服务端校验
- 其他调用入口、版本差异和业务状态变化仍然存在;执行端必须守住自己的输入与授权边界,不能把模型行为当成唯一保障。
- 把所有规则写入 description 就等于严格校验
- 描述不会自动执行整数范围、资源归属或互斥关系检查;能结构化的规则进入 Schema,其余规则需要真实业务代码。
面试官还会怎么问?
为什么不只用 TypeScript 接口?
接口能帮助本地开发者,但编译后通常不会变成运行时检查;工具调用跨越进程和语言边界,需要实际可解析且可执行的输入契约。
校验失败可以自动强制转换吗?
只有契约明确允许且转换没有歧义时才适合;否则把空字符串变成零等行为会悄悄改变用户意图,应返回具体错误让调用方修正。
能把 Schema 当作工具授权清单吗?
不能,字段合法不代表调用主体有权限。授权应结合可信身份和目标资源执行,并且在真正产生副作用前再次确认有效状态。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。