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.
Summary
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.
Recipe
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:
- Multi-step reasoning tasks: planning, debugging, math, logic puzzles.
- Tasks where you want Claude to self-calibrate effort instead of you hardcoding a depth.
- Any workload where you might later want to inspect or log Claude's reasoning path.
- Building toward tuning the
effortparameter, which composes withthinking. - Migrating from a fixed-budget thinking setup to a simpler adaptive one.
Working Example
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:
- A reusable helper function that separates the
thinkingblock from thetextblock on every call. - Checking
block.typeinside the loop rather than assuming a fixed content shape. - Handling the case where
reasoningmay beNonefor a prompt that did not need visible reasoning. - Reading
response.stop_reasonalongside the content, useful for detecting truncated responses. - A prompt genuinely suited to adaptive thinking: multi-step diagnostic reasoning, not a trivial lookup.
Deep Dive
How It Works
- The
thinkingparameter accepts a config object;{"type": "adaptive"}is the value this site's examples use throughout. - With adaptive thinking on, Claude evaluates the incoming request and decides internally how much reasoning to produce before answering.
- The API returns the reasoning as one or more
thinkingcontent blocks inresponse.content, ordered before the correspondingtextblock. response.contentis always a list, even for a single-block reply, so code should iterate rather than index a fixed position.- Claude Fable 5 runs with always-on adaptive thinking by default, reflecting that this mode is treated as the baseline behavior for that model rather than an opt-in extra.
Content Block Shapes
| 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 |
Python Notes
# 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.
Gotchas
- Assuming
response.content[0]is always the text answer. With adaptive thinking on, index0may be thethinkingblock instead. Fix: iterate overresponse.contentand switch onblock.typerather than indexing by position. - Treating a missing
thinkingblock as an error. Simple prompts often produce no visible reasoning at all, that is adaptive thinking working correctly, not a bug. Fix: guard withis not Nonechecks and only log it as unexpected if the prompt was genuinely complex. - Forgetting
max_tokenshas to cover thinking plus the answer. A lowmax_tokensvalue can truncate the reasoning before the final answer is written. Fix: budgetmax_tokensgenerously for tasks you expect to trigger deep reasoning, and checkresponse.stop_reasonfor"max_tokens". - Confusing
thinkingwithoutput_config.effort. Enabling adaptive thinking does not by itself set a reasoning depth ceiling. Fix: pairthinking={"type": "adaptive"}with an explicitoutput_config={"effort": ...}when you need to control cost, see the effort tuning page. - Displaying raw reasoning to end users unfiltered. The
thinkingblock can be verbose and is meant for debugging or optional disclosure, not as the primary UI response. Fix: show thetextblock by default, and gate any reasoning display behind an explicit "show reasoning" affordance. - Re-sending the thinking block back as conversation history unmodified. Some multi-turn flows accidentally include prior
thinkingblocks as if they were normal assistant text, bloating token usage. Fix: strip or summarize priorthinkingblocks before appending them to the next turn'smessageslist.
Alternatives
| 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 |
FAQs
What is the minimal code to turn on adaptive thinking?
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
thinking={"type": "adaptive"},
messages=[{"role": "user", "content": "..."}],
)Why did my response not include a thinking block?
- Adaptive thinking lets Claude decide reasoning is unnecessary for simple prompts.
- A trivial factual question or short lookup often produces only a
textblock. - This is expected behavior, not a misconfiguration.
Does adaptive thinking cost more than a normal request?
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.
Do I need to set the effort parameter to use adaptive thinking?
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.
How do I read the reasoning text out of the response?
for block in response.content:
if block.type == "thinking":
print(block.thinking)Should I show the thinking block directly to end users?
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.
Is adaptive thinking on by default for every model?
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.
Can adaptive thinking be combined with multimodal input?
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.
What happens if max_tokens is too low for the reasoning?
- The response can be truncated mid-reasoning or mid-answer.
- Check
response.stop_reasonfor"max_tokens"to detect this. - Fix by raising
max_tokensfor prompts likely to trigger deep reasoning.
Is there a way to force Claude to always produce a thinking block?
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.
Does the thinking block count toward max_tokens?
Yes, reasoning tokens and answer tokens both draw from the same output budget set by max_tokens.
How do multi-turn conversations handle prior thinking blocks?
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.
Related
- Extended Thinking and the Effort Parameter Explained - the conceptual foundation for this config.
- Extended Thinking, Effort & Multimodal Basics - a broader set of minimal examples covering thinking, effort, and images together.
- Tuning the effort Parameter for Cost and Speed - pair adaptive thinking with an explicit cost ceiling.
- Effort Levels and Thinking Display Options Reference - reference table for display modes that pair with this config.
- Extended Thinking, Effort & Multimodal Best Practices - numbered practices for using this in production.
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.