Questions? Call 1.800.716.8955

Chapter 2

Agents and Workflows (14.7%)

What the exam tests: choosing between a workflow and an agent, structuring multi-agent systems, and building agents with the Claude Agent SDK, custom loops, managed hosting, hooks, and common frameworks.

Workflow or agent?

A workflow is a system where your code decides the path: LLM calls and tools are orchestrated through predefined steps. An agent is a system where the model decides the path: it chooses which tools to call and when it is done, in a loop. Both are "agentic systems," but they sit at different points on a control-versus-flexibility curve. Start with the simplest tier that works:

Single call. Classification, extraction, summarization, Q&A.

Workflow. Multi-step tasks whose steps you can specify in advance.

Agent. Open-ended tasks where the number and order of steps cannot be known up front. Before choosing an agent, check four criteria. If any answer is "no," stay with a simpler tier.

Criterion Question to ask

Complexity Is the task multi-step and hard to fully specify in advance?

Value Does the outcome justify the higher cost and latency of a loop?

Viability Is Claude actually capable at this kind of task?

Cost of error Can mistakes be caught and recovered from (tests, review, rollback)?

The five workflow patterns

These come from Anthropic's "Building effective agents" guidance and appear constantly in scenario items.

Figure 2. The five workflow patterns from Anthropic's "Building effective agents" Pattern How it works Use when

  • Prompt
  • chaining
  • Output of step N is input to step N+1, with op‐
  • tional checks ("gates") between
  • A task decomposes into fixed, sequential subtasks,
  • such as outline then draft then translate
  • Routing A classifier call sends input to a specialized
  • prompt or model
  • Inputs fall into distinct categories, such as refunds vs
  • technical support, or easy vs hard queries routed to
  • Haiku vs Opus
  • Paralleliza‐
  • tion
  • Independent subtasks run at once (sectioning)
  • or the same task runs several times for con‐
  • sensus (voting)
  • Speed matters, or you want multiple perspectives,
  • such as several guardrail checks run side by side
  • Orchestrat‐
  • or-workers
  • A central LLM breaks the task down dynamically
  • and delegates to workers, then synthesizes
  • Subtasks cannot be predicted in advance, such as ed‐
  • its across an unknown set of files

EvaluatoroptimizerOne call generates, another critiques, loop until criteria are met

Clear evaluation criteria exist and iteration measurably

improves output

Agent architecture

An agent is fundamentally a loop: send messages and tools to Claude, execute any tool_use blocks it returns, append the tool_result blocks, and repeat until stop_reason is end_turn. Everything else is about making that loop reliable.

Prompt chaining

fixed steps, optional gates

Llm 1 llm 2 llm 3

Llm 1

Llm 2

Llm 3

Figure 3. An agent is a loop: call Claude, run the tools it asks for, append the results, repeat until end_turn

Manager/supervisor hierarchies. A lead agent plans and delegates to specialized subagents, then integrates their results. The lead keeps the big picture; each subagent keeps a narrow job. Subagents improve execution in three ways:

Context isolation. A subagent can read 50 files and return a 300-word summary. The lead's context window never sees the raw reading.

Parallelism. Independent research or file work runs concurrently.

Specialization. Each subagent gets its own system prompt, tool set, and even a cheaper model, such as Haiku for bulk reading.

The tradeoff is cost and coordination. Multi-agent systems use many more tokens than a single agent, and information can be lost at hand-off boundaries. Use them when the work genuinely fans out.

Building agents with Claude

There are four ways to build a Claude agent. They differ in who supplies the harness (the loop and context management) and who supplies the deployment.

Approach Harness Hosting Built-in tools Best for

Custom loop on the Messages API You write it You None; only tools you define

Claude Agent SDK (claude-agent-sdk, @anthropic-ai/claude-agent-sdk)

Tool Runner is not the Agent SDK. Tool Runner is a helper inside the regular anthropic SDK that loops over tools you define. The Agent SDK is Claude Code packaged as a library, with built-in tools, permissions, sessions, hooks, and subagents.

Self-hosted vs Anthropic-hosted. The Agent SDK gives you a harness but you deploy it. Managed Agents is the only option where Anthropic runs both the loop and the tool-execution environment.

Hooks for deterministic actions. Model behavior is probabilistic; hooks are not. A hook is code that runs at a fixed lifecycle point, such as before a tool call (PreToolUse), after a tool call (PostToolUse), or when the agent stops. Use hooks for anything that must always happen: block rm -rf, run a formatter after every edit, log every tool call, require approval for payments. If it must happen every time, put it in a hook, not in the prompt.

Agent patterns

Tool-use loop. The core pattern above. Return every tool result, including failures with is_error: true, so the model can recover.

Sub-agents. Delegate isolated, context-heavy work and get a summary back.

Memory. Persist facts across sessions in files or a memory tool rather than relying on one ever-growing context.

Context-window management. Prune old tool outputs, compact (summarize) history near the limit, and delegate to subagents. See Chapter 7.

Agentic frameworks

The guide names three abstraction frameworks you should recognize:

Strands Agents (AWS open source): model-driven agents with tool decorators, common on Amazon Bedrock.

LangGraph (LangChain): agents and workflows as explicit state graphs with nodes, edges, and checkpoints; good for complex branching and human-in-the-loop.

PydanticAI: type-safe Python agents with Pydantic-validated inputs and outputs. Frameworks speed up development but add abstraction that can hide prompts and make debugging harder. A frequent correct answer is "use direct API calls first, and adopt a framework only if it solves a real problem."

Worked example 2.1: a manual agent loop

The exam expects you to recognize every part of the basic agent loop. Here it is in Python with a single weather tool. Read it line by line; most agent questions are about one of these lines. import json

  • import anthropic
  • client = anthropic.Anthropic()
  • tools = [{
  • "name": "get_weather",
  • "description": (

"Get the current weather for a city. Use this whenever the user asks "

"about current conditions or temperature. Returns temperature in "

  • "Celsius and a short description."
  • ),
  • "input_schema": {
  • "type": "object",

"properties": {"city": {"type": "string", "description": "City name, e.g. Toronto"}}, "required": ["city"],

  • },
  • }]
  • def get_weather(city: str) -> dict:
  • # Stand-in for a real API call
  • return {"city": city, "temp_c": 7, "conditions": "light rain"}

messages = [{"role": "user", "content": "Should I bring an umbrella in Toronto today?"}] for turn in range(10): # 1. hard cap on iterations

messages.append({"role": "assistant", "content": response.content}) # 2. keep full content

if response.stop_reason != "tool_use": # 3. done (or truncated/refused)

results.append({"type": "tool_result", "tool_use_id": block.id, "content": json.dumps(output)})

except Exception as e: # 4. errors go back to Claude

results.append({"type": "tool_result", "tool_use_id": block.id, "content": f"Error: {e}", "is_error": True})

messages.append({"role": "user", "content": results}) # 5. all results, one message print(response.stop_reason)

print("".join(b.text for b in response.content if b.type == "text"))

What to notice:

The iteration cap. Without it, a confused agent can loop forever and burn budget. Append response.content, not just text. The assistant turn must include the tool_use blocks, or the next request is invalid because each tool_result must match a prior tool_use_id.

Exit on any non-tool_use stop. In production, branch on max_tokens and refusal separately instead of treating them as success. Errors are results. Claude can retry with a corrected city name or explain the problem to the user.

One user message for all results. This preserves parallel tool calling.

Worked example 2.2: the same agent with the Tool Runner

The SDK's Tool Runner removes the loop boilerplate. You write the function; the decorator turns its signature and docstring into a tool definition.

  • import anthropic
  • from anthropic import beta_tool
  • client = anthropic.Anthropic()
  • @beta_tool
  • def get_weather(city: str) -> str:

"""Get the current weather for a city. Use for questions about current conditions or temperature.

messages=[{"role": "user", "content": "Umbrella in Toronto today?"}], )

final = runner.until_done()

The exam point: Tool Runner is a convenience over the same Messages API loop. It has no builtin tools, no file system, and no sandbox. You still host it and you still own security.

Worked example 2.3: an agent with the Claude Agent SDK

The Agent SDK gives you Claude Code's harness: built-in tools, permissions, hooks, and subagents. A minimal code-review agent in Python looks like this (check the current SDK reference for exact option names before using it in production):

  • import asyncio
  • from claude_agent_sdk import query, ClaudeAgentOptions
  • async def main():
  • options = ClaudeAgentOptions(

system_prompt="You are a careful senior reviewer. Report issues; do not edit files.", allowed_tools=["Read", "Grep", "Glob"], # read-only by design

  • cwd="/srv/repos/payments",
  • max_turns=20,
  • )

async for message in query(prompt="Review src/ for unsafe SQL construction.", options=options):

  • print(message)
  • asyncio.run(main())
  • Three design decisions to recognize:

Least privilege by tool list. A reviewer gets read tools only. Adding Edit or Bash would widen the blast radius with no benefit.

A working directory boundary. The agent operates inside one repository.

A turn limit. The SDK equivalent of the iteration cap.

Worked example 2.4: choosing the pattern

Work through each scenario before reading the analysis.

Scenario A. A news site wants each article translated into French, German, and Spanish, then checked for tone. Languages are fixed, translations are independent.

Analysis: Parallelization (sectioning). Run the three translations concurrently, then a tone check on each. No agent is needed because every step is known in advance.

Scenario B. A customer-service system receives billing questions, technical faults, and cancellation requests. Each category has different policies and tools. Analysis: Routing. A fast classifier call (Haiku is a good fit) sends each message to a specialized prompt with only the tools that category needs. This also improves security, since the cancellation flow never sees billing tools. Scenario C. A content team wants product descriptions that meet a ten-point brand rubric. First drafts usually miss two or three points.

Analysis: Evaluator-optimizer. One call drafts, a second scores against the rubric and explains failures, and the loop repeats until all ten points pass or a cap is hit.

Scenario D. An engineering team wants to "fix the failing tests in this repository." The number of failures and the files involved are unknown.

Analysis: An agent, because the steps cannot be specified in advance. If the repository is large, an orchestrator that delegates investigation of each failing test to a subagent keeps the main context small.

Scenario E. A compliance team needs each contract run through exactly the same five checks, with an audit trail.

Analysis: A workflow, specifically prompt chaining with gates. Auditability and repeatability rule out a free-running agent.

Worked example 2.5: a supervisor with subagents

A due-diligence assistant must review 40 supplier documents and produce a risk summary. A single agent reading all 40 documents would fill its context with raw text and lose track of the goal.

A better design:

The lead agent lists the documents and splits them into batches of five.

Each batch goes to a reader subagent on a cheaper, faster model with one instruction: extract risks as a fixed JSON structure (supplier, risk type, severity, quote, page). Subagents run in parallel and return only their JSON.

The lead merges results, de-duplicates, ranks by severity, and writes the summary. Why it works: the lead's context holds 40 compact JSON results instead of 40 documents, reading runs in parallel, and the structured hand-off format prevents information loss at the boundary. The cost is more total tokens than a single pass, which is acceptable because each document is read once by a cheaper model.

Worked example 2.6: hooks for deterministic behavior

A team's coding agent occasionally runs git push to the main branch. The system prompt already says not to. What should they add?

A PreToolUse hook on the Bash tool that inspects the command and denies anything matching git push to protected branches. In the Agent SDK the hook is a function registered under PreToolUse with a matcher for Bash; it returns a decision of deny with a reason that the agent sees. In Claude Code the same logic is a shell command configured in settings.json that exits with a blocking status code.

The principle the exam is testing: prompts express intent; hooks enforce policy. Keep the system-prompt line too, so the agent does not keep trying, but the hook is what makes the rule true.

Scenario drills

Answer each in one sentence, then compare.

A startup wants a demo agent running by Friday with file editing and shell access on a developer laptop. Which build approach is fastest? A product manager asks for "an agent" to send a weekly metrics email built from the same three SQL queries. What do you recommend?

A lead agent's final report omits findings that subagents clearly discovered. Name the most likely cause and a fix.

A long-running research agent must run every night and keep notes between runs, without the team operating servers. Which option fits?

A team built on LangGraph cannot tell which prompt produced a bad step. What is a sensible first move?

An agent calls the same search tool 30 times with near-identical queries. Name two fixes. Answers:

The Claude Agent SDK (or Claude Code itself), because file and shell tools are built in. A scheduled workflow: three queries, one summarization call, one send step. No agent loop is needed.

Unstructured or overly long subagent hand-offs; require a fixed result schema and make the lead's synthesis step explicitly cover every result.

Claude Managed Agents with a scheduled deployment and a memory store.

Add tracing that logs each node's full prompt and response; if the framework hides too much, reimplement the failing step with direct API calls.

Return richer, de-duplicated results with a note of what was already searched, and cap tool calls per task (or add a task budget).

Common traps

Choosing an autonomous agent for a fixed, predictable process. A workflow is cheaper, faster, and easier to test.

Putting a must-always rule ("never delete production files") only in the system prompt. Use a hook or permission rule.

Assuming more agents means better results. Multi-agent systems multiply token cost.

Confusing the Agent SDK (self-hosted harness) with Managed Agents (Anthropic-hosted). Dropping failed tool results from the conversation instead of returning them as errors.

Check yourself

An invoice pipeline always runs: extract fields, validate totals, write to the ERP. Workflow or agent, and which pattern? A research assistant must investigate an unknown number of sources and keep its main context small. Which architecture fits?

A team wants an agent with built-in file and bash tools, running in their own VPC. Which option fits?

Where should "always run the linter after a file edit" live?

Name two costs of a multi-agent design.

Answers: A workflow using prompt chaining with validation gates. A lead agent delegating to subagents (orchestrator-workers), each returning summaries. The Claude Agent SDK, self-hosted. A PostToolUse hook. Higher token usage and information loss or coordination overhead between agents.

Use ← → to move between sections