Claudeのtool_choiceの使い方とauto/any/tool/noneの違い
tool_choiceはauto/any/tool/noneの4種類。any/toolで説明文が消える理由、Opus 5.5・Sonnet 5.5・Fable 5.1・Mythos 5.1で400になる条件、切り分けを解説します。
どの値を選ぶか — 4種類の挙動早見表
Claude APIのtool_choiceは、Claudeがツールを呼ぶかどうか、どのツールを呼ぶかを決めるパラメータです。値はauto・any・tool・noneの4種類で、toolsと組み合わせて初めて意味を持ちます。
| 値 | 挙動 | 既定値になる条件 |
|---|---|---|
auto | 挙動ツールを呼ぶか直接応答するかをClaudeが判断する | 既定値になる条件toolsを指定したとき |
any | 挙動提供したツールのどれかを必ず呼ぶ(どれかは指定しない) | 既定値になる条件— |
tool | 挙動nameで指定した特定のツールを必ず呼ぶ | 既定値になる条件— |
none | 挙動どのツールも呼ばせない | 既定値になる条件toolsを指定しなかったとき |
書式は{"type": "auto"}のようにtypeを渡し、toolのときだけ{"type": "tool", "name": "get_weather"}とnameを足します。
迷いどころはautoとanyの境界です。ツールを使うかどうかが場面で変わるならauto、何かしらのツールを必ず通したいならany、処理がいつも同じツール1本に決まっているならtoolが基本線になります。ただし後半で述べるとおり、anyとtoolは新しいモデルほど使えない組み合わせが増えています。選ぶ前に、使うモデルが強制呼び出しに対応しているかを先に確かめるのが近道です。
anyとtoolで説明文が消える理由と、残したいときの書き方
anyまたはtoolを指定すると、APIはassistantメッセージをプリフィルしてツール呼び出しを強制します。このためClaudeはtool_useブロックの前に自然文を出しません。ユーザーが説明を求めても同じです。
autoでは事情が違います。次の対比のとおり、同じ質問でもレスポンスの形が変わります。
autoと、any・toolの応答の形
auto
textブロック(「天気を確認します」のような一言)が付くことがある。付くかどうかも文言もリクエストごとに変わり得る。
any / tool
プリフィルされるのでtextブロックは付かず、contentはtool_useから始まる。
この差でツール呼び出しの精度が落ちることはない、というのがAnthropicの検証結果です。
説明を画面に出しつつツールを使わせたいときは、tool_choiceをautoのままにして、ユーザーメッセージに指示を書きます。「サンフランシスコの天気は?get_weatherツールを使って回答してください」の形です。autoのまま説明文が残ります。
autoでtextブロックが付いた場合のcontent配列は次の形です。「サンフランシスコの天気と現地時刻を教えて」への例です。
{
"role": "assistant",
"content": [
{ "type": "text", "text": "サンフランシスコの現在の天気と時刻を確認します。" },
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "get_weather",
"input": { "location": "San Francisco, CA" }
}
]
}文言はリクエストごとに変わるので、アプリケーション側は特定の文言に依存せず、他の生成テキストと同じ扱いにします。
症状から選ぶ — 使い分けの判断
実装時に効くのは「その値でアプリが何に困るか」です。場面ごとに、選ぶ値と避ける値を並べます。
場面別の選び方
会話型アシスタント → auto
ツールを使うかどうか自体をClaudeに任せられます。避けたいのは厳密なワークフローです。ツールを呼ばずに終わる応答を想定しておく必要が出ます。
ルーティング処理 → any
複数ツールのどれかは必ず呼びたいが、選択はClaudeに任せる場面です。自然文の説明を出したい対話UIには向きません。
常に同じ処理 → tool
フォームの入力抽出など、毎回同じツールを呼ぶ処理です。指定したツールが必ず呼ばれるので、Claudeにツールの要不要を判断させたい場面とは相性が悪くなります。
1ターンだけ止めたい → none
ツール定義を送ったまま、そのターンだけ呼び出しを止めます。ツールを一切使わないアプリなら、そもそも
toolsを渡さないほうが素直です。
手元で4種類を切り替えて試す
次のリクエストはtoolの例です。tool_choiceの行だけを{"type": "auto"}・{"type": "any"}・{"type": "none"}に差し替えれば、同じ入力で4種類を比べられます。
curl -sS https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5",
"max_tokens": 1024,
"tools": [{
"name": "get_weather",
"description": "指定した場所の現在の天気を取得する",
"input_schema": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"]
}
}],
"tool_choice": {"type": "tool", "name": "get_weather"},
"messages": [{"role": "user", "content": "サンフランシスコの天気は?"}]
}'確認する場所は2つです。1つはcontent配列の先頭ブロックのtypeで、autoならtextかtool_use、anyとtoolならtool_useから始まります。もう1つはstop_reasonで、ツールが呼ばれていればtool_useが入ります。noneではtool_useブロックが出ないので、tool_useが返ったら指定の書式を疑います。最初にautoでcontent配列を見て、そこからany・toolへ切り替えると、textブロックが消える様子を確認できます。モデルIDにclaude-opus-5を使っているのは、このモデルが強制呼び出しに対応しているためです。別のモデルに替えるときは次の節の対応表を先に見てください。
400エラーが出たら — どのモデルが強制呼び出しを拒否するか
tool_choice: {"type": "any"}や{"type": "tool", "name": "..."}を送って400が返るなら、主な原因は次の2系統です(max_tokens: 0の事前ウォームと組み合わせた場合は、後述の「プロンプトキャッシュへの影響」を参照)。
| モデル・設定 | 制約 | 代替手段 |
|---|---|---|
手動の拡張思考(thinking: {"type": "enabled"}) | 制約anyとtoolはエラー | 代替手段autoまたはnone。適応的思考なら強制呼び出しが使える(下記4モデルを除く) |
| Claude Opus 5.5 / Sonnet 5.5 / Fable 5.1 / Mythos 5.1 | 制約anyとtoolは思考設定に関わらず400 | 代替手段auto+strict tool use、または構造化出力 |
2行目の4モデルに、Opus 5.5とSonnet 5.5が含まれる点に注意が必要です。Fable 5.1とMythos 5.1だけが対象と覚えていると、新しいOpus・Sonnetへ切り替えた途端に、動いていた強制呼び出しが400に変わります。一方、同じOpus系でもOpus 5は、適応的思考をオンにした状態で強制呼び出しを使えます。「Opusだから使える」とも「Opus 5.5だから使えない」とも一括りにはできず、モデルごとの確認が要ります。
これらのモデルに送ると、invalid_request_errorの400が返ります。トークンカウントのエンドポイントでも同じエラーになります。つまりモデルを切り替える前に、新しいモデルIDで既存のリクエストを数えさせるだけで、強制呼び出しが残っていないかを検出できます。本文は次のとおりです。
tool_choice: type "tool" and "any" are not supported for this model.エラーの切り分けは次の順で進めます。
forced tool useの400を切り分ける
- 1
モデルIDを確かめる
Opus 5.5・Sonnet 5.5・Fable 5.1・Mythos 5.1のいずれかなら、思考設定を変えても直りません。
any/toolを外します。 - 2
thinkingの設定を見る
上の4モデル以外で400なら、
thinking: {"type": "enabled"}(手動の拡張思考)が残っていないかを確かめます。省略すれば手動の拡張思考は外れ、強制呼び出しが使えます。思考が既定オンのモデルでは、適応的思考で動きます。なおOpus 5のように新しいモデルでは、enabledそのものが別文言の400になります。 - 3
代替を選ぶ
ツール入力の型を保証したいなら
auto+strict: true、結果を固定のJSON形状で受けたいなら構造化出力へ移ります。どちらでもnoneは引き続き使えます。
プロンプト側の指示は、autoでもどのツールが選ばれるかに影響し続けます。強制できなくなった分は、ツールのdescriptionとユーザーメッセージの指示で補えます。noneは4モデルでも使えるので、「このターンは呼ばせない」側の制御は失われません。失われるのは「必ず呼ばせる」側だけです。
実装上の影響は、強制呼び出しの前提でレスポンスを処理している箇所に出ます。anyなら必ずtool_useが返る前提でcontent[0]を読むコードは、autoに替えた時点でテキストだけの応答を受け取りえます。分岐をstop_reasonの値で書き直しておけば、強制の有無に関わらず同じ処理で扱えます。
強制できない分は、ツール定義で選択を寄せる
any/toolが使えないモデルでは、どのツールが選ばれるかをautoの中で寄せることになります。公式のベストプラクティスで、この目的に効く項目は次の4つです。
autoでツール選択を安定させる4つの手
descriptionを厚くする
ツール性能を左右する最大の要素とされています。何をするか、いつ使うか(使わないか)、各パラメータの意味、返さない情報まで書き、1ツールあたり3〜4文以上が目安です。
関連操作を1ツールにまとめる
create_pr・review_pr・merge_prのように分けず、actionパラメータを持つ1ツールに寄せると、選択の曖昧さが減ります。名前に接頭辞を付ける
github_list_prs、slack_send_messageのようにサービス名を前に置きます。ツールが増えるほど効いてきます。理由は「説明」で聞く
呼び出しの理由を聞くパラメータには、推論の逐語ではなく短い説明か根拠を求めます。思考そのものを求める書き方は
reasoning_extractionの拒否につながることがあります。
strict: trueの置き場所も押さえておきます。name・description・input_schemaと同じ階層、つまりツール定義のトップレベルのプロパティです。strict付きのツールでは、tool_useブロックのinputがスキーマに従い、nameも常に有効な名前になります。ただしcomputer useとbrowser useのツールセット(computer_toolset_20260801・browser_toolset_20260801)はstrict: trueを受け付けず、設定したリクエストは拒否されます。
なぜ手動の拡張思考とany/toolは両立しないか
思考がオンの間は、assistantの応答をプリフィルできません。適応的思考でも同じです。一方でanyとtoolは、ツール呼び出しを強制するためにassistantメッセージをプリフィルする仕組みです。そのうえで、強制呼び出しは手動の拡張思考とは両立せず、適応的思考では使えると定められています。
適応的思考なら強制呼び出しは通ります。ただし前節のとおり、4モデルは思考の設定に関わらずあらゆるリクエストで強制呼び出しを拒否します。拡張思考を使っていないのに400になるのは、この4モデルに当たっている可能性が高いと言えます。
auto + strict tool useで入力の型を保証する
強制呼び出しが使えないとき、ツール入力の型を保証する手段がstrict: trueです。ツール定義に付けると、出力トークンのサンプリングをJSON Schemaに適合する範囲へ制約します(grammar-constrained sampling)。tool_choiceとは独立した設定なので、autoのままで使えます。
公式の例は予約システムのpassengers: intです。strictが無いと"2"や"two"が返ることがあり、strict: trueなら常に整数の2になります。保証されるのは型と必須フィールドの有無までで、入った値が正しいか(実在の地名か、ユーザーの意図どおりか)までは保証しません。strict: trueでも防げない挙動はClaude tool useで必須パラメータを省略するとどうなるかで扱っています。
強制呼び出しに対応するモデルなら、anyとstrict tool useの組み合わせが公式の推奨形です。どれかのツールが必ず呼ばれることと、入力がスキーマに従うことを同時に保証できます。
noneでツール定義を残したまま呼び出しだけ止める
noneはtoolsを渡さないときの既定値ですが、toolsを渡したまま明示することもできます。ツール定義はリクエストに残り、呼び出しだけが止まります。
使いどころは2つあります。デバッグで「このターンはツールを使わない応答を見たい」とき。そして、ツール定義をプロンプトキャッシュのプレフィックスに残したまま、一部のターンだけ通常応答にしたいときです。配列ごと削除するより、tool_choiceの値だけを切り替えるほうが実装は単純になります。
強制したツールが失敗したとき、ループはどうなるか
ツールの実行がエラーになったら、結果をis_error: true付きのtool_resultで返します。内容にはエラーメッセージを入れます。入力が不正だったりパラメータが足りなかったりした場合、公式はClaudeが修正して2〜3回再試行してから謝ると説明しています。サーバーツール(ウェブ検索など)のエラーはClaude側で処理されるため、is_errorで返す必要はありません。
強制呼び出しでは、ここに設計上の注意が1つ出ます。anyやtoolは、指定したリクエストごとにツールを呼ばせる設定です。結果を返す2回目以降のリクエストで同じ値を保つと、ツールを呼ぶ応答が続きます。公式に明記はありませんが、定義から推すと、ループが自然には終わらないと考えられます。終了条件を決めておく方法は2つあります。結果を返すターンからautoに切り替えて文章で締めさせる方法と、呼び出し回数の上限をアプリ側で数える方法です。前者はtool_choiceを変えるので、メッセージ側のキャッシュが無効になる点を織り込みます。toolを使う抽出処理のように1回で完結する用途なら、この問題は起きません。
ツール呼び出しはstop_reasonで検出する
Claudeがクライアント側ツールを呼んだレスポンスはstop_reason: "tool_use"を返し、contentにtool_useブロックが入ります。検出は特定のtool_choice値を前提にせず、stop_reasonを見るのが安全です。
autoでは、ツールを呼ばず直接応答してend_turnで終わることがあります。ツールの実行結果はtool_resultブロックを含むユーザーメッセージで返し、会話を続けます。このときtoolsとtool_choiceは前のリクエストと同じ値に保つのが基本です。tool_choiceだけ変えるとメッセージ側のキャッシュが無効になります。
disable_parallel_tool_useはtool_choiceの中に書く
並列ツール呼び出しは既定で有効で、1回の応答で複数のtool_useブロックが返ります。無効にするdisable_parallel_tool_use: trueは、トップレベルのパラメータではなくtool_choiceオブジェクトの中のフィールドです。
tool_choiceのtype | disable_parallel_tool_use: trueの効果 |
|---|---|
auto | disable_parallel_tool_use: trueの効果1回の応答で最大1つのツールだけ呼ぶ。ツールを呼ばず文章で答えることもできる |
any / tool | disable_parallel_tool_use: trueの効果ちょうど1つのツールを呼ぶ |
"tool_choice": {"type": "auto", "disable_parallel_tool_use": true}並列が本当に起きているかは、収集済みのレスポンスから測れます。tool_useブロックを含むメッセージを数え、そこに含まれるtool_useの総数をメッセージ数で割れば、1メッセージあたりの平均呼び出し数が出ます。公式のトラブルシューティングも同じ手順を示しています。disable_parallel_tool_useを入れる前後でこの値を見ると、設定が効いているかを確認できます。なお並列呼び出しは、Claude 4以降のモデルで既定になっています。
書き方はanyやtoolでも同じです。ただしOpus 5.5・Sonnet 5.5・Fable 5.1・Mythos 5.1ではany/tool自体が使えないので、autoと組み合わせる形だけが残ります。
プロンプトキャッシュへの影響
tool_choiceを変えると、キャッシュ済みのメッセージブロックは無効になります。ツール定義とシステムプロンプトのキャッシュは残り、メッセージ本文は再処理の対象です。デバッグでtool_choiceを毎回切り替える運用では、この再処理コストが発生します。キャッシュの事前ウォームに使うmax_tokens: 0のリクエストも、anyやtoolを指定するとinvalid_request_errorで拒否されます。仕組みはPrompt Cachingを理解するにあります。
並列呼び出しが増えない・減ったときの確認点
autoで並列呼び出しが期待より少ないとき、最も多い原因はツール結果の返し方です。1回のassistantターンで複数のtool_useが返ったら、結果はtool_use_idで対応づけ、すべて1つのユーザーメッセージにまとめて返します。結果を別々のユーザーメッセージに分けると、Claudeに並列呼び出しを避けるよう「教える」形になり、以降の並列呼び出しが減ります。
並列呼び出しが減ったときの見直し順
- 1
結果を1つのユーザーメッセージに集める
tool_resultブロックは、メッセージ内のテキストより前に置きます。 - 2
実行しなかった呼び出しにも結果を返す
順番に実行して途中で失敗し、残りを走らせなかった場合も、
is_error: trueと短い理由を付けたtool_resultを返します。 - 3
プロンプトで並列を促す
システムプロンプトで「独立した操作は同時に呼ぶ」と指示します。ユーザーメッセージ側なら、「ParisとLondonの天気を同時に調べて」のように並列を明示します。
どのツールをどの順で実行するかはAPIが決めません。読み取りだけの独立した操作は並列で走らせて待ち時間を縮められます。副作用や順序の制約があるツールは、順番に実行するほうが安全な場合があります。Fable 5.1では、次の読み込みが暗黙のままの長いエージェントループで並列呼び出しが減ることがあると、公式が注記しています。通常のfunction callingには影響しないとされています。
思考と組み合わせるときの注意
適応的思考でツールを使うなら、ツール結果を返すときに、直前のassistantメッセージに含まれるthinkingブロックを改変せず丸ごと戻す必要があります。強制呼び出しの可否とは別の制約で、tool_choiceをautoにしても外れません。ツールを呼んで結果を返し、次の応答が出るまでの一連の流れは、モデルから見ると1つのassistantターンとして数えられます。このため、ツール呼び出しのたびにthinkingブロックを保存しておく処理が、ループの中で欠かせなくなります。思考がオンで既定になっているモデルでも、適応的思考の扱いであれば強制呼び出しは使えます。ただし前節の4モデルは例外です。手動の拡張思考を使うなら、tool_choiceはautoかnoneの2択に絞られます。強制したい場面なら、先に思考の方式を適応的思考へ移す必要があります。
まとめ
強制呼び出しに頼る実装は、モデルを新しい世代へ切り替えた時点で400に変わりえます。モデル更新のたびにany/toolの可否を確かめるか、最初からauto+strict tool useで組んでおくのが安全です。モデル選定はAnthropic API完全ガイドと合わせて確認できます。