Claude Agent SDK Intro
Lesson 03 · Building Your Own Agents · ~12 min read
What the Claude Agent SDK is — and what it isn’t
The most common confusion in 2026: someone hears about the “Claude Agent SDK,” opens
PyPI, types pip install claude-agent-sdk, and finds nothing useful. That’s
because the SDK isn’t a separate distribution. It’s a set of higher-level primitives
shipped inside the official anthropic Python package — the same package
Lesson 02 used for the hand-rolled loop. One pip install anthropic gives you
both the low-level Anthropic() Messages client and the agent-loop primitives
this lesson introduces. They live in a different namespace
(anthropic.agents) but ship in the same wheel.
Contrast briefly with the three other framework SDKs the course covers in Module 3. LangGraph
is an independent package (pip install langgraph) that depends on
langchain-core. CrewAI is its own package too (pip install crewai),
with its own runtime. OpenAI’s agent framework lives in a separate
openai-agents distribution alongside the base openai client.
Anthropic took a different shape on purpose: same package, additional namespace, no extra
dependency to keep current. If your project already imports anthropic, the SDK
is already on disk.
The rebrand from Computer Use
Short history, because tutorials and blog posts older than mid-2025 still use the old name. In late 2024 Anthropic released “Computer Use” as a public beta. The framing was narrow: an SDK focused on letting Claude drive a desktop — capture the screen, click, type, scroll — using a small family of pre-defined tools. The interesting parts of that release weren’t actually about desktops; they were about the agent loop, the tool-definition format, and the stop-condition machinery that all of it ran on top of.
In 2025 the scope broadened. General-purpose agent primitives — the loop, the
@tool decorator, the typed stop conditions — became the headline. The
computer-use tools (screen, mouse, keyboard) were repositioned as one of several built-in
tool families alongside web search, code execution, and file editing. The name moved to
“Claude Agent SDK.” 2026 Q2 is the first GA-stable cut and the version this
course pins: anthropic>=0.39,<0.40 in agents/requirements.txt.
The practical implication for you: if you Google something and land on a 2024 Computer Use tutorial, the imports and shapes are largely the same, but the namespace and entry points moved. Treat anything older than mid-2025 as a hint, not a recipe.
The five primitives you’ll actually use
A small inventory you can hold in your head. Slide 5 has the same list with arrows; this is the prose version.
Agent— wraps the loop. Constructed with a client, a model name, a system prompt, a tool list, and stop-condition settings. Has.run(message)(blocking, returns a result object) and.stream(message)(yields typed events as the agent works).@tool/Tool— the decorator turns a plain Python function into something the agent can call. It inspects the type hints and docstring at definition time and builds a JSON Schema automatically. No more hand-written schema dicts.- Message helpers — small utilities
(
assistant_message,tool_result, etc.) so you don’t hand-write the role/content dict shape you saw in L02. You only reach for these when you pre-seed a conversation or replay one for testing. - Stop-condition config —
max_turnsandmax_cost_usdas constructor arguments, plus anon_stephook that is called after every turn and canraiseto interrupt the loop from caller code. - Streaming events —
agent.stream()yields typed events (message_start,tool_use,text_delta,tool_result,end_turn) that map cleanly onto UI updates, log lines, or observability spans.
That’s the whole surface area you need for now. Modules 11 and 12 (Plan F) will revisit more advanced primitives — guardrails, sub-agents, structured-output helpers — when the cross-framework comparison demands them. For Lessons 03 and 04 these five are enough.
Same loop, less code
The headline of this lesson is a line-count delta. The L02 weather agent — the one you wrote by hand — is around 80 lines of Python. The same agent built on the SDK is around 12. Same model calls, same tools, same answer, same cost ballpark. The difference is pure boilerplate.
It is worth walking through what disappeared when you switch:
- The
for turn in range(MAX_TURNS):loop body now lives insideAgent.run(). You don’t see it. - The branch on
response.stop_reason—end_turn,tool_use,max_tokens— is internal. - The “append the assistant’s content, then append a user message containing
tool_resultblocks” dance is internal too. You don’t mutate amessageslist any more. - Cost tracking is automatic.
result.usage.total_cost_usdfor the total,max_cost_usd=for the cap. The manualtotal_in/total_outaccumulators and the per-model price constants go away. - The turn cap is
max_turns=and raises a typed exception (MaxTurnsExceeded) instead of a genericRuntimeError. - The tool-error path — catching the tool function’s exception and surfacing
is_error: Trueback to the LLM — is wrapped by the@tooldecorator.
What you still own: writing the tool functions themselves, picking the model,
writing the system prompt, deciding budgets, handling KeyboardInterrupt at the
outer scope. The interesting parts of agent design didn’t go away — only the
loop boilerplate did. That’s the trade you’re making in every framework chapter
for the rest of the course.
The @tool decorator and Python introspection
Concretely, the decorator turns this:
from anthropic.agents import tool
@tool
def search_notes(query: str) -> str:
"""Search the user's notes by substring and return up to 5 matches."""
...
into the JSON Schema the LLM needs. Type hints become the property types
(str → "type": "string", int →
"type": "integer", bool → "type": "boolean",
list[X] → "type": "array", and so on). A parameter is
required if it has no default; otherwise it’s optional. The docstring
becomes the tool description, which is what the LLM actually reads when
deciding whether to call the tool.
Docstrings matter more than function names
A vague docstring — or none at all — means the LLM doesn’t know
when to call your tool. The agent stalls, asks the user clarifying questions
it shouldn’t need to, or hallucinates an answer instead of calling the tool.
A specific docstring with an example input and the exact format of the return value is
dramatically more reliable. The hand-rolled L02 schema dict had a description
field that played the same role; the SDK just makes the docstring the canonical place
for it. Homework Task 1 will have you observe this failure mode first-hand.
Pydantic models also work as parameter types — useful when one tool argument is a
structured object rather than a primitive. The decorator reads the model’s field
definitions and inlines them into the schema. We’ll lean on this in L04 for a
write_report(sections: list[Section]) tool, and Homework Task 2 introduces it
with a smaller TravelQuery model.
Built-in stop conditions and the on_step hook
Lesson 01 enumerated four stop conditions for an agent loop: natural exit, turn cap, cost
cap, and caller interrupt. Lesson 02 wired three of them by hand (the cost cap was an
if branch on accumulated usage; the turn cap was the range() in
the for loop; the interrupt was KeyboardInterrupt). The SDK
collapses all of that to constructor arguments:
from anthropic import Anthropic
from anthropic.agents import Agent
agent = Agent(
client=Anthropic(),
model="claude-3-5-sonnet-latest",
system="You are a helpful weather assistant.",
tools=[get_weather, get_clothing_advice],
max_turns=10, # turn cap
max_cost_usd=0.50, # cost cap
on_step=my_step_handler, # caller hook
)
- Natural exit (
end_turn): automatic.Agent.run()returns a result the moment the LLM signals it is done. No branch to write. - Turn cap:
max_turns=. RaisesMaxTurnsExceededwhen exceeded — a typed exception you can catch specifically. - Cost cap:
max_cost_usd=. The SDK tracks token usage per turn, looks up the model’s pricing in its built-in registry, and raisesMaxCostExceededwhen the running total crosses the cap. - Caller interrupt:
on_step=is called after every turn with anAgentStepobject (turn number, tool calls just made, cost so far, stop reason). Raising from inside the hook stops the loop cleanly with whatever exception you raised. The outer scope still needs to catchKeyboardInterruptto handle Ctrl-C, exactly as in L02.
Pricing comes from the model registry inside the anthropic package. If you
use a custom or fine-tuned model whose price isn’t in the registry, supply
pricing=ModelPricing(input_per_million=..., output_per_million=...) on the
Agent constructor. In L02 these prices were a manual pair of module-level
constants; here they’re a structured argument the SDK uses internally.
When to pick Claude Agent SDK (and when not to)
A short decision matrix you’ll revisit in Module 6 once you’ve seen LangGraph, CrewAI, and the OpenAI Agents SDK side by side. For now, the rules of thumb:
Pick the Claude Agent SDK when:
- Your model is already Claude — or it’s reasonable to standardise on Claude for this particular agent.
- The agent shape is tool-heavy: three or more tools used per task, possibly chained in unpredictable orders. This is the lesson’s sweet-spot scenario and exactly what L04’s research assistant will demonstrate.
- You don’t need an explicit graph shape (LangGraph) or multi-agent role-play (CrewAI).
- You want low dependency weight and minimal abstraction layers over the raw Messages API — useful for latency-sensitive deployments where every layer costs you milliseconds.
Don’t pick the Claude Agent SDK when:
- You need to swap models between providers per call — the OpenAI Agents SDK is better at that pattern.
- Your control flow is naturally a DAG or a graph you want to draw — reach for LangGraph.
- You’re building three or more agents that genuinely play different roles (researcher / critic / writer) — CrewAI is shaped for that.
- Your team’s existing infra is already deeply LangChain- or LangGraph-shaped and you’d be swimming against the current.
This is the framing L04 builds on: the tool-heavy research assistant is the canonical sweet-spot demo for the Claude Agent SDK, and it’s exactly the shape you’ll build next.
References
- Anthropic, Claude Agent SDK docs —
docs.anthropic.com/en/docs/agents-and-tools/agent-sdk/overview. - Anthropic, Tool use guide —
docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview. - Anthropic engineering, Building Effective Agents (2024).
- L02 —
agents/lesson02-agent-loop/theory.html, the hand-rolled version of the same loop.