Enabling Adaptive Thinking with thinking: {type: 'adaptive'}
Adaptive thinking lets Claude decide, per request, how much visible reasoning a task actually needs, instead of you guessing a fixed budget up front.
Search across all documentation pages
Adaptive thinking lets Claude decide, per request, how much visible reasoning a task actually needs, instead of you guessing a fixed budget up front.
Extended thinking exposes Claude's reasoning as a separate thinking content block returned alongside the final answer.
Adaptive thinking is the recommended mode for turning this on, because it hands the depth decision to Claude itself.
You enable it with a single thinking parameter on the messages.create call.
Once enabled, your response parsing needs to handle two content block types instead of one, thinking and text.
This page covers the exact config, a complete working example, and the gotchas that come up most often when teams first wire this in.
Quick-reference recipe card - copy-paste ready.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
thinking={"type": "adaptive"},
messages=[{"role": "user", "content": "Design a rollback plan for a failed deploy."}],
)
for block in response.content:
print(block.type)When to reach for this:
effort parameter, which composes with thinking.import anthropic
client = anthropic.Anthropic()
def ask_with_adaptive_thinking(prompt: str) -> dict:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=2048,
thinking={"type": "adaptive"},
messages=[{"role": "user", "content": prompt}],
)
thinking_text = None
answer_text = None
for block in response.content:
if block.type == "thinking":
thinking_text = block.thinking
elif block.type == "text":
answer_text = block.text
return {
"reasoning": thinking_text,
"answer": answer_text,
"stop_reason": response.stop_reason,
}
if __name__ == "__main__":
result = ask_with_adaptive_thinking(
"A service has three replicas. One is failing health checks intermittently. "
"Walk through how you would diagnose the root cause before restarting anything."
)
if result["reasoning"]:
print("--- Reasoning ---")
print(result["reasoning"])
print("--- Answer ---")
print(result["answer"])What this demonstrates:
thinking block from the text block on every call.block.type inside the loop rather than assuming a fixed content shape.reasoning may be None for a prompt that did not need visible reasoning.response.stop_reason alongside the content, useful for detecting truncated responses.thinking parameter accepts a config object; {"type": "adaptive"} is the value this site's examples use throughout.thinking content blocks in response.content, ordered before the corresponding text block.response.content is always a list, even for a single-block reply, so code should iterate rather than index a fixed position.| Block type | Field to read | Present when |
|---|---|---|
thinking | block.thinking (string) | Claude judged the task benefited from visible reasoning |
text | block.text (string) | Always present for a normal completed response |
# Defensive extraction pattern used throughout this section's examples.
def split_content(response):
thinking, text = None, None
for block in response.content:
if block.type == "thinking":
thinking = block.thinking
elif block.type == "text":
text = block.text
return thinking, textTreat block.thinking as optional in every code path. A getattr-style guard or the if block.type == "thinking" check shown above avoids AttributeError when a simple prompt skips reasoning entirely.
response.content[0] is always the text answer. With adaptive thinking on, index 0 may be the thinking block instead. Fix: iterate over response.content and switch on block.type rather than indexing by position.thinking block as an error. Simple prompts often produce no visible reasoning at all, that is adaptive thinking working correctly, not a bug. Fix: guard with is not None checks and only log it as unexpected if the prompt was genuinely complex.max_tokens has to cover thinking plus the answer. A low max_tokens value can truncate the reasoning before the final answer is written. Fix: budget max_tokens generously for tasks you expect to trigger deep reasoning, and check response.stop_reason for "max_tokens".thinking with output_config.effort. Enabling adaptive thinking does not by itself set a reasoning depth ceiling. Fix: pair thinking={"type": "adaptive"} with an explicit output_config={"effort": ...} when you need to control cost, see the effort tuning page.thinking block can be verbose and is meant for debugging or optional disclosure, not as the primary UI response. Fix: show the text block by default, and gate any reasoning display behind an explicit "show reasoning" affordance.thinking blocks as if they were normal assistant text, bloating token usage. Fix: strip or summarize prior thinking blocks before appending them to the next turn's messages list.| Alternative | Use When | Don't Use When |
|---|---|---|
No thinking config at all | Simple, low-latency requests where reasoning depth is irrelevant | The task involves multi-step logic, planning, or debugging |
| Fixed-budget thinking config (non-adaptive, if supported by your SDK version) | You need a hard, predictable reasoning token ceiling regardless of task difficulty | You want Claude to self-calibrate and avoid wasting budget on easy prompts |
Adaptive thinking plus explicit effort level | Production workloads needing both self-calibration and a cost ceiling | You need absolute determinism in reasoning token counts across requests |
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
thinking={"type": "adaptive"},
messages=[{"role": "user", "content": "..."}],
)text block.It can, since visible reasoning consumes additional output tokens when Claude decides a task needs it. Simple prompts add little to no overhead; complex ones may use noticeably more tokens.
No. thinking and effort are independent settings. Adaptive thinking works on its own with default effort; adding an explicit effort level just caps how deep that reasoning is allowed to go.
for block in response.content:
if block.type == "thinking":
print(block.thinking)Generally no. Treat it as debugging or optional-disclosure content, and surface the text block as the primary answer. If you do show reasoning, make it an explicit opt-in UI affordance.
No, except for Claude Fable 5, which runs with always-on adaptive thinking by default. Other models in the lineup require the explicit thinking config to enable it.
Yes. A request can include an image content block and thinking={"type": "adaptive"} in the same call; Claude reasons about the image content just as it would text.
response.stop_reason for "max_tokens" to detect this.max_tokens for prompts likely to trigger deep reasoning.Adaptive thinking is designed to let Claude decide, so it will skip visible reasoning on prompts it judges trivial. If you need guaranteed reasoning output regardless of task difficulty, that is a different, non-adaptive thinking configuration, not covered by this page.
Yes, reasoning tokens and answer tokens both draw from the same output budget set by max_tokens.
Avoid re-sending raw thinking blocks from earlier turns as plain assistant text in your messages history. Strip them out or summarize them so token usage does not balloon across a long conversation.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the official
anthropicPython SDK (latest 0.x release). Model names, SDK versions, and pricing move quickly - verify current specifics at platform.claude.com/docs before relying on them.
Reviewed by Chris St. John·Last updated Jul 16, 2026