Intermediate · 22 min read · updated 2026-07-14

Build Agents with the Claude Agent SDK

A hands-on guide to the Claude Agent SDK: how the tool loop works, how to define tools, and how to ship a real agent to production.

Claude Agent SDKAI AgentsTypeScriptPythonLLM Engineering
Who this is for: developers who already ship production code and want to build a custom agent - not a chatbot wrapper - using the Claude Agent SDK, with real tool definitions, a planning loop, and a deployment target. If you have never called an LLM API before, start with prompt engineering for business first.

The Claude Agent SDK (formerly shipped internally as the engine behind Claude Code, then released as a standalone SDK in 2025) gives you the same agent loop Anthropic uses in its own products: a model that reads a prompt, decides whether to call a tool, executes it, reads the result, and loops until it has an answer. That loop is the entire value proposition. Everything else - context management, permission gates, subagents, hooks - exists to keep that loop safe and cheap at scale.

What the Claude Agent SDK actually gives you

It is not a framework in the LangChain sense. There is no graph builder, no DAG of nodes. The SDK is a thin, opinionated runtime around three primitives:

  1. A message loop that sends your prompt plus conversation history to a Claude model, receives either text or a tool-use block, and resumes automatically after you return the tool result.
  2. Tool definitions - JSON Schema descriptions of functions the model can call, paired with the actual handler you write.
  3. Session state - context compaction, prompt caching, and (in the TypeScript and Python packages) built-in support for file edits, bash execution, and web fetch as first-class tools if you want them.

The SDK ships as @anthropic-ai/claude-agent-sdk for Node/TypeScript and claude-agent-sdk for Python. Both wrap the standard Messages API but add the orchestration you would otherwise hand-roll: retry logic on tool errors, automatic context trimming when you approach the context window limit, and a permission callback so you can approve or block any tool call before it runs.

Reality check: if your "agent" only ever calls one tool once and returns, you do not need this SDK - a single Messages API call with tools is simpler and cheaper. The SDK earns its keep when the model needs multiple rounds of tool calls to finish a task.

The tool loop, step by step

Here is what happens on the wire for a single turn:

  1. You send messages + tools (schema only, not implementations) to the model.
  2. The model replies with a stop_reason of either end_turn (done, here is text) or tool_use (it wants to call something, with arguments already validated against your schema).
  3. Your code executes the real function - hitting a database, calling an API, running a shell command.
  4. You append a tool_result block with the output (or an error) and send the whole thing back.
  5. Repeat from step 2 until end_turn.

The SDK automates steps 2-5 for you: you register handlers once, and it runs the loop until completion or until you hit a max-turns guard you set. Left unbounded, a buggy tool that always "needs more information" can loop dozens of times and burn real money - always set maxTurns (TypeScript) or max_turns (Python).

import { query } from "@anthropic-ai/claude-agent-sdk";

const result = query({
  prompt: "Check inventory for SKU-4471 and email the warehouse manager if stock is below 20 units.",
  options: {
    model: "claude-opus-4-6",
    maxTurns: 8,
    allowedTools: ["check_inventory", "send_email"],
    tools: {
      check_inventory: {
        description: "Look up current stock count for a SKU",
        input_schema: {
          type: "object",
          properties: { sku: { type: "string" } },
          required: ["sku"],
        },
        handler: async ({ sku }) => {
          const row = await db.inventory.findOne({ sku });
          return { count: row?.count ?? 0 };
        },
      },
      send_email: {
        description: "Send an email to a named recipient",
        input_schema: {
          type: "object",
          properties: {
            to: { type: "string" },
            subject: { type: "string" },
            body: { type: "string" },
          },
          required: ["to", "subject", "body"],
        },
        handler: async (args) => mailer.send(args),
      },
    },
  },
});

for await (const event of result) {
  if (event.type === "text") process.stdout.write(event.text);
}

This is the whole shape of the SDK. No graph, no chain abstraction - just a prompt, a tool registry, and a loop. For a deeper dive into how tool schemas are matched and validated at the model level, see LLM tool calling explained.

Defining tools that the model can actually use well

Most agent failures I have debugged in production are not model failures - they are bad tool design. Three rules that consistently fix them:

  • Name tools like functions, not features. get_order_status beats orderTool. The model reads the name as part of its reasoning.
  • Put constraints in the schema, not the description. An enum for status values gets enforced; a sentence saying "must be one of..." gets ignored under pressure.
  • Return structured errors, not exceptions. If a tool fails, return { error: "SKU not found" } as the tool result rather than throwing - the model can recover and try a different SKU, adjust its plan, or ask the user. A thrown exception just kills the loop.

TypeScript vs Python: which to pick

AspectTypeScript SDKPython SDK
Best fitWeb backends, Next.js API routes, Node workersData pipelines, notebooks, existing ML/ETL stacks
StreamingNative async iteratorsAsync generators, near-identical API
Tool schemaZod or raw JSON SchemaPydantic models or raw JSON Schema
DeploymentVercel functions, Cloudflare Workers, any Node hostCloud Run, AWS Lambda (with cold-start cost), FastAPI services
Ecosystem fitPairs naturally with a React/Next.js frontendPairs naturally with pandas/numpy tool handlers

If your product is a web app, use the TypeScript SDK and keep the agent server-side in an API route - never expose your Anthropic API key to the browser. If you are building an internal automation that touches spreadsheets, PDFs, or existing Python data tooling, the Python SDK removes an unnecessary language boundary. For teams choosing between building this from scratch versus using no-code automation, n8n vs Make vs Zapier is worth reading before you commit engineering time.

Planning: when to let the model plan vs. when to script it

A common mistake is asking the model to plan a multi-step task from a single prompt with no structure. It works about 70% of the time and silently skips steps the other 30%. Two patterns that raise reliability:

  1. Explicit plan-then-execute. First call: "list the steps you will take, as JSON, before doing anything." Second call: execute the tool loop against that plan, checking off items. This roughly doubles token cost per task but cuts silent step-skipping dramatically in tasks with 5+ steps.
  2. Scripted orchestration, model-only for judgment calls. For workflows you can describe as a state machine (fetch -> validate -> decide -> act), write the state machine in plain code and only call the agent loop for the "decide" step, where judgment actually matters. This is cheaper and far easier to debug than letting the model own the whole flow.
Tip: log every tool call and its arguments to a persistent store (even just a JSON log file) during development. When an agent misbehaves, you almost always find the bug by reading the actual sequence of tool calls, not by re-reading the prompt.

For structuring the final output of a plan or decision step, pair the SDK with strict schemas - see structured outputs for how to force JSON-shaped responses instead of parsing free text.

Multi-agent and subagent patterns

The SDK supports subagents: a top-level agent can spawn a scoped subagent with its own tool allowlist and its own context window, then read back a summary instead of the subagent's full transcript. This is the same mechanism Claude Code uses for its Task tool. Use it when:

  • A subtask needs a large amount of exploratory tool-calling (searching, reading many files) that would otherwise bloat the parent's context.
  • You want to isolate blast radius - a subagent with only read-only tools cannot accidentally trigger a write in a research phase.
  • Different steps genuinely need different system prompts or personas (a "reviewer" agent vs. a "writer" agent).

Do not reach for subagents just because a task has multiple steps - that adds latency (each subagent spin-up is a fresh context) and complexity for no benefit if the parent agent could just call two tools in sequence. Full pattern catalog in multi-agent systems guide and agentic workflow patterns.

Memory and context across sessions

The SDK does not give you persistent memory out of the box - it manages the context window within a session (compaction, prompt caching) but forgets everything once the process exits. For an agent that needs to remember a user across days:

  • Store a compact summary (not the raw transcript) in your own database after each session ends.
  • Re-inject that summary as a system-prompt prefix on the next session rather than replaying the full history.
  • Use prompt caching for anything static and reused every call - your tool definitions and system prompt rarely change and caching them cuts input-token cost by roughly 90% on repeated content. See prompt caching guide for the mechanics.

Details on memory architecture patterns - what to summarize, when to use a vector store vs. a flat log - are in AI agent memory guide.

Model choice and cost control

As of mid-2026, Claude Opus 4.6 is the strongest reasoner for agent planning and complex tool sequencing, but Claude Sonnet 5 handles the majority of tool-calling loops at roughly a third of the cost and noticeably lower latency per turn. A pattern that works well in production: use Sonnet for the main loop, and only escalate to Opus for a single "plan" or "review" call at the start or end of a task. Track cost per task, not per token - a 12-turn agent loop on a cheap model can still cost more than a 2-turn loop on an expensive one. For a deeper cost breakdown, read Claude Code token cost control - the same principles (cache hits, context trimming, escalation-only for hard steps) apply directly to Agent SDK deployments.

Deploying an agent to production

An agent built with the SDK is just a long-running or on-demand process - deployment is a normal backend deployment problem, with three things to get right:

  1. Never run tool handlers with more privilege than the task needs. A tool that runs shell commands or hits your database should validate inputs exactly like any other API endpoint - see claude-code permissions and safety for the permission-gate pattern, which applies equally to your own SDK-built agents.
  2. Put it behind your own API, never call it from the browser. Wrap the query() call in a server route (Next.js API route, Cloud Run service, or a plain Express endpoint) and stream results down to the client over SSE or a WebSocket.
  3. Set hard limits: max turns, max tokens per session, and a timeout. An agent stuck in a tool-calling loop against a flaky third-party API is the single most common cause of runaway bills in early deployments.
Deployment targetGood forWatch out for
Vercel serverless functionLow-traffic agents, quick ship60s-300s execution limits depending on plan; long agent loops can time out
Cloud Run / Fly.ioLong-running loops, WebSocket streamingYou manage scaling and cold starts yourself
A dedicated worker + queueHigh-volume async tasks (batch processing)Adds infra (queue, worker pool) but decouples request latency from agent runtime

If you are choosing a hosting platform for the whole app the agent lives in, Vercel vs Firebase hosting covers the trade-offs relevant here too.

FAQ

What is the difference between the Claude Agent SDK and just calling the Messages API with tools?

The Messages API is the raw primitive - you get a tool_use block and you handle everything else yourself, including the resume loop, retries, and context management. The Agent SDK wraps that primitive with an automatic loop, built-in permission checks, prompt caching defaults, and (in the newer releases) subagent support. Use the raw API for simple single-call tool use; use the SDK once you need multi-turn tool loops.

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

No - it is built specifically around the Anthropic Messages API and Claude's tool-use format. If you need a model-agnostic agent framework, look at LangChain or a direct multi-provider setup; see LangChain vs LlamaIndex for that comparison, or Vercel AI Gateway if you want to swap models behind one interface.

How much does it cost to run an agent built on this SDK?

Cost is driven by tokens per turn times number of turns, not a separate SDK fee - you pay standard Claude API pricing. A typical 5-turn agent task on Sonnet 5 with cached tool definitions runs a few cents; the same task on Opus without caching can run 5-10x more. Budget by task, cap maxTurns, and cache anything static.

Is the Claude Agent SDK the same thing that powers Claude Code?

Yes, functionally - the SDK is the productized version of the same agent loop and tool-execution engine that runs inside Claude Code. If you have used Claude Code, the mental model (prompt, tool call, permission check, result, loop) transfers directly.

Do I need TypeScript or Python specifically, or can I call it from another language?

The official packages are TypeScript and Python only. You can still build the same loop yourself in any language against the raw Messages API - you just lose the SDK's built-in compaction, caching defaults, and subagent helpers and have to reimplement them.

What is the biggest mistake teams make building their first agent with this SDK?

Letting the tool loop run unbounded with no maxTurns and no cost ceiling. The second biggest is writing tool descriptions in prose instead of encoding constraints in the JSON Schema - the model follows schema constraints far more reliably than sentences.

Get help

If you want a second pair of eyes on an agent build - tool design, cost control, or getting it into production safely - book a free 30-minute call through the contact form or message us directly on wa.me/972585802298.

Sources