Mastering Claude's Capabilities: A Practical Guide to Extended Thinking, Structured Outputs, and Tool Use
Learn how to leverage Claude's advanced features like extended thinking, structured outputs, tool use, and batch processing with practical code examples and best practices.
This guide covers Claude's most powerful API features: extended thinking for complex reasoning, structured outputs for reliable JSON, tool use for external actions, and batch processing for efficiency. You'll get practical code examples and best practices.
Mastering Claude's Capabilities: A Practical Guide to Extended Thinking, Structured Outputs, and Tool Use
Claude's API offers a rich set of features that go far beyond simple text generation. Whether you're building a complex agent, processing large datasets, or need reliable structured outputs, understanding these capabilities is key to unlocking Claude's full potential. This guide walks through the most impactful features with practical code examples and best practices.
Extended Thinking: Let Claude Reason Step-by-Step
Extended thinking allows Claude to "think" before responding, producing a chain-of-thought reasoning process before generating the final answer. This is invaluable for complex tasks like math problems, multi-step analysis, or code generation.
How It Works
When you enable extended thinking, Claude generates an internal reasoning block (the "thinking" content) before producing the visible response. This thinking is not shown to the end user but is available in the API response for debugging or transparency.
Enabling Extended Thinking
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
thinking={
"type": "enabled",
"budget_tokens": 2048 # Reserve tokens for thinking
},
messages=[
{"role": "user", "content": "Solve this step by step: A train leaves station A at 60 mph. Another train leaves station B (200 miles away) at 40 mph heading toward A. When do they meet?"}
]
)
Access the thinking content
for block in response.content:
if block.type == "thinking":
print("Thinking:", block.thinking)
elif block.type == "text":
print("Response:", block.text)
Adaptive Thinking (Beta)
For dynamic control, use adaptive thinking to let Claude decide how much thinking budget to use based on the task complexity:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=8192,
thinking={
"type": "enabled",
"budget_tokens": 4096
},
messages=[
{"role": "user", "content": "Analyze this complex codebase and suggest refactoring opportunities..."}
]
)
Best Practice: Set budget_tokens to about 50-75% of your max_tokens. Claude will use less if the task doesn't require deep reasoning.
Structured Outputs: Get Reliable JSON Every Time
When building applications, you often need Claude to return structured data (JSON, XML, etc.) rather than free-form text. Structured outputs ensure the response follows a strict schema.
Using the text Content Block with JSON Schema
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[
{"role": "user", "content": "Extract the following from this email: sender name, date, subject, and urgency level (low/medium/high). Return as JSON."}
],
system="You are a data extraction assistant. Always respond with valid JSON following this schema: {\"sender\": string, \"date\": string, \"subject\": string, \"urgency\": \"low\" | \"medium\" | \"high\"}"
)
Using Tool Use for Structured Output
A more robust approach is to define a tool that acts as an output schema:
extraction_tool = {
"name": "extract_email_info",
"description": "Extract structured information from an email",
"input_schema": {
"type": "object",
"properties": {
"sender": {"type": "string"},
"date": {"type": "string"},
"subject": {"type": "string"},
"urgency": {"type": "string", "enum": ["low", "medium", "high"]}
},
"required": ["sender", "date", "subject", "urgency"]
}
}
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=[extraction_tool],
tool_choice={"type": "tool", "name": "extract_email_info"},
messages=[
{"role": "user", "content": "From: John Doe\nDate: 2024-01-15\nSubject: Urgent: Server Down\n\nPlease fix the production server ASAP!"}
]
)
Tool Use: Let Claude Interact with the World
Tools (function calling) allow Claude to perform actions like querying databases, calling APIs, or controlling software. This is the foundation for building autonomous agents.
Defining Tools
# Define a weather lookup tool
weather_tool = {
"name": "get_weather",
"description": "Get current weather for a location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name, e.g., 'San Francisco, CA'"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"default": "celsius"
}
},
"required": ["location"]
}
}
Handling Tool Calls
def get_weather(location, units="celsius"):
# Simulate API call
return {"temperature": 22, "conditions": "sunny", "location": location}
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=[weather_tool],
messages=[
{"role": "user", "content": "What's the weather in Tokyo?"}
]
)
Check if Claude wants to use a tool
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
# Execute the tool
if tool_name == "get_weather":
result = get_weather(**tool_input)
# Send result back to Claude
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=[weather_tool],
messages=[
{"role": "user", "content": "What's the weather in Tokyo?"},
{"role": "assistant", "content": response.content},
{"role": "user", "content": [
{
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result)
}
]}
]
)
Parallel Tool Use
Claude can call multiple tools simultaneously for efficiency:
# Claude will call both tools in one response if appropriate
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=[weather_tool, news_tool, calendar_tool],
messages=[
{"role": "user", "content": "What's the weather today and do I have any meetings?"}
]
)
Batch Processing: Handle Large Volumes Efficiently
Batch processing allows you to send multiple requests asynchronously, reducing costs and improving throughput for non-real-time tasks.
Creating a Batch
import anthropic
from anthropic.types import MessageBatchIndividualRequest
client = anthropic.Anthropic()
Prepare batch requests
requests = [
MessageBatchIndividualRequest(
custom_id=f"req-{i}",
params={
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 1024,
"messages": [{"role": "user", "content": f"Summarize: {text}"}]
}
)
for i, text in enumerate(long_texts)
]
Submit batch
batch = client.messages.batches.create(requests=requests)
print(f"Batch ID: {batch.id}")
Retrieving Results
# Check batch status
batch = client.messages.batches.retrieve(batch.id)
print(f"Status: {batch.processing_status}")
When complete, get results
if batch.processing_status == "ended":
for result in client.messages.batches.results(batch.id):
if result.result.type == "succeeded":
print(f"{result.custom_id}: {result.result.message.content[0].text}")
else:
print(f"{result.custom_id}: Error - {result.result.error}")
Best Practices Summary
- Use extended thinking for complex reasoning - Enable it for math, logic, code generation, and analysis tasks
- Leverage structured outputs - Use tool definitions or system prompts with JSON schemas for reliable data extraction
- Design tools with clear descriptions - Good descriptions help Claude choose the right tool and fill parameters correctly
- Handle tool calls asynchronously - Use parallel tool use when tasks are independent
- Batch for throughput - Use batch processing for large-scale offline tasks like data enrichment or classification
Key Takeaways
- Extended thinking dramatically improves Claude's performance on complex reasoning tasks by allowing internal step-by-step analysis before generating the final response.
- Structured outputs via tool definitions or system prompts ensure you get reliable, parseable JSON every time, eliminating the need for regex or post-processing.
- Tool use enables Claude to interact with external systems, databases, and APIs, forming the backbone of autonomous agent architectures.
- Batch processing reduces costs and increases throughput for large-scale, non-real-time workloads by up to 50% compared to individual requests.
- Always set appropriate thinking budgets (50-75% of max_tokens) and test with edge cases to ensure your application handles all possible response types gracefully.