Claude Agent SDK

Agent SDK

Definition

Anthropic's Python SDK for building agentic applications with Claude. Provides primitives for agentic loop management, subagent orchestration, tool integration, and lifecycle hooks. Imported as `claude_agent_sdk`. Removes the boilerplate of raw-API agentic loops so architects can focus on design rather than plumbing.

Example Usage

`from claude_agent_sdk import Agent, AgentDefinition, Session` — wire a model, system prompt, and tool list into an `AgentDefinition`, attach hooks, and let the SDK drive the agentic loop instead of hand-rolling it.

Why It Matters for the CCA-F Exam

Domain 1 (Agentic Architecture, 27% of the exam) tests SDK primitives, lifecycle hooks, and the boundary between SDK-provided infrastructure and architect-owned design decisions. Expect questions requiring candidates to distinguish what the SDK handles automatically (loop management, tool-result threading, hook dispatch) from what still requires explicit architectural choices (decomposition strategy, context budgets, escalation paths).

In Depth

The Claude Agent SDK is Anthropic's first-party Python library that wraps the raw Messages API with production-grade agentic infrastructure. The key question it answers: what does the SDK actually give you over calling the API yourself?

What the SDK removes

Every raw agentic loop requires the same boilerplate: poll stop_reason, dispatch tool calls, collect results, re-inject them as tool_result blocks, manage tool_use_id matching, retry on transient errors, and loop until end_turn. The SDK handles all of that. The comparison table and code example below show the contrast concretely.

Core imports and AgentDefinition

from claude_agent_sdk import Agent, AgentDefinition, Session
from claude_agent_sdk.hooks import PreToolUseHook, PostToolUseHook, StopHook, SubagentStopHook

An AgentDefinition bundles the model ID, system prompt, and tool list:

defn = AgentDefinition(
    model="claude-opus-4-8",
    system="You are a code reviewer.",
    tools=["read_file", "search_code"],
)

An Agent takes a definition and optional hooks, then exposes .run(). A Session persists conversation state across turns — see the Session page for lifecycle details.

The four hook types

HookFires whenTypical use
PreToolUseBefore any tool executesValidate inputs, enforce least-privilege, block dangerous calls
PostToolUseAfter a tool returnsLog results, rate-limit, transform output
StopAgent reaches end_turnAudit final output, trigger downstream actions
SubagentStopA delegated subagent finishesCollect results, merge state

These hooks are the production differentiator — raw API loops have no hook surface at all.

What the SDK does NOT abstract

The SDK handles infrastructure (loops, hooks, state). Sound multi-agent *design* — decomposition strategy, tool scoping, escalation paths, context window budgets — remains the architect's responsibility. Domain 1 exam questions frequently test this boundary.

How It Compares

CapabilityRaw Messages APIClaude Agent SDK
Agentic loop managementManual (you write the loop)Built-in
stop_reason dispatchManualSDK handles routing
Tool-result threadingManual (match tool_use_id)Handled by SDK
Session persistenceManual (you store/restore messages)SDK-managed via Session
Subagent delegationManual (nested API calls)Task tool built-in
Lifecycle hooksNot availablePreToolUse, PostToolUse, Stop, SubagentStop
Session forkingManual snapshot logicfork_session built-in
Retry on transient errorsManualSDK handles

Example

Side-by-side: the raw Messages API requires manual loop management, stop_reason dispatch, and tool_use_id threading (~25 lines). The Agent SDK collapses that to an AgentDefinition + hooks + Session.run() (~15 lines), with a PreToolUse hook enforcing read-only access for free.

python
import anthropic

# --- RAW API: you own every part of the agentic loop ---
client = anthropic.Anthropic()
messages = []

def raw_loop(user_prompt: str, tools: list) -> str:
    messages.append({"role": "user", "content": user_prompt})
    while True:
        resp = client.messages.create(
            model="claude-opus-4-8", max_tokens=4096,
            tools=tools, messages=messages
        )
        messages.append({"role": "assistant", "content": resp.content})
        if resp.stop_reason == "end_turn":
            return next(b.text for b in resp.content if b.type == "text")
        # Manually dispatch each tool_use block
        tool_results = []
        for block in resp.content:
            if block.type == "tool_use":
                output = dispatch_tool(block.name, block.input)  # your code
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,  # must match exactly
                    "content": output,
                })
        messages.append({"role": "user", "content": tool_results})


# --- AGENT SDK: SDK owns the loop; you write hooks and definitions ---
from claude_agent_sdk import Agent, AgentDefinition, Session
from claude_agent_sdk.hooks import PreToolUseHook

def block_writes(tool_name: str, tool_input: dict) -> dict | None:
    if tool_name in ("write_file", "delete_file"):
        raise PermissionError(f"{tool_name} blocked")
    return None  # proceed unchanged

defn = AgentDefinition(
    model="claude-opus-4-8",
    system="You are a read-only code reviewer.",
    tools=["read_file", "search_code"],
)
agent = Agent(definition=defn, hooks=[PreToolUseHook(block_writes)])

with Session() as session:
    result = agent.run("Review src/auth.py for issues", session=session)
    print(result.final_message)

Frequently Asked Questions

Does the Agent SDK replace the Anthropic Python SDK for non-agentic use cases?

No. The Agent SDK is layered on top of the Anthropic SDK. For simple request-response tasks — summarization, classification, single-turn Q&A — the raw SDK or Messages API is simpler and lighter. Reach for the Agent SDK when you need session persistence, subagent delegation, or lifecycle hooks.

Can I use the Agent SDK with models other than Claude?

The Agent SDK is designed for Claude models. The `AgentDefinition` accepts any current Claude model ID (e.g., `claude-opus-4-8`, `claude-sonnet-4-6`, `claude-haiku-4-5`). Using non-Claude models is not a supported SDK use case.