Interleaved Thinking and Tool Use in Claude
9 min read · updated August 11, 2026
Extended thinking normally happens once, at the start of an assistant turn, before Claude has seen any tool results. Interleaved thinking removes that restriction: the model can produce a new thinking block after each tool result comes back, so a later decision can be reasoned about with the earlier answers in hand.
What ordinary tool use cannot do
A standard extended-thinking turn has a fixed shape. Claude thinks, then acts. The thinking block is emitted first, the tool_use block after it, and the turn ends with stop_reason: "tool_use". You run the tool, append a tool_result, and call the API again — and the assistant turn that follows starts with the tool output already in context but with no new reasoning attached to it. The model answers from the result rather than thinking about the result.
That is fine when the tool call is a lookup. It is limiting when the second call depends on how the first one turned out: a search that returns nothing useful and should be re-run with different terms, a database query whose row count decides whether to aggregate or to page, a calculation whose result should be sanity-checked before it is reported. In all three the useful reasoning happens after the tool answers, and there was nowhere to put it.
The beta header
Anthropic ships the behaviour behind a beta header. In the raw HTTP API it is a request header alongside the version header:
POST https://api.anthropic.com/v1/messages
x-api-key: $ANTHROPIC_API_KEY
anthropic-version: 2023-06-01
anthropic-beta: interleaved-thinking-2025-05-14
content-type: application/json
{
"model": "claude-sonnet-4-20250514",
"max_tokens": 8000,
"thinking": { "type": "enabled", "budget_tokens": 4000 },
"tools": [
{
"name": "search_orders",
"description": "Search orders by customer email.",
"input_schema": {
"type": "object",
"properties": { "email": { "type": "string" } },
"required": ["email"]
}
}
],
"messages": [
{ "role": "user", "content": "Did [email protected] order anything in March?" }
]
}In the official SDKs the same thing is passed as a beta rather than hand-written — the Python client takes betas=["interleaved-thinking-2025-05-14"] on client.beta.messages.create, and the TypeScript client takes the equivalent betas array. The dated suffix is part of the value, not documentation: the header is matched literally, so dropping the date makes it an unrecognised beta. The general mechanism, including what happens when a required header is missing, is on beta headers in the Claude API.
Block ordering across a multi-step turn
The observable difference is entirely in the content array. Here is the documented shape of a two-step turn — first response, then the response after the tool result is returned. This is the schema the API is specified to produce, reconstructed from the documentation, not a transcript of a run:
// First assistant turn
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "...", "signature": "EqQBCgIY..." },
{ "type": "tool_use", "id": "toolu_01A...", "name": "search_orders",
"input": { "email": "[email protected]" } }
],
"stop_reason": "tool_use"
}
// You append: { "role": "user", "content": [
// { "type": "tool_result", "tool_use_id": "toolu_01A...", "content": "[]" } ] }
// Second assistant turn — WITH the interleaved beta
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "...", "signature": "EqQBCgIY..." },
{ "type": "tool_use", "id": "toolu_01B...", "name": "search_orders",
"input": { "email": "[email protected]", "include_archived": true } }
],
"stop_reason": "tool_use"
}The second thinking block is the whole feature. Without the beta, the second assistant turn opens with text or tool_use and no reasoning of its own; with it, Claude gets to consider the empty result before deciding what to do next. A turn may also mix a text block in with the tool call, which is normal and explained separately in why Claude returns text and a tool call together.
Thinking blocks must come back intact
Every thinking block carries a signature field: an opaque cryptographic value that lets the API verify the block was produced by the model and not written by the client. When you build the next request, the entire assistant content array — thinking blocks, signatures and all — goes back verbatim, in order, ahead of the tool_result you are adding.
- Do not strip thinking blocks from a turn that is still in progress. On a tool-use turn they are part of the state the model needs to continue coherently.
- Do not edit the text inside one. The signature is over the block; rewriting the reasoning and keeping the signature fails verification.
- Do not reorder. Thinking precedes the tool call it led to, and the API expects that order back.
- Expect
redacted_thinking. If safety systems flag the reasoning, the block arrives asredacted_thinkingwith encrypted contents. It is still passed back unchanged; it is not an error and it is not something to filter out.
When this goes wrong the API tells you, which is a mercy: a request whose thinking blocks have been stripped, truncated or re-serialised comes back as HTTP 400 with an invalid_request_error naming the block index and complaining that the signature could not be verified, rather than quietly producing a worse answer. The usual cause is not malice but a message-history layer that stores conversations as {role, text} pairs and reconstructs the array on the way out. That representation cannot round-trip a thinking block, and it will work perfectly until the first thinking-enabled tool call.
The corollary for storage: persist assistant turns as the raw content array, not as flattened text. If you need a display string, derive it at render time from the text blocks and keep the array as the source of truth. This is the same discipline that text and tool calls in the same turn asks for, and it is easier to adopt once than to retrofit.
The budget is spent across the whole turn
budget_tokens caps thinking, and with interleaving that cap applies across all the thinking blocks in the turn rather than to each one. Four tool calls with a 4,000-token budget do not get 4,000 tokens each. This is also why a turn can run long: thinking tokens are billed as output tokens, and max_tokens has to be large enough to hold the budget plus the visible answer plus every tool-call argument along the way. Setting max_tokens at or below budget_tokens is rejected rather than silently truncated. The allocation rules are covered in budget_tokens and extended thinking.
Two practical consequences follow. First, agent loops that were tuned for non-thinking tool use will show a higher output-token bill per turn once interleaving is on, because reasoning now appears at every step instead of only the first. Second, prompt caching interacts with this: each additional round trip re-sends a longer assistant history, so a cache breakpoint placed before the tool loop pays for itself faster than it did without thinking in the middle.
If the extra reasoning does not change what the model does — and for a straightforward single-lookup tool it often will not — the honest conclusion is to leave the beta off for that route and keep it for the ones where a tool result genuinely changes the plan.
There is one accounting subtlety worth checking against the documentation before you build a cost model. Anthropic treats thinking blocks from earlier, completed assistant turns differently from the ones inside the turn currently in progress: a finished turn’s reasoning does not have to keep being carried forward the way the in-flight tool loop’s does. The practical reading is that interleaving inflates a single multi-step turn rather than inflating a long conversation without limit — but the exact rule is on the extended thinking page, it has been revised, and it is not something to infer from a bill.
Finally, a note on how to tell whether the beta actually took effect, because nothing in the response announces it. Count thinking blocks per assistant turn across a tool loop. Without the beta you will see at most one, in the first turn of the turn sequence; with it you can see one in each. Absence in a single turn is not proof it is off — the model is not obliged to think before every step — so look at the distribution over a handful of multi-step conversations rather than at one response.