Controlling Tool Use with tool_choice
Controlling Tool Use with tool_choice
By default Claude decides on its own whether to call a tool. The tool_choice parameter lets you override that decision. There are four options, and knowing exactly what each does — and its side effects — is a frequent exam target.
The four options
tool_choice | Behavior |
|---|---|
{"type": "auto"} | Claude decides whether to call any tool. Default when tools are provided. |
{"type": "any"} | Claude must use one of the provided tools, but may pick which one. |
{"type": "tool", "name": "..."} | Forces a specific named tool every time. |
{"type": "none"} | Prevents any tool use. Default when no tools are provided. |
The critical side effect of any / tool
When tool_choice is any or tool, the API prefills the assistant turn to force a tool call. This means the model will not emit a natural-language preamble or explanation before the tool_use block — even if you explicitly ask it to. If you need the model to "think out loud" and call a particular tool, keep tool_choice: {"type": "auto"} and steer it with an instruction in the user message ("Use the get_weather tool in your response").
When to use which
auto— general agents, exploratory work, anything where the model should reason about whether a tool is even needed. This is the right default for most multi-tool agents.any— you know a tool must run this turn (e.g. a router that must dispatch to some handler) but Claude should choose which.tool(forced) — structured-extraction pipelines where every call must populate one known schema. Combine with strict tools for guaranteed, schema-valid output.none— a turn where you want pure natural language even though tools are defined (e.g. a final summary step).
Interactions to remember
- Extended thinking:
anyandtoolare not supported with extended thinking and return an error. Onlyautoandnoneare compatible. - Prompt caching: changing
tool_choiceinvalidates cached message blocks (tool definitions and system prompt stay cached, but message content is reprocessed). Don't toggle it casually inside a cached loop. - Guaranteed valid calls:
tool_choice: {"type": "any"}+strict: trueon tools guarantees both that a tool is called and that inputs match the schema.
stop_reason
When Claude emits a tool call, the response's stop_reason is "tool_use". Your agent loop runs the tool, appends a tool_result block, and calls the API again. Forcing a tool with any/tool makes "tool_use" the expected stop reason for that turn.
Exam focus
Memorize the four values and their defaults (auto is the default with tools; none without). The highest-yield fact: any and tool suppress the natural-language preamble because the assistant turn is prefilled — so if a scenario needs both reasoning text and a guaranteed tool, the answer is auto + a user-message instruction, not forced tool use.