Claude Agent SDK vs the raw API

Claude API · Expert · 15 min

Picking the right layer saves weeks: don't rebuild an agent harness that already exists, or adopt one you don't need.

There are three ways to build an agent on Claude, from most control to least work:

  • Messages API (this course so far): you write the loop, the tools and the memory handling. Best for focused features and full control.
  • Claude Agent SDK: a library (Python and TypeScript) that runs the same agent loop as Claude Code inside your process, with built-in tools for reading and editing files, running commands and searching the web, plus permissions, sessions (resumable conversations), hooks (your own code run at set points), subagents (helper agents for sub-tasks) and MCP. Best when your agent works on files or a codebase.
  • Claude Managed Agents (beta): Anthropic hosts the loop and a sandbox; you configure agents and sessions through the API. Best for long-running background tasks without your own infrastructure.

The Python package is claude-agent-sdk, imported as claude_agent_sdk. It is asynchronous: functions marked async def are started with asyncio.run(...), and async for loops over messages as they arrive while the agent works.

query(prompt=..., options=ClaudeAgentOptions(...)) starts a one-off task. Important options: allowed_tools (tools that run without asking), permission_mode (for example default, acceptEdits or plan), cwd (the folder it works in), max_turns and system_prompt. You get AssistantMessage objects while it works and a final ResultMessage with the result and cost. For a back-and-forth chat, ClaudeSDKClient keeps one session open.

Treat an agent like a new colleague with shell access: give the narrowest tools and folder that do the job.

Example

# pip install claude-agent-sdk   (uses ANTHROPIC_API_KEY)
import asyncio
from claude_agent_sdk import (query, ClaudeAgentOptions,
                              AssistantMessage, ResultMessage, TextBlock)

async def main():
    options = ClaudeAgentOptions(
        system_prompt="You are a careful code reviewer.",
        allowed_tools=["Read", "Grep", "Glob"],   # read-only tools run freely
        permission_mode="default",
        cwd="./my_project",
        max_turns=10,
    )
    async for msg in query(prompt="Find likely bugs in utils.py", options=options):
        if isinstance(msg, AssistantMessage):
            for block in msg.content:
                if isinstance(block, TextBlock):
                    print(block.text)
        elif isinstance(msg, ResultMessage):
            print("done:", msg.subtype, "cost $", msg.total_cost_usd)

asyncio.run(main())

Remember

  • Messages API = full control; Agent SDK = Claude Code's loop and tools in your app; Managed Agents = hosted
  • query() with ClaudeAgentOptions for one-off tasks; ClaudeSDKClient for ongoing sessions
  • Restrict allowed_tools, permission_mode and cwd

Watch out for

  • Giving an agent broad shell and write access with automatic approval on your real machine.

Check yourself

  1. You need a small feature that classifies emails with one tool call. Which layer fits best?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: code.claude.com/docs/en/agent-sdk/overview