SDK Overview
Why Claude Agent SDK Matters
The Problem: Building agents with Claude requires manually handling tool definitions, response parsing, conversation loops, and streaming -- significant boilerplate for every project.
The Solution: The Claude Agent SDK provides a Python-first framework for building agents with Claude, offering structured tool use, streaming responses, and seamless integration with the Anthropic API.
Real Impact: Teams using the Claude Agent SDK report 60% faster agent development with built-in best practices for safety, structured outputs, and conversation management.
Real-World Analogy
Think of the Claude Agent SDK as a professional kitchen setup:
- Agent = The head chef who coordinates the meal preparation
- Tools = Kitchen appliances (oven, mixer, blender) the chef uses
- Streaming = Watching the chef cook in real-time through an open kitchen
- System Prompt = The recipe and kitchen rules the chef follows
- Tool Results = Ingredients delivered from the pantry when requested
Core SDK Components
Agent Class
The main entry point for creating Claude-powered agents with configurable system prompts, tools, and model parameters.
Tool Definitions
Structured tool schemas using Python dataclasses or Pydantic models that Claude can invoke during conversations.
Streaming Interface
Real-time token-by-token output with event hooks for tool calls, completions, and errors.
Claude Code Integration
Seamless integration with Claude Code for building CLI agents that can read, write, and execute code.
Setting Up
# Install the Claude Agent SDK
pip install claude-agent-sdk
# Set your API key
export ANTHROPIC_API_KEY="your-api-key-here"
# Verify installation
python -c "import claude_agent_sdk; print(claude_agent_sdk.__version__)"
Agent Configuration
import anthropic
from claude_agent_sdk import Agent, tool
# Initialize the client
client = anthropic.Anthropic()
# Define tools using decorators
@tool
def get_weather(city: str, units: str = "celsius") -> str:
"""Get the current weather for a city.
Args:
city: The city name to look up
units: Temperature units (celsius or fahrenheit)
"""
return f"Weather in {city}: 22 {units}, partly cloudy"
@tool
def search_web(query: str) -> str:
"""Search the web for information.
Args:
query: The search query
"""
return f"Search results for: {query}"
# Create the agent
agent = Agent(
client=client,
model="claude-sonnet-4-20250514",
system_prompt="""You are a helpful assistant that can check
weather and search the web. Always be concise.""",
tools=[get_weather, search_web],
max_turns=10,
)
# Run the agent
response = agent.run("What's the weather like in Tokyo?")
print(response)
Tool Use
Tool Definition Best Practices
- Clear Docstrings: Claude uses docstrings to understand when and how to use tools
- Type Hints: Always use Python type hints for parameters -- they become the tool schema
- Default Values: Provide sensible defaults for optional parameters
- Error Handling: Return descriptive error messages so Claude can retry or adjust
- Focused Tools: Each tool should do one thing well rather than being a Swiss army knife
Streaming
# Stream responses in real-time
async def run_streaming():
agent = Agent(
client=client,
model="claude-sonnet-4-20250514",
system_prompt="You are a helpful research assistant.",
tools=[search_web],
)
# Stream with event callbacks
async for event in agent.stream("Research quantum computing advances"):
if event.type == "text":
print(event.text, end="", flush=True)
elif event.type == "tool_call":
print(f"\nCalling tool: {event.tool_name}")
elif event.type == "tool_result":
print(f"\nTool result received")
elif event.type == "complete":
print("\nAgent finished")
Common Pitfall
Problem: Agent makes too many tool calls for simple queries, wasting tokens and time.
Solution: Set max_turns to limit the agent loop. Use clear system prompts that instruct Claude to answer directly when it already has the information, and only use tools when external data is truly needed.
Quick Reference
| Function | Description | Example |
|---|---|---|
Agent() | Create an agent | Agent(client=c, model="...", tools=[...]) |
@tool | Define a tool | @tool def my_func(x: str): ... |
.run() | Run synchronously | result = agent.run("query") |
.stream() | Stream responses | async for event in agent.stream(...): |
max_turns | Limit agent loops | Agent(..., max_turns=10) |
system_prompt | Set agent behavior | Agent(..., system_prompt="...") |
anthropic.Anthropic() | API client | client = anthropic.Anthropic() |