
Let Claude Think Between Tool Calls, Not Just Before: Interleaved Thinking in Your Agent Loop
Chris Harper
3 min read
Aug 15, 2026 · 04:09 UTC
With adaptive thinking on Sonnet 4.6 or Opus 4.6, Claude automatically reasons after each tool result before calling the next one — no prompt engineering required.
Standard tool use has a hidden flaw: Claude thinks once before the first tool call, then chains subsequent calls with no reasoning gap between them. When results are independent (parallel lookups, simple transformations), that's fine. But when each result should reshape the next query — competitive research, multi-source fact-checking, debugging flows where the error output determines which log to pull — you want the model reasoning at every step, not just at the start.
Interleaved thinking adds a reasoning block after each tool_result before the model decides its next action. The loop becomes: think → call tool → receive result → think about result → call next tool → ... On Sonnet 4.6 and Opus 4.6 with adaptive thinking, this is on by default.
import anthropic
client = anthropic.Anthropic()
tools = [
{
"name": "web_search",
"description": "Search the web for current information.",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
}
]
messages = [
{
"role": "user",
"content": "Compare React vs Vue popularity for new projects in 2026: check npm download stats, then cross-verify with recent job listings.",
}
]
while True:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=16000,
thinking={"type": "adaptive"}, # interleaved thinking is automatic on 4.6
tools=tools,
messages=messages,
)
if response.stop_reason == "end_turn":
print(next(b.text for b in response.content if hasattr(b, "text")))
break
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = dispatch_tool(block.name, block.input) # your handler
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
After each tool_result the response will contain a fresh thinking block before the next tool_use. You don't change the loop at all — adaptive thinking handles the interleaving.
On other Claude 4 models (not 4.6), opt in with a beta header:
client.messages.create(
...,
extra_headers={"anthropic-beta": "interleaved-thinking-2025-05-14"},
)
When it makes a real difference:
| Task type | Interleaved thinking benefit |
|---|---|
| Multi-source research (result A informs query B) | High — each result reshapes the next search |
| Sequential debugging (error → log → patch) | High — model reasons whether error narrows the search |
| Parallel independent lookups | Low — results don't depend on each other |
| Single-tool, single-call | None — only one turn |
Why it matters: Better multi-step judgment from the same model, same tokens, with no prompt engineering. The model's adaptive reasoning handles it — you just keep the same tool loop you already have.
Sources: Thinking in tool and multi-turn workflows — platform.claude.com · Extended thinking — platform.claude.com · Build a tool-using agent — platform.claude.com