The Claude Agent SDK

Claude Code Agents: Advanced Orchestration

Chapter 2 · The Claude Agent SDK

Advanced AI Workflows & the Claude API introduced multi-agent patterns at the raw API level — tool use, streaming, and building an AI-powered app from scratch. This chapter picks up specifically where that course's own multi-agent chapter left off: using the Claude Agent SDK to define and run agents programmatically, in code, rather than as the hand-written definition files Fundamentals covered.

Hand-Written Definitions vs. Programmatic Agents

Fundamentals' Chapter 2 covered an agent definition as a markdown file — frontmatter fields (name, description, tools, model) plus a written system-prompt body. That works well for a fixed, well-understood role used repeatedly. Defining the same fields programmatically — as a data structure built in code, rather than a static file — opens up something a static file can't: generating or adjusting an agent's own configuration dynamically at runtime. A tool allowlist could be built conditionally based on the current user's permission level; a system prompt could be templated with variables filled in from the actual task at hand, rather than written once and left fixed.

The Agentic Loop

Running an agent that uses tools involves a repeating cycle: send a message, the model requests a tool call, your code executes that tool, the result is sent back, and the cycle repeats until the model produces a final answer with no further tool calls needed. The SDK's Tool Runner handles this entire cycle automatically — you register the available tools and hand off the conversation, and the loop runs to completion without you writing the repeat-until-done logic yourself.

Manual Tool-Use Loops

The alternative to the Tool Runner is writing that same loop by hand — genuinely more code, but full control over what happens at each step: custom logging between every tool call, injecting extra validation logic before a tool actually runs, or stopping the loop early under a specific condition the automatic runner wouldn't know to check for. This is a real trade-off between convenience and control, not a strictly better or worse option in either direction — worth choosing deliberately based on whether that extra control is actually needed.

# Illustrative pattern — actual SDK syntax may vary by version agent_config = { "name": "changelog-writer", "description": "Writes changelog entries for finished work", "tools": [read_file_tool, edit_file_tool], "model": "claude-haiku-4-5", } # The Tool Runner handles the repeat-until-done loop for you result = client.beta.messages.tool_runner( **agent_config, messages=[{"role": "user", "content": task_brief}] )

Managed Agents

A managed agent runs server-hosted, inside infrastructure that persists independently of your own local process — useful for handing off a genuinely long-running task without needing your own machine to stay running and connected the whole time. This trades some direct control for not having to manage that infrastructure yourself.

AspectHand-Written Definition (Fundamentals)Programmatic (SDK) Agent
Where it's definedA static markdown fileBuilt as data/code at runtime
Can it vary at runtime?No — fixed once writtenYes — tools, prompt, model can depend on conditions
Best suited forA stable, well-understood, repeated roleAn agent whose configuration genuinely needs to change per run
Default to hand-written unless dynamic behavior is actually needed
A hand-written definition is simpler to read, review, and reason about than a programmatically generated one. Reach for the SDK's programmatic approach specifically when an agent's configuration genuinely needs to vary at runtime — not as a default, more "advanced-feeling" way to define every agent.
Programmatic definitions add real complexity
Building an agent's configuration in code means more code to maintain, and more that can go subtly wrong in how that configuration gets assembled — a conditional that doesn't cover every case, a templated prompt with a variable substituted incorrectly. This is worth the added complexity specifically when the dynamic behavior it enables is genuinely needed — the same "orchestration has a real cost" theme this course opened with in Chapter 1, applied here to configuration itself rather than to chaining agents together.

Hands-On Exercises

Exercise 1

Explain a concrete scenario where an agent's tool allowlist genuinely needs to be built at runtime rather than fixed in a hand-written definition file.

📄 View solution
Exercise 2

Explain the trade-off between using the Tool Runner and writing a manual tool-use loop, and give an example of when the manual loop's extra control would genuinely be worth its extra code.

📄 View solution
Exercise 3

A developer converts every agent in their project to a programmatically-defined SDK agent, even ones whose configuration never changes between runs. Using this chapter's own warning box, explain what's questionable about this decision.

📄 View solution

Chapter 2 Quick Reference

  • A programmatic agent's configuration is built in code, letting it vary at runtime — unlike a fixed, hand-written definition file
  • The Tool Runner automates the repeat-until-done agentic loop; a manual loop trades that convenience for full control
  • A managed agent runs server-hosted, independent of your own local process
  • Default to hand-written definitions unless an agent's configuration genuinely needs to vary at runtime
  • Programmatic definitions add real maintenance complexity — worth it only when the dynamic behavior is actually needed