厳格なツール使用:自分自身の呼び出しの拒否をやめる
バックエンドがClaude自身が生成したツール呼び出しを拒否する場合、厳格なツール使用が解決策になります。この動画では、架空のエンジニアリングコンサルティング会社Meridianで1つのツールに対してこの機能をオンにし、同じ100件のリクエストをオンとオフの両方で実行します。
この動画のデモは2026年9月に収録されました。使用したモデルはClaude Haiku 4.5(claude-haiku-4-5)です。新しいモデルでは結果が異なる場合があります。
Claudeは通常ツールのinput_schemaに従いますが、デフォルトではそれを強制する仕組みはありません。そのため、バックエンドがClaudeが行ったツール呼び出しを拒否することがあります。これは、呼び出しの入力に次のいずれかが含まれている場合に起こります。
- 整数
2の代わりに文字列"2" - 必須フィールドの欠落
厳格なツール使用はこれを解決します。strict: trueという1つのフラグだけで、Claudeが書く入力がスキーマと一致するようになります。
Meridianでは、アシスタントがqueue_stamp_requestツールを使って、図面セットを免許を持つエンジニアの押印に回すためのキューに登録します。Meridianのバリデータとは、すべてのツール呼び出しをチェックするコードのことです。厳格モードをオフにすると、100件中79件が拒否されます。バリデータから生成したスキーマで厳格モードをオンにすると、拒否件数はゼロになります。
厳格なツール使用の仕組み
strict: trueを指定すると、APIはまずJSON Schemaを文法(grammar)にコンパイルします。文法とは、入力の各時点でどのトークンが次に来てよいかを示す一連のルールです。 その後、Claudeがツール呼び出しの次のトークンを選ぶたびに、その文法が許すトークンしか選べなくなります。これは文法制約付きサンプリング(新しいタブで開きます)と呼ばれます。

strict: trueを指定すると、スキーマが許すトークンしか選べなくなるため、整数フィールドには整数が入ります。
以下はMeridianのツール定義を短縮したものです。厳格モードにはそのうちの2行、フラグとそのフラグが必要とする設定が必要です。
{
"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と並んでトップレベルに置かれ、スキーマの外にあります。"additionalProperties": falseがその設定です。これは、入力にスキーマが名前を挙げていないフィールドを含められないことを意味し、厳格モードではすべてのオブジェクトに対してこれが必須です。
バリデータからスキーマを構築する
厳格なツール使用は、Claudeが書く入力をスキーマと一致させる仕組みなので、スキーマはバリデータが言っていることと一致している必要があります。スキーマを手書きすると、この2つはずれていきます。すると、ツール呼び出しがスキーマには一致していても拒否されることがあります。 Meridianでは、手書きのスキーマによって免許番号がパターンなしの単純な文字列になっていました。そのため、"PE 46196"はスキーマを通過しましたが、PE-に続く5桁の数字を要求するバリデータでは失敗しました。
ルールはバリデータの中で一度だけ書き、そこからスキーマを生成してください。Pythonではバリデータは通常Pydanticクラスです。TypeScriptでは通常Zodで書かれます。
以下はMeridianのPydanticクラスStampRequestと、それを使うコード、そしてStampRequest.model_json_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()は、Claudeが書いた入力であるcall.inputを、同じクラスに対してチェックします。
厳格モードのオフとオンで実行結果を比較する
Meridianのテストでは、queue_stamp_requestツールを使ってClaude Haiku 4.5に100件の平易な言葉による押印リクエストを送り、StampRequestがすべてのツール呼び出しを検証します。同じ100件のリクエストを2回実行します。まずは手書きのスキーマで厳格モードをオフにして、次に生成したスキーマで厳格モードをオンにして実行します。
下記で両方の実行を再現してみてください。
スキーマのpatternは許される形式を示しており、厳格モードはClaudeにそれを守らせます。
厳格モードは入力の形を制御しますが、リクエストに一度も含まれていない事実を補うことはできません。100件のリクエストのうち28件は免許について一度も言及していません。生成したスキーマでは免許番号にnullを許可しており、その28件すべてがnullとして返ってきました。
厳格なツール使用の限界
2026年10月時点で知っておくべき6つのことを紹介します。
- 保護対象保健情報(PHI)を含めないでください。 コンパイルされたスキーマは、プロンプトやレスポンスと同じPHI保護を受けません。そのため、プロパティ名、
enumの値、constの値、patternの式にPHIを含めないでください。 - 境界値はサポートされていません。 スキーマで
minimum、maximum、minLength、またはmaxLengthを使用しているリクエストは400エラーを返します。境界値はPydanticの@field_validatorのようなバリデータ関数でチェックし、そのフィールドの説明文の中に明記してください。 - 制限はツール全体で積み上がります。 1件のリクエストに含められる厳格なツールは最大20個(新しいタブで開きます)です。それらのツール全体で、任意パラメータは最大24個まで含められます。また、
anyOfまたは型配列(str | Noneのようなnullable可能なフィールドが生成するもの)を使うパラメータは最大16個まで含められます。 - 入力がスキーマに一致しないこともあります。 これは拒否の後や、レスポンスが
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は、拒否の後や打ち切られたレスポンスの後、あるいはenumやconstの文字列の大文字・小文字が変わった場合を除き、ツールの入力をスキーマに一致させます。- Pydanticクラスのようなバリデータからスキーマを生成してください。
- 境界値はスキーマから外し、ツール、任意パラメータ、nullable可能なパラメータはリクエスト全体を通してカウントしてください。