严格工具使用:停止拒绝自己的调用
当您的后端拒绝了 Claude 自己生成的工具调用时,严格工具使用就是解决方案。视频中在 Meridian(一家虚构的工程咨询公司)为一个工具启用了该功能,并在启用前后各运行了相同的 100 个请求。
本视频中的演示录制于 2026 年 9 月。它在 Claude Haiku 4.5(claude-haiku-4-5)上运行。在较新的模型上结果可能有所不同。
Claude 通常会遵循工具的 input_schema,但默认情况下没有任何机制强制执行这一点。因此,有时您的后端会拒绝 Claude 发出的工具调用,因为该调用的输入存在以下情况之一:
- 字符串
"2"而不是整数2 - 缺少必填字段
严格工具使用可以解决这个问题。只需一个标志 strict: true,就能让 Claude 写入的输入与您的模式(schema)匹配。
在 Meridian,一个助手使用 queue_stamp_request 工具为持证工程师的图章排队处理图纸集。Meridian 的验证器是检查每个工具调用的代码。在关闭严格模式的情况下,它会拒绝 100 个请求中的 79 个。在开启严格模式且模式(schema)是从验证器生成的情况下,它不会拒绝任何请求。
严格工具使用的工作原理
当设置 strict: true 时,API 首先会将您的 JSON Schema 编译成一个语法(grammar)。语法是一组规则,规定了在输入的每一点上接下来可以出现哪些令牌(token)。 然后,每当 Claude 选取工具调用的下一个令牌时,它只能选取该语法所允许的令牌。这被称为语法约束采样(grammar-constrained sampling)(在新标签页中打开)。

在设置 strict: true 时,只能选取您的模式(schema)所允许的令牌,因此整数字段只能得到一个整数。
这是 Meridian 的工具定义,经过精简。严格模式需要其中两行:该标志,以及该标志所要求的一项设置。
{
"name": "queue_stamp_request",
"description": "Queues a drawing set for a professional engineer's stamp.",
"strict": true,
"input_schema": {
"type": "object",
"properties": {
"drawing_set_id": {"type": "string"},
"revision": {"type": "integer"}
},
"required": ["drawing_set_id", "revision"],
"additionalProperties": false
}
}"strict": true是该标志。它位于顶层,与name、description和input_schema并列,在模式(schema)之外。"additionalProperties": false是该设置。它意味着输入不能携带模式(schema)未指明的字段,而严格模式要求每个对象上都必须有这一设置。
从您的验证器构建模式(schema)
严格工具使用会让 Claude 写入的输入与您的模式(schema)匹配,因此模式(schema)必须与您的验证器所说的一致。当您手写模式(schema)时,两者会逐渐产生分歧。这样一来,一个工具调用可能与模式(schema)匹配,却仍然被拒绝。 在 Meridian,一份手写的模式(schema)将执照编号定义为不带任何模式(pattern)限制的普通字符串。因此 "PE 46196" 通过了模式(schema)检验,却未通过验证器检验,而验证器要求的格式是 PE- 加五位数字。
只在您的验证器中编写一次规则,再由它生成模式(schema)。在 Python 中,验证器通常是一个 Pydantic 类。在 TypeScript 中,通常使用 Zod 编写。
下面是 Meridian 的 Pydantic 类 StampRequest,以及使用它的代码,再之后是 StampRequest.model_json_schema() 返回的模式(schema)。每个 # ... 代表未展示的代码,该模式(schema)仅展示了执照编号部分。
class StampRequest(BaseModel):
model_config = {"extra": "forbid"}
# ...
pe_license_number: str | None = Field(pattern=r"^PE-\d{5}$")
# ...
stamp_tool = {
# ...
"input_schema": StampRequest.model_json_schema(),
"strict": True,
}
stamp_request = StampRequest.model_validate(call.input){
"additionalProperties": false,
"properties": {
"pe_license_number": {
"anyOf": [
{"pattern": "^PE-\\d{5}$", "type": "string"},
{"type": "null"}
],
"title": "Pe License Number"
}
}
}"extra": "forbid"会变成"additionalProperties": false,即严格模式所要求的设置。str | None会变成anyOf,因此执照编号是一个带有该pattern的字符串,或为 null。model_validate()会用同一个类来检查call.input,即 Claude 写入的输入。
比较关闭和开启严格模式的运行结果
Meridian 的测试向 Claude Haiku 4.5 发送 100 个使用 queue_stamp_request 工具的日常语言图章请求,并由 StampRequest 验证每一次工具调用。同样的 100 个请求运行两次:第一次使用手写模式(schema)且关闭严格模式,第二次使用生成的模式(schema)且开启严格模式。
请在下方重放这两次运行。
模式(schema)中的 pattern 规定了允许的格式,而严格模式会让 Claude 遵守它。
严格模式控制的是输入的结构,但无法补充请求中从未给出的事实。在这 100 个请求中,有 28 个从未提到执照信息。生成的模式(schema)允许执照编号为 null,而这 28 个请求返回的结果也确实全部是 null。
严格工具使用的局限性
截至 2026 年 10 月,有六点需要了解:
- 请勿包含受保护的健康信息(PHI)。 编译后的模式(schema)不具备与提示和响应相同的 PHI 保护措施,因此请不要在属性名、
enum值、const值和pattern表达式中包含 PHI。 - 不支持边界限制。 如果请求的模式(schema)中使用了
minimum、maximum、minLength或maxLength,将返回 400 错误。请改用验证函数(例如 Pydantic 的@field_validator)来检查边界,并在字段的描述中说明这些边界。 - 限制会在各工具之间累加。 一个请求最多可以包含 20 个严格工具(在新标签页中打开)。在这些工具之间,最多可以包含 24 个可选参数。它还最多可以包含 16 个使用
anyOf或类型数组的参数,而像str | None这样的可空字段正是生成此类参数的方式。 - 输入仍可能无法匹配模式(schema)。 这种情况会发生在拒绝回答之后、响应因达到
max_tokens而被截断时,或者当enum或const字符串以不同大小写形式返回时。 - 部分模型会拒绝强制工具调用。 将
tool_choice设置为any或tool会强制进行工具调用。这会在 Claude Opus 5.5、Claude Sonnet 5.5、Claude Fable 5.1 和 Claude Mythos 5.1 上返回 400 错误。在这些模型上,请将tool_choice保留为其默认值auto。 - 程序化工具调用无法使用严格工具。 在程序化工具调用中,Claude 编写调用您工具的代码。第 8 课将对此进行讲解。
关键要点
strict: true会让工具输入与您的模式(schema)匹配,但在拒绝回答、响应被截断,或enum/const字符串大小写发生变化等情况下除外。- 从您的验证器(例如 Pydantic 类)生成模式(schema)。
- 不要在模式(schema)中设置边界限制,并在整个请求范围内统计工具数量、可选参数数量和可空参数数量。