19 Building Agents with the Claude Agent SDK
The Claude Code SDK has been renamed to the Claude Agent SDK, reflecting its broader purpose: giving agents not just a code editor, but a complete computer.
19.1 From Code SDK to Agent SDK
When the Claude Code SDK first shipped, it was positioned as a way to programmatically drive Claude Code — to embed the coding assistant’s capabilities inside custom applications. But as developers began using it, a clear pattern emerged: the SDK was being used for far more than coding.
Finance teams built agents that analyzed spreadsheets and generated reports. Operations teams built agents that managed infrastructure. Customer support teams built agents that handled ticket triage. The “Code” in the name had become a constraint on how people thought about the tool.
The rename to Claude Agent SDK reflects reality. The SDK gives an agent “a computer” — files, a shell, network access, tools — and lets you decide what that computer should do. Coding is one use case, but it is no longer the defining one.
19.2 The Agent Loop
At the heart of the SDK is a simple but powerful loop. Every agent, regardless of its purpose, follows the same cycle:
┌─────────────────────────────────┐
│ 1. Gather Context │
│ Read files, query APIs, │
│ search history, inspect state │
└──────────────┬──────────────────┘
│
▼
┌─────────────────────────────────┐
│ 2. Take Action │
│ Run commands, write files, │
│ call APIs, create artifacts │
└──────────────┬──────────────────┘
│
▼
┌─────────────────────────────────┐
│ 3. Verify Work │
│ Check results, run tests, │
│ compare against expectations │
└──────────────┬──────────────────┘
│
▼
Done? ── No ──▶ Back to 1
│
Yes
▼
Complete
This loop — gather context → take action → verify work → repeat — is the fundamental unit of agentic behavior. Understanding it deeply is the key to building effective agents.
19.2.1 Why Verification Matters
The third step is the one that separates reliable agents from unreliable ones. An agent that takes action without verifying is essentially hallucinating its way through a task. An agent that verifies its work — runs the tests, checks the output, confirms the API response — can catch its own mistakes and self-correct.
from claude_agent_sdk import Agent
agent = Agent(
model="claude-sonnet-4-6",
tools=["bash", "file_read", "file_write", "http_request"],
system_prompt="""You are a data pipeline agent.
1. Always verify your work by running tests.
2. If a test fails, fix the issue before proceeding.
3. Never declare success until all tests pass.""",
)
result = agent.run(
"Fetch yesterday's sales data from the API, "
"transform it, and load it into the warehouse."
)19.3 Use Cases
The SDK has been used to build agents across a wide range of domains:
| Domain | Example Agent | Key Tools |
|---|---|---|
| Finance | Expense reconciliation, report generation | http_request, file_read, bash |
| Personal Assistant | Calendar management, email drafting | MCP servers (Gmail, Calendar) |
| Customer Support | Ticket triage, resolution suggestions | http_request, MCP (Zendesk) |
| Deep Research | Literature review, competitive analysis | web_search, file_write |
| DevOps | Infrastructure provisioning, incident response | bash, MCP (AWS, Datadog) |
| Data Engineering | Pipeline monitoring, data quality checks | bash, http_request, sql |
The common thread across all these use cases is that the agent operates on real systems — not just generating text, but taking actions and verifying their effects. This is what makes an agent an agent, rather than a chatbot.
19.4 Key Concepts
19.4.1 Context Engineering via File Structure
The most powerful technique for managing agent context is also the simplest: use the filesystem as your context window. Instead of trying to cram everything into a single prompt, organize information into files that the agent can read on demand.
project/
├── CLAUDE.md # Project-level instructions
├── docs/
│ ├── architecture.md
│ ├── api-spec.yaml
│ └── runbook.md
├── src/
│ ├── CLAUDE.md # Module-specific instructions
│ ├── models/
│ │ └── CLAUDE.md # Sub-module instructions
│ ├── handlers/
│ └── tests/
├── data/
│ └── schemas/
└── .claude/
├── instructions.md
└── preferences.md
The agent reads CLAUDE.md files hierarchically — project-level first, then module-level as it navigates. This means the agent always has the right context for the file it’s working on, without you having to specify it.
<!-- src/models/CLAUDE.md -->
# Models Module
This module contains all data models. Conventions:
- Use Pydantic v2 for all models
- Every model must have a `config` inner class with `frozen = True`
- Validation should happen in validators, not in __init__
- All datetime fields must be timezone-aware (UTC)19.4.2 Subagents for Parallelization and Management
When a task is complex, a single agent context can become overwhelmed. Subagents solve this by spawning focused, independent agents that handle a specific subtask and report back.
from claude_agent_sdk import Agent, Subagent
# Main orchestrator agent
orchestrator = Agent(
model="claude-opus-4-6",
system_prompt="""You are a research orchestrator.
Delegate subtasks to specialized subagents.
Synthesize their findings into a final report.""",
subagents=[
Subagent(
name="data-collector",
description="Fetches and parses raw data from APIs",
model="claude-sonnet-4-6",
tools=["http_request", "file_write"],
),
Subagent(
name="analyst",
description="Performs statistical analysis on data files",
model="claude-opus-4-6",
tools=["bash", "file_read"],
),
Subagent(
name="writer",
description="Writes clear, structured reports",
model="claude-sonnet-4-6",
tools=["file_read", "file_write"],
),
],
)Subagents serve two purposes:
- Parallelization: Multiple subagents can work simultaneously, each in its own context. A code review agent might spawn subagents to review different parts of a PR in parallel.
- Context management: Each subagent has its own context window. The orchestrator only sees the summary results, not the full execution trace. This prevents the main context from filling up with intermediate details.
Use subagents when a task naturally decomposes into independent parts, or when the intermediate work would consume too much context. Avoid subagents for tasks that require tight coupling between steps — the overhead of communication can outweigh the benefits.
19.4.3 Compact for Context Limits
Even with good context engineering, long-running agents eventually approach their context window limit. The compact operation addresses this by summarizing the conversation history while preserving the essential information.
# The agent manages this automatically, but you can
# also trigger it manually or configure thresholds
agent = Agent(
model="claude-sonnet-4-6",
compact_threshold=0.8, # Compact when 80% of context is used
compact_strategy="selective", # Keep recent + important, summarize rest
)The compact operation:
- Identifies the most important messages (recent activity, key decisions, error states).
- Summarizes the rest into a compact representation.
- Replaces the full history with the summary plus the important messages.
- Continues execution with the freed-up context.
The agent is aware that compaction has occurred and can re-read files or re-query APIs if it needs details that were summarized away.
19.4.4 Tools as Primary Building Blocks
In the Agent SDK, tools are the primary building blocks of agent capability. The model’s intelligence is constant; what changes between agents is the set of tools they have access to.
agent = Agent(
model="claude-sonnet-4-6",
tools=[
# Built-in tools
"bash", # Execute shell commands
"file_read", # Read files
"file_write", # Write files
"file_edit", # Surgical file edits
"web_search", # Search the web
"http_request", # Make HTTP requests
# Custom tools
query_database,
send_email,
create_jira_ticket,
],
)Custom tools are just Python functions with type hints:
from claude_agent_sdk import tool
@tool
def query_database(sql: str, database: str = "production") -> str:
"""Execute a read-only SQL query against the specified database.
Args:
sql: The SQL query to execute. Must be a SELECT statement.
database: The database to query. Defaults to production.
Returns:
The query results as a formatted string.
"""
# Implementation here
result = db.execute(sql, database=database)
return format_result(result)The SDK automatically generates the tool schema from the function signature and docstring. The model sees the tool’s name, description, parameters, and return type — everything it needs to decide when and how to use it.
19.4.5 MCP for Integrations
The Model Context Protocol (MCP) is the standard way to connect agents to external systems. MCP servers expose tools, resources, and prompts through a unified protocol. The Agent SDK includes a built-in MCP client that can connect to any MCP server.
agent = Agent(
model="claude-sonnet-4-6",
mcp_servers=[
{"name": "github", "command": "mcp-server-github"},
{"name": "slack", "command": "mcp-server-slack"},
{"name": "postgres", "command": "mcp-server-postgres",
"args": ["--connection-string", DATABASE_URL]},
],
)MCP servers can be:
- Local processes running on the same machine as the agent
- Remote services accessed over HTTP or SSE
- Docker containers spun up on demand
The key benefit of MCP is portability. An MCP server written for one agent framework works with any other. Tools, once built, can be shared across the entire ecosystem.
19.4.6 Verification Loops
The most effective agents don’t just act — they verify. A verification loop is a pattern where, after taking an action, the agent checks whether the action had the intended effect before proceeding.
agent = Agent(
model="claude-opus-4-6",
system_prompt="""You are a deployment agent. After every action:
1. Run the test suite.
2. Check the health endpoint.
3. Verify the deployment status.
If any check fails, roll back and diagnose the issue.
Do not report success until all checks pass.""",
tools=["bash", "http_request", "file_read"],
verification_tools=["bash", "http_request"],
)Common verification patterns:
| Pattern | How It Works | Example |
|---|---|---|
| Run tests | Execute test suite after code changes | pytest tests/ |
| Check API responses | Verify HTTP status and response body | curl localhost:8080/health |
| Diff inspection | Review what changed before committing | git diff --staged |
| Lint and type-check | Catch style and type errors | ruff check . && mypy . |
| Log analysis | Check application logs for errors | tail -100 app.log \| grep ERROR |
19.5 Building a Complete Agent
Here is a complete example — a customer support agent that triages incoming tickets, attempts resolution, and escalates when needed:
from claude_agent_sdk import Agent, tool
import httpx
@tool
def fetch_tickets(status: str = "open") -> list[dict]:
"""Fetch support tickets by status."""
resp = httpx.get(f"https://api.helpdesk.io/tickets?status={status}")
return resp.json()["tickets"]
@tool
def search_knowledge_base(query: str) -> str:
"""Search the internal knowledge base for solutions."""
resp = httpx.post("https://kb.internal/search", json={"q": query})
return resp.json()["answer"]
@tool
def resolve_ticket(ticket_id: str, resolution: str) -> bool:
"""Mark a ticket as resolved with the given resolution note."""
resp = httpx.post(
f"https://api.helpdesk.io/tickets/{ticket_id}/resolve",
json={"resolution": resolution},
)
return resp.status_code == 200
agent = Agent(
model="claude-sonnet-4-6",
system_prompt="""You are a customer support agent.
1. Fetch open tickets.
2. For each ticket, search the knowledge base for a solution.
3. If a solution is found, resolve the ticket.
4. If no solution is found, escalate to a human.
Always verify that the resolution was accepted before moving on.""",
tools=[fetch_tickets, search_knowledge_base, resolve_ticket, "bash"],
mcp_servers=[{"name": "slack", "command": "mcp-server-slack"}],
)
agent.run("Process today's support tickets.")19.5.1 Loop Variations for Different Workloads
The basic loop adapts to different workload types. Here are common variations:
The Research Loop — used by deep research agents that gather and synthesize information:
research_agent = Agent(
model="claude-opus-4-6",
system_prompt="""You are a research agent.
Loop:
1. Identify what you still need to know
2. Search for information (web, documents, databases)
3. Read and extract relevant findings
4. Cross-reference against existing findings
5. Identify gaps and contradictions
Continue until you have a comprehensive, well-sourced answer.""",
tools=["web_search", "file_read", "file_write"],
)The Monitoring Loop — used by agents that watch systems and respond to changes:
monitor_agent = Agent(
model="claude-sonnet-4-6",
system_prompt="""You are an infrastructure monitor.
Loop:
1. Check system metrics (CPU, memory, latency, errors)
2. Compare against thresholds and baselines
3. If anomaly detected: investigate, diagnose, respond
4. Log all actions and decisions
5. Wait for next check interval
Never auto-remediate critical systems without approval.""",
tools=["bash", "http_request"],
)The verification step in each variation looks different — a research agent verifies by cross-referencing sources; a monitor verifies by confirming the anomaly is resolved — but the structural pattern is the same.
19.6 Key Takeaways
- The Claude Code SDK is now the Claude Agent SDK, reflecting its broader purpose of giving agents a complete computer, not just a code editor.
- Every agent follows the same loop: gather context → take action → verify work → repeat. The verification step is what separates reliable agents from unreliable ones.
- Context engineering via file structure is the most powerful technique for managing agent context — use
CLAUDE.mdfiles hierarchically. - Subagents enable parallelization and context management by spawning focused, independent agents for subtasks.
- Compact summarizes conversation history to free up context without losing essential information.
- Tools are the primary building blocks — the model’s intelligence is constant; tools define what the agent can actually do.
- MCP servers provide a portable, standardized way to connect agents to external systems.
- Verification loops — running tests, checking outputs, inspecting diffs — are essential for building agents that work reliably in production.