← Agent Frameworks 🕐 13 min read
Agent Frameworks

Anthropic Claude Agent SDK — Enterprise Patterns & Architecture Reference

> **Source credibility: HIGH (SDK mechanics) / MEDIUM (market positioning)** — SDK behavior, architecture, and API surface sourced directly from Anthropic's official GitHub repositories: `anthropics/c

See also (wiki): wiki/enterprise-agent-runtime-infrastructure.md · wiki/assistive-to-agentic-shift.md · wiki/agentic-ai-governance.md · wiki/workflow-redesign.md

Source credibility: HIGH (SDK mechanics) / MEDIUM (market positioning) — SDK behavior, architecture, and API surface sourced directly from Anthropic’s official GitHub repositories: anthropics/claude-agent-sdk-python, anthropics/claude-agent-sdk-demos, anthropics/agent-sdk-workshop, and anthropics/claude-cookbooks. Enterprise adoption claims are vendor-published and represent selected wins with no control group and no independent verification. Cross-reference against: METR RCT (experienced developers 19% slower), CMU study (40.7% code complexity increase), Atlan 200-deployment analysis (median +159.8% ROI requires workflow redesign first).

TIER 1 — May 2026; SDK sourced from live Anthropic GitHub repositories.


1. What the Agent SDK Is vs. the Raw API

The Claude Agent SDK (pip install claude-agent-sdk) is not a wrapper around the Anthropic REST API. It is a managed runtime that embeds the Claude Code CLI and orchestrates the full agent loop — tool execution, permission gating, lifecycle hooks, and multi-turn conversation state — as a Python (or TypeScript) process rather than a prompt-response cycle.

Raw API: The developer manages the tool loop manually. Each model response must be parsed, tool calls extracted, executed, and fed back as user messages. State tracking, error recovery, and permission enforcement are the developer’s responsibility.

Agent SDK: The SDK owns the loop. The developer declares tools, agents, hooks, and permissions; the SDK handles invocation order, context threading, and turn management. The model sees a coherent conversation; the developer sees a stream of typed message objects.

The practical consequence for enterprise teams: the SDK reduces “make Claude use a tool” from ~200 lines of loop management code to a single @tool decorator and a configuration object. The engineering effort shifts from loop mechanics to tool design, permission policy, and system prompt quality.

Version note: As of May 2026, versions ≥0.1.0 renamed ClaudeCodeOptionsClaudeAgentOptions. The package was rebranded from “Claude Code SDK” to “Claude Agent SDK” to reflect its scope beyond coding tasks.


2. Core Architectural Primitives

query() — Stateless Single-Turn

The simplest entry point. An async generator that accepts a prompt and returns an AsyncIterator of response messages. No session state is retained between calls.

async for message in query(prompt="Summarize Q1 results", options=options):
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, TextBlock):
                print(block.text)

Use case: single-turn automation tasks where a fresh context is correct behavior (batch document processing, one-shot classification, scheduled report generation).

ClaudeSDKClient — Stateful Multi-Turn with Bidirectional Control

The ClaudeSDKClient context manager supports interactive, multi-turn sessions. Unlike query(), it also enables two capabilities that query() does not support: custom tools and hooks.

async with ClaudeSDKClient(options=options) as client:
    await client.query("Draft a board memo on the Q1 results")
    async for message in client.receive_response():
        # handle typed message stream
    await client.query("Add a risk section")
    async for message in client.receive_response():
        ...

Tools — In-Process MCP Servers

Tools are Python functions decorated with @tool and bundled into an in-process MCP server via create_sdk_mcp_server. The SDK exposes them to the model under the naming convention mcp__<server_key>__<tool_name>.

@tool("get_account_health", "Retrieve health metrics for a named account", {"account_id": str})
async def get_account_health(args: dict) -> dict:
    data = load_account_data(args["account_id"])
    return {"content": [{"type": "text", "text": json.dumps(data)}]}

server = create_sdk_mcp_server(name="crm", tools=[get_account_health])
options = ClaudeAgentOptions(
    mcp_servers={"crm": server},
    allowed_tools=["mcp__crm__get_account_health"]
)

In-process vs. external MCP: External MCP servers run as separate subprocesses and communicate via stdio IPC. In-process SDK servers run in the same Python process — no subprocess management, no IPC overhead, easier debugging, simpler deployment. For production enterprise agents, in-process is the default choice unless the tool must be shared across multiple agent processes independently.

Mixed configurations are supported: an agent can simultaneously use in-process SDK servers (for proprietary business logic) and external MCP servers (for vendor-provided tool suites).

Subagents — Isolated Parallel Workers

A AgentDefinition declares a named worker agent. The orchestrating (lead) agent invokes workers via the Task tool. Each subagent runs in an isolated context window — it has its own conversation history and tool permissions, and its outputs are returned to the lead agent as task results.

from claude_agent_sdk import AgentDefinition

researcher = AgentDefinition(
    description="Search the web and compile research notes on a given subtopic",
    prompt="You are a research analyst. Given a research question, use WebSearch to find 3-5 authoritative sources. Write structured findings to a markdown file.",
    tools=["mcp__research__web_search", "Write"],
    model="haiku",  # cost-optimize subagent tasks
)

options = ClaudeAgentOptions(
    agents={"researcher": researcher},
    allowed_tools=["Task", "mcp__crm__get_account_health"],
)

The lead agent calls Task(agent="researcher", prompt="Research competitive positioning for ACME Corp") and receives results when the subagent completes. Multiple subagents can run in parallel when the orchestrator spawns independent Task calls concurrently.

Model routing within agent networks: Subagents can be assigned a different model than the orchestrator. The pattern used in the workshop: orchestrator on claude-sonnet-4-6, specialized workers on haiku. This reduces per-task cost on well-defined subtasks while retaining full reasoning capacity at the coordination layer.

Hooks — Deterministic Lifecycle Interception

Hooks are Python functions the SDK runtime (not the model) invokes at fixed lifecycle points. The model has no awareness of hooks; they are the application’s control plane.

Four hook events:

Event Fires When Enterprise Use
UserPromptSubmit User message about to reach model Inject compliance context, add audit metadata, enforce prompt policies
PreToolUse Before a tool executes Block dangerous operations, validate inputs, require HITL approval
PostToolUse After a tool returns Transform results, log to SIEM, enforce output policies
Stop Agent turn completes Metrics collection, session cleanup, trigger downstream workflows

Example: a PreToolUse hook that blocks shell commands matching a denylist pattern:

async def enforce_bash_policy(input_data, tool_use_id, context):
    if input_data["tool_name"] != "Bash":
        return {}
    command = input_data["tool_input"].get("command", "")
    for banned in BANNED_PATTERNS:
        if banned in command:
            return {
                "hookSpecificOutput": {
                    "hookEventName": "PreToolUse",
                    "permissionDecision": "deny",
                    "permissionDecisionReason": f"Pattern '{banned}' blocked by policy",
                }
            }
    return {}

Hooks are the correct mechanism for HITL checkpoints: a PreToolUse hook can pause execution, surface the proposed action to a human reviewer, and return allow or deny based on their response.

Permission Model

The SDK evaluates tool permissions via a layered decision tree:

  1. disallowed_tools — always blocked, evaluated first
  2. allowed_tools — auto-approved without prompting
  3. permission_mode — default behavior for tools not in either list
  4. can_use_tool — a Python callback for dynamic per-call decisions
  5. Hook PreToolUse — final interception layer

permission_mode options: 'default' (prompt user), 'acceptEdits' (auto-approve file changes, prompt for shell), 'bypassPermissions' (auto-approve all — use only in sandboxed environments).


3. Enterprise Patterns from the Demos

Pattern A: Hierarchical Multi-Agent Research (research-agent demo)

Architecture: A lead agent decomposes a research request into 2–4 subtopics and spawns parallel specialized subagents.

Three subagent roles:

  • Researcher Agent — uses WebSearch + Write; stores findings as markdown files in research_notes/
  • Data Analyst Agent — uses Glob, Read, Bash, Write; extracts metrics and generates PNG charts in charts/
  • Report Writer Agent — uses Skill, Write, Glob, Read, Bash; synthesizes everything into a final PDF

Observability mechanism: SDK hooks intercept all tool calls via pre_tool_use and post_tool_use handlers. A parent_tool_use_id field links each tool call to its originating subagent — so when the Lead Agent spawns Researcher via Task (receiving ID task_123), every subsequent tool call from that researcher instance carries task_123 as its parent. The system emits both human-readable transcripts and structured tool_calls.jsonl.

Enterprise translation: This is the pattern for any multi-domain research workflow — competitive intelligence, due diligence, regulatory landscape mapping. The key design decision is that subtask decomposition happens at runtime, not at design time. The lead agent decides how to divide the problem; the developer provides the specialist capabilities.

Pattern B: Interactive Plan-Then-Act with HITL Preview (ask-user-question-previews demo)

Architecture: The agent enters “plan mode” before executing irreversible actions. It generates structured questions rendered as visual HTML preview cards (not plain text options) and presents them to a human via WebSocket before proceeding.

The SDK mechanism: previewFormat: "html" on AskUserQuestion tool calls, combined with a canUseTool callback in the ClaudeSDKClient configuration that intercepts question blocks and routes them to a browser-based approval UI.

Enterprise translation: The correct architecture for agents with write access to production systems — CRM updates, contract generation, procurement requests. The agent proposes; a human approves; the agent executes. The WebSocket transport makes this viable for async review workflows where the approver is not co-located with the running agent.

Pattern C: Email Agent with IMAP Integration (email-agent demo)

Architecture: An IMAP-connected assistant that performs agentic search across an inbox, identifies relevant threads, and provides AI-powered responses. Demonstrates real credential handling (IMAP auth) integrated with the SDK’s permission model.

Enterprise translation: The pattern for integrating agents with existing communication infrastructure. The IMAP implementation is illustrative — the same architecture applies to Outlook/Exchange via Microsoft Graph, Slack via API, or any message store with a search interface.

Pattern D: Progressive Capability Assembly (agent-sdk-workshop curriculum)

The workshop curriculum teaches enterprise technical leaders via four progressive stages on a single cohesive task (company briefing):

Stage Toggle SDK Primitive What Unlocks
0 — Baseline (all off) system_prompt Conversational response only; no external data
1 — Tool-Enabled ENABLE_TOOLS @tool + mcp_servers Agent can look up live data from internal sources
2 — Delegating ENABLE_SUBAGENTS AgentDefinition + Task tool Agent spawns specialists; parallel work becomes possible
3 — Persistent ENABLE_MEMORY hooks + persistence tool Agent remembers context across sessions via hook-managed storage

The pedagogical insight: attendees run the same query at each stage and observe the answer quality improve. The delta between Stage 0 and Stage 3 makes the value of each primitive concrete without requiring attendees to write production code.

Pattern E: Enterprise Use-Case Breakouts

The workshop pre-builds six enterprise agent configurations as assembly exercises:

Scenario Tool Categories Active Key Subagents Edge Case Designed In
Chief of Staff schedule, knowledge, memory writer, summarizer Calendar conflict + competing priorities in same briefing
Customer Support support, knowledge classifier, verifier Duplicate charge is actually two legitimate charges; lazy prompt issues wrongful refund
SRE Agent ops, knowledge, code procedure_runner, verifier Deploy at 11:42 → error spike at 12:03; runbook RB-001 resolves it, but hedging prompts miss it
Account Intelligence knowledge, memory researcher, classifier Healthy usage metrics + departed executive sponsor = hidden churn risk
Freeform all all (user-defined)

Tool categories available: schedule, knowledge, support, ops, code, memory — six categories, 19 pre-built tools. Subagent library: researcher, summarizer, classifier, verifier, writer, procedure_runner.

All mock data is local JSON — no external APIs, no third-party credentials required. The @tool contract stays identical when swapping mock implementations for production integrations.


4. Long-Running Agent Support

The v2 Session API (unstable_v2_*) introduces separate send() and stream() calls instead of the unified query() generator. This enables:

  • Session persistence — a session ID can be serialized, stored, and resumed across process restarts
  • Multi-turn conversation management — explicit control over when to send and when to receive, allowing async patterns where the agent processes work between human interactions
  • Decoupled streaming — receive can begin independently of send, enabling push-notification patterns

The hello-world-v2 demo demonstrates the V2 patterns directly. The unstable_ prefix signals that this API surface is not yet stable and may change before GA.

For long-running workflows requiring persistence across days or weeks (e.g., a research agent that accumulates findings over a week of incremental runs), the production pattern combines the V2 Session API with a PostToolUse hook that persists intermediate state to a durable store after each tool call. A crash or restart can then resume from the last checkpoint rather than the beginning.


5. MCP Integration — Anthropic’s Perspective vs. NVIDIA’s

Anthropic’s position: MCP is the interoperability layer for external tool ecosystems, but in-process SDK MCP servers are preferred for application-owned tools. External MCP servers (via stdio or sse transport) integrate vendor tool suites — Anthropic explicitly supports mixed configurations where the same agent uses both.

The SDK’s mcp_servers parameter accepts either an SdkMcpServer object (in-process) or a config dict specifying transport, command, and args (external subprocess). The model sees all tools identically regardless of which transport they use.

Key difference from NVIDIA AIQ: NVIDIA’s Agent Intelligence Toolkit treats MCP as one of several framework adapters — alongside LangChain, LangGraph, LlamaIndex, and CrewAI — and positions itself as the orchestration layer above all of them. Anthropic’s SDK treats MCP as the tool transport and positions Claude itself as the orchestrator. The architectural implication: Anthropic’s approach is Claude-native by design; NVIDIA’s is model-agnostic by design.

Enterprise decision point: Teams standardizing on Claude as their primary model should prefer the Anthropic SDK’s in-process MCP server pattern — simpler deployment, no subprocess management, direct Python debugging. Teams managing a multi-model fleet or already invested in LangGraph/LlamaIndex tooling may prefer NVIDIA AIQ or LangGraph’s MCP adapter layer, accepting the abstraction cost in exchange for framework portability.

Cross-reference: google-adk-enterprise-agents.md for Google’s MCP positioning; a2a-mcp-protocol-security.md for MCP attack surface analysis.


6. Architectural Differences: Claude SDK vs. Bedrock Agents vs. NVIDIA AIQ

Dimension Claude Agent SDK AWS Bedrock Agents NVIDIA AIQ
Orchestration model Claude Code runtime embedded in Python process Managed AWS service with Lambda action groups Framework adapter layer; model-agnostic
Tool definition @tool decorator, in-process MCP server Lambda function + OpenAPI schema in S3 Tool wrappers compatible with LangChain, LlamaIndex, CrewAI
HITL mechanism PreToolUse hook + canUseTool callback Bedrock Agent human-in-the-loop flow Framework-dependent
Multi-agent AgentDefinition + Task tool invocation Bedrock agent-to-agent calls (supervisor/sub patterns) Multi-agent via framework conventions
Deployment model Any Python environment (cloud, on-prem, laptop) AWS-only, managed service NVIDIA infrastructure preferred; portable in principle
Observability Hook-based; structured JSONL; developer-managed CloudWatch + Bedrock trace logging Integrated with NVIDIA NeMo tooling
Model lock-in Claude only (by design) Any Bedrock-supported model Multi-model (Llama, Mistral, commercial)
Permission model Layered: disallowed → allowed → mode → callback → hook IAM roles + resource policies Framework-level; no built-in permission layer

The Bedrock Agents managed-service model reduces infrastructure overhead at the cost of AWS lock-in and less control over the agent loop. The Claude Agent SDK gives developers full control over the loop — hooks, permission callbacks, session management — at the cost of managing the runtime themselves. NVIDIA AIQ is the choice when the constraint is hardware-level inference optimization or multi-model portability, not developer ergonomics.


7. TypeScript vs. Python SDK

Anthropic maintains both a Python SDK (claude-agent-sdk) and a TypeScript SDK (@anthropic-ai/claude-agent-sdk). The feature surface is not identical at any given release; Python has historically led.

Python: Default choice for data science, ML, and backend automation teams. The workshop curriculum runs Python. All cookbook examples are Python.

TypeScript: Used when the agent is embedded in a web application or Node.js service. The simple-chatapp demo (React + Express + SDK) is TypeScript-native. The hello-world and hello-world-v2 demos in claude-agent-sdk-demos are TypeScript, reflecting the demos repo’s primary audience (full-stack developers).

Bun vs. Node.js: The demos repo specifies Bun as the preferred runtime (or Node 18+). Bun’s significantly faster startup time matters for development iteration; production deployments can use either.

Enterprise guidance: Python for orchestration-heavy agents with data integrations; TypeScript for agents embedded in web products or user-facing interfaces. Avoid mixing runtimes within a single agent network — the in-process MCP server model requires language-homogeneous deployment.


8. Workshop Curriculum — What Enterprise Teams Are Being Trained On

The agent-sdk-workshop is explicitly designed for “VP/Director level” technical leaders “familiar with LLMs and comfortable in a terminal.” The design principle: attendees never write code — they flip switches, pick components, and write prompts.

This is a deliberate choice about where the highest-leverage skill gap is. The workshop’s thesis: the SDK has reduced the implementation cost of tool declaration and loop management to near zero. The remaining enterprise skill gap is:

  1. Architectural judgment — which tool categories to enable, which subagents to deploy, where to enforce HITL checkpoints
  2. System prompt quality — the config.py in every breakout has a SYSTEM_PROMPT field; prompt tuning is “where the real work is”
  3. Edge case anticipation — every breakout has a deliberately tricky scenario where the obvious agent action is wrong (e.g., issuing a refund that’s actually unjustified, missing a churn signal hidden behind healthy usage metrics)

The build_options() function in 01-guided-demo/agent.py is the teaching centerpiece — attendees read it and walk away knowing the full API surface of ClaudeAgentOptions.

Key tables the curriculum repeats (in GUIDE.md, FAQ.md, and CHEATSHEET.md — repetition is intentional):

Concept Main Agent Sub-Agent
Who defines it Developer Developer
Who invokes it User (via client.query()) Lead agent (via Task tool)
Context window Shared with user conversation Isolated
Concept Tool Hook
Who triggers it The model The SDK runtime
Is the model aware Yes No
Primary use Capability extension Control plane

9. Key Limitations and Production Considerations

Not for production at scale (demos): The claude-agent-sdk-demos README explicitly states: “These are demo applications by Anthropic. They are intended for local development only and should NOT be deployed to production or used at scale.” Production agents require additional layers — retry logic, circuit breakers, rate limit handling, cost attribution, and observability tooling not present in the demos.

CLI bundling: The SDK bundles the Claude Code CLI. This has deployment implications: the wheel includes platform-specific binaries for macOS, Linux, and Windows. Containerized deployments must specify the correct platform wheel.

No built-in cost attribution: Token consumption tracking is the developer’s responsibility. For enterprise deployments managing multiple agent instances across departments, pair with the patterns in token-cost-governance-enterprise-ai-2026.md.

Session V2 is unstable: The unstable_v2_* API is explicitly flagged as pre-stable. Avoid building production workflows on it until Anthropic removes the prefix.

Concurrency: The SDK does not enforce limits on simultaneous agent instances. On GPU-constrained infrastructure (on-prem inference), external concurrency controls are required to prevent resource contention. Cross-reference: MLX/MPS concurrency guidance in project memory.


10. Signal Summary for CIO/Architect Conversations

  • The Agent SDK eliminates the tool loop implementation cost — the remaining engineering challenge is tool design and permission policy, not orchestration mechanics
  • In-process MCP servers are the correct architecture for application-owned tools; external MCP servers integrate vendor ecosystems
  • Hooks are the production HITL mechanism — PreToolUse is where human approval checkpoints belong
  • Subagent model routing (orchestrator on Sonnet, workers on Haiku) is the cost optimization pattern for multi-agent workflows
  • The workshop curriculum’s edge case scenarios reveal the real production challenge: not “can the agent do the task” but “does the agent do the right thing when the obvious move is wrong”
  • The SDK is Claude-only by design; teams requiring model portability should evaluate NVIDIA AIQ or LangGraph as the orchestration layer above model-specific SDKs

Brandon Sneider | brandon@brandonsneider.com May 2026