Extended Thinking, Effort & Multimodal Basics
7 examples to get you started with Extended Thinking, Effort & Multimodal - 5 basic and 2 intermediate.
Search across all documentation pages
7 examples to get you started with Extended Thinking, Effort & Multimodal - 5 basic and 2 intermediate.
pip install anthropic.export ANTHROPIC_API_KEY=sk-ant-....client = anthropic.Anthropic().The starting point before any thinking or effort tuning is applied.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Summarize the tradeoffs of microservices."}],
)
print(response.content[0].text)messages.create sends a single-turn request with no thinking config, so no reasoning block is returned.response.content is a list of content blocks; for a plain text answer it usually holds one text block.Turn on adaptive thinking so Claude decides how much reasoning a task needs.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
thinking={"type": "adaptive"},
messages=[{"role": "user", "content": "Plan a phased database migration."}],
)
for block in response.content:
print(block.type)thinking={"type": "adaptive"} lets Claude choose reasoning depth per request instead of a fixed budget.response.content shows both a thinking block and a text block for a task like this.Related: Enabling Adaptive Thinking with thinking: {type: 'adaptive'} - full walkthrough of this config
Once thinking is enabled, extract the reasoning separately from the final answer.
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
print("Reasoning:", thinking_text)
print("Answer:", answer_text)thinking block and the text block are separate items in the same content list.block.type lets your application log reasoning separately from what the user sees.thinking block, guard with is None checks in real code.Cap reasoning depth and cost with the effort parameter.
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
thinking={"type": "adaptive"},
output_config={"effort": "low"},
messages=[{"role": "user", "content": "Classify this ticket as billing, bug, or feature request."}],
)
print(response.content[-1].text)output_config={"effort": "low"} favors speed and low cost over deep reasoning.thinking config, both can be set together.low effort suits simple, high-volume tasks like classification.Related: Tuning the effort Parameter for Cost and Speed - choosing a level per workload
Ask Claude to look at an image and answer a question about it.
import base64
import anthropic
client = anthropic.Anthropic()
with open("chart.png", "rb") as f:
image_data = base64.standard_b64encode(f.read()).decode("utf-8")
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": image_data,
},
},
{"type": "text", "text": "What trend does this chart show?"},
],
}
],
)
print(response.content[0].text)content becomes a list of typed blocks when a message mixes an image with text.base64.standard_b64encode turns the raw bytes into the string format the API expects.media_type must match the actual file format, mismatches cause request errors.Related: Sending Images for Vision Analysis with Base64 Encoding - deeper walkthrough of vision input
Reason through a question that requires both looking at an image and thinking through the answer.
import base64
import anthropic
client = anthropic.Anthropic()
with open("architecture-diagram.png", "rb") as f:
image_data = base64.standard_b64encode(f.read()).decode("utf-8")
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1500,
thinking={"type": "adaptive"},
output_config={"effort": "high"},
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": image_data,
},
},
{"type": "text", "text": "Identify any single points of failure in this architecture."},
],
}
],
)
for block in response.content:
if block.type == "thinking":
print("Reasoning:", block.thinking[:200], "...")
elif block.type == "text":
print("Answer:", block.text)thinking, output_config, and a multimodal content list work in the same request.high effort is appropriate here because spotting architectural flaws benefits from deeper reasoning.[:200]) is a common pattern when logging long thinking blocks.Write defensive code, since not every response returns visible reasoning.
def extract_answer(response):
thinking = None
answer = None
for block in response.content:
if block.type == "thinking":
thinking = block.thinking
elif block.type == "text":
answer = block.text
return thinking, answer
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=256,
thinking={"type": "adaptive"},
output_config={"effort": "low"},
messages=[{"role": "user", "content": "What is the capital of France?"}],
)
thinking, answer = extract_answer(response)
print("Had reasoning:", thinking is not None)
print("Answer:", answer)low effort often returns no thinking block at all, adaptive thinking skipped it.extract_answer helper keeps every call site from repeating the same loop.thinking is not None before using it avoids AttributeError in production code.Related: Effort Levels and Thinking Display Options Reference - full table of levels and display modes
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 18, 2026