Agentic Architecture & Orchestration
Everything Domain 1 tests: the agentic loop, stop_reason handling, tool execution, task decomposition, multi-agent topologies, subagents with isolated context, session state, and lifecycle hooks. Every concept comes with the real request, response, or code — because that is how the exam frames its questions.
1.1 The agentic spectrum: workflow vs agent
The exam's first trap is definitional. Anthropic draws a hard line between two ways of using an LLM in a system, and several questions hinge on picking the right side of it:
| Workflow | Agent | |
|---|---|---|
| Control flow | Predefined by your code — the LLM fills in steps you orchestrated | Decided by the model at runtime — Claude chooses which tools to call, in what order, and when to stop |
| Best when | The task is well-defined and repeatable (classify, extract, route) | The path to the goal is unknown in advance (debug this failure, resolve this ticket) |
| Cost / latency | Predictable | Open-ended — must be bounded with max iterations, budgets, timeouts |
| Failure mode | Brittle when input varies | Runaway loops, tool misuse, unbounded spend |
The architect's rule the exam rewards: use the simplest pattern that solves the problem. If a fixed prompt chain hits the quality bar, an agent is the wrong answer — even though this is an "agents" certification. Distractors love to offer an impressive multi-agent design for a task a single prompt handles.
1.2 The agentic loop — the pattern behind every question
Every agent, from a support bot to Claude Code itself, runs the same four-beat loop: send request → check stop_reason → execute tool → return result → repeat. You must be able to read this loop in raw API terms.
Beat 1 — the request declares tools
POST /v1/messages
{
"model": "claude-sonnet-5",
"max_tokens": 4096,
"tools": [{
"name": "get_order_status",
"description": "Look up the current status, carrier and ETA of a customer order by its order ID. Use when the customer asks where their order is.",
"input_schema": {
"type": "object",
"properties": { "order_id": { "type": "string" } },
"required": ["order_id"]
}
}],
"messages": [
{ "role": "user", "content": "Where is my order ORD-8813?" }
]
}Beat 2 — Claude answers with a tool call, not text
{
"role": "assistant",
"stop_reason": "tool_use",
"content": [
{ "type": "text", "text": "I'll check that order for you." },
{ "type": "tool_use",
"id": "toolu_01A9x",
"name": "get_order_status",
"input": { "order_id": "ORD-8813" } }
]
}The stop_reasonfield is the loop's steering wheel. Memorise the values — the exam tests them directly:
| stop_reason | Meaning | Your code should |
|---|---|---|
tool_use | Claude wants a tool executed | Run the tool, append a tool_result, call the API again |
end_turn | Claude finished its answer | Exit the loop, return the response |
max_tokens | Output was truncated at the limit | Treat as incomplete — never parse truncated JSON as success |
stop_sequence | A custom stop string was hit | Handle per your protocol |
refusal | Claude declined the request | Surface gracefully; do not blind-retry |
pause_turn | A server-tool loop hit its iteration limit mid-turn | Resend the assistant response as-is to let Claude resume |
model_context_window_exceeded | The context window itself was exhausted (distinct from max_tokens) | Treat as incomplete; trim or restructure context, then retry |
This is the complete current list of seven values — the exam may test any of them, not just the four or five that show up in a first tutorial.
Beats 3+4 — execute, return, repeat, and always bound the loop
import anthropic
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Where is my order ORD-8813?"}]
MAX_ITERATIONS = 10 # an unbounded agent loop is a production incident
for _ in range(MAX_ITERATIONS):
resp = client.messages.create(
model="claude-sonnet-5", max_tokens=4096,
tools=TOOLS, messages=messages)
if resp.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": resp.content})
results = []
for block in resp.content:
if block.type == "tool_use":
results.append({
"type": "tool_result",
"tool_use_id": block.id, # must match the tool_use id
"content": run_tool(block.name, block.input)})
messages.append({"role": "user", "content": results}) # results go back as a USER turn
continue
break # end_turn (or refusal / max_tokens) exits the loopassistant message, or forgetting tool_use_id. Tool results are content blocks inside the next user turn, correlated by ID. Any answer choice that breaks that contract is wrong.Deep dive: why the loop must be bounded three ways
Production agent loops are bounded by (1) iteration count — a hard ceiling on round trips; (2) budget — cumulative token or dollar spend per session; (3) wall clock— user-facing latency SLA. The exam expects you to know that model self-restraint is not a control: an agent that "usually stops" is an unbounded agent. Bounds live in code, never in the prompt.
1.3 Executing tools correctly: parallel calls and error results
Two execution details separate passing candidates from failing ones.
Parallel tool use
Claude can emit multiple tool_useblocks in one assistant turn when calls are independent (e.g. "check the order status AND the refund policy"). Your loop must execute all of them and return all results in a single user turn, one tool_result block per tool_use_id. Returning them across separate turns breaks the correlation and is a recurring distractor.
Errors are data, not exceptions
When a tool fails, you do not crash the loop and you do not silently return an empty string. You return a structured error to the model so it can reason about recovery:
{
"type": "tool_result",
"tool_use_id": "toolu_01A9x",
"is_error": true,
"content": "Order lookup failed: ORDER_NOT_FOUND. The order ID may be
mistyped. Valid IDs look like ORD-#### . Ask the customer to re-check."
}Note what that error contains: an error category, a hint about whether retrying makes sense, and a suggested next action. Claude reads error text like instructions — a good error message is self-healing behaviour for free.
""or omitting the failed call entirely makes the agent hallucinate a success path. Exam answers that "skip the failed tool and continue" are wrong; answers that return structured error context are right.1.4 Task decomposition: when to break work apart
Decomposition questions give you a big task and four ways to split it. The scoring logic behind the correct answers:
- Decompose when subtasks need different context. A research task over 40 documents cannot fit one context window; each reader gets its slice, a synthesiser gets the summaries.
- Decompose when subtasks need different tools or permissions. The agent that reads production logs should not be the agent that writes code — scoping is decomposition.
- Decompose when steps have different quality bars. A cheap model drafts, a strong model reviews (multi-pass beats one giant pass).
- Do NOT decompose when the task is sequential and shares one evolving state. Splitting a refactor across agents that each hold partial state creates merge conflicts and lost context — keep it in one session.
Output contracts make decomposition work: each subtask returns a structured summary (facts, decisions, open issues), never its raw transcript. The coordinator reasons over summaries; shipping full transcripts upward recreates the context problem you decomposed to escape.
1.5 Multi-agent topologies: hub-and-spoke wins
When one agent is not enough, the exam recognises exactly one blessed shape: a coordinator (hub) that owns the goal, delegates bounded subtasks to specialist subagents (spokes), and synthesises their results. Spokes never talk to each other.
Why flat (peer-to-peer) topologies are anti-pattern #7:
- No single owner of "done." Peers can ping-pong work forever; the hub decides completion.
- N² communication paths means N² places context gets corrupted or duplicated.
- Debugging dies. With a hub, every decision has one audit point; with peers, causality is spread across transcripts.
- Error propagation becomes untraceable — a hallucination introduced by one peer laundered through another looks like independent confirmation.
1.6 Subagents and context isolation
A subagent is a fresh context window with its own system prompt, its own restricted tool set, and a one-shot task. In Claude Code / the Agent SDK this is the Agent tool (renamed from Task in Claude Code v2.1.63 — Task(...) still works as a legacy alias, so both names appear in the wild): the parent spawns a subagent, the subagent works in isolation, and only its final report returns to the parent.
Three properties the exam tests:
- Isolation is the feature.The subagent's exploration (50 file reads, dead ends, noise) never pollutes the parent's context. The parent pays only for the conclusion.
- Tool scoping happens per subagent. A read-only research subagent gets Read/Grep/Glob and nothing else. Giving every agent every tool is anti-pattern #6 — it bloats reasoning and widens blast radius.
- Communication is a contract.The parent's prompt to a subagent must be self-contained (the subagent has no memory of the conversation), and it should specify the shape of the report it wants back.
In Claude Code, custom subagents are Markdown files with frontmatter — this exact syntax appears in questions:
# .claude/agents/security-auditor.md
---
name: security-auditor
description: Reviews code changes for security issues. Use after any
change that touches auth, input handling, or file access.
tools: Read, Grep, Glob # read-only: an auditor never edits
---
You are a security auditor. Examine the changed files for injection,
authz bypass, and unsafe file handling. Report findings as a list of
{file, line, issue, severity}. If nothing is found, say so explicitly.1.7 Session state management
The API is stateless: every request re-sends the whole conversation. "Session state" is therefore an architecture decision you make, and the exam asks where each kind of state belongs:
| State | Where it lives | Why |
|---|---|---|
| Conversation turns | Your message array / SDK session | Replayed each request; prompt caching makes the replay cheap |
| Durable facts (customer ID, verified identity, decisions made) | External store (DB/file), re-injected into the system prompt | Survives compaction, restarts and handoffs |
| Working notes in long tasks | Scratchpad files the agent writes and re-reads | Context windows overflow; files do not |
| Cross-agent state | Passed explicitly in delegation prompts / reports | Subagents share no memory — anything unstated is unknown |
The recurring scenario: a support agent verified the customer's identity in turn 2; the conversation is compacted at turn 40; the agent asks the customer to verify again (bad) or worse, assumes verification (dangerous). The correct architecture extracted "identity verified, account #, case facts" into durable state at the moment it happened, and re-injects it every request.
1.8 Lifecycle hooks: rules that cannot be talked out of
Hooks are deterministic scripts that fire at fixed points of the agent lifecycle — PreToolUse (can block a tool call before it runs), PostToolUse (react to a result: format, lint, log), plus session-level events. The architectural point the exam hammers: a hook is enforcement; a prompt is a suggestion.
// .claude/settings.json - block edits to production config, always
{
"hooks": {
"PreToolUse": [{
"matcher": "Edit|Write",
"hooks": [{ "type": "command",
"command": "python check_protected_paths.py" }]
}],
"PostToolUse": [{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "npx prettier --write" }]
}]
}
}If the requirement contains words like must never / always / compliance / policy, the answer is a hook (or permission rule), not a CLAUDE.md instruction. Prompts steer probability; hooks remove it. That is anti-pattern #1 in one sentence.
Checkpoint quiz — Domain 1
Exam-style: one scenario, one correct answer, three plausible mistakes. Click an option to lock in and see the explanation.
Your support agent calls get_order_status and the warehouse API times out. What should the tool layer return to Claude?
In a coordinator + 4-subagent research system, the analysis subagent needs the search subagent's findings. How should they flow?
Company policy: Claude must never write to infra/prod/. Where does this rule belong?
A team wants to pull 6 fixed fields out of uniform vendor invoices, 500/day. The architecturally correct starting point is:
Turn 3: customer's identity verified. Turn 45: the long conversation gets compacted. How should the architecture have protected the verification fact?
Quick glossary
Every term below appears somewhere in this course. If a question uses a word you're unsure of, check here before re-reading the whole lesson.
Agentic loop
The repeating cycle behind any Claude-powered agent: send a request, check what Claude wants to do next (stop_reason), run a tool if asked, send the result back, repeat until Claude is done.
stop_reason
A field on Claude's response telling your code why it stopped talking — e.g. it wants to call a tool (tool_use), it finished (end_turn), or it ran out of room (max_tokens).
tool_use / tool_result
tool_use is Claude asking your code to run something (a search, a database lookup...). tool_result is your code's answer, sent back so Claude can continue.
Subagent / Agent tool
A helper Claude spawns to do one focused piece of work in its own separate memory space, then reports back a summary — so the main conversation doesn't get cluttered with the helper's scratch work.
Hooks (PreToolUse / PostToolUse)
Small scripts that run automatically around a tool call — one right before it (can block it entirely) and one right after (can react to the result). Used for rules that must always hold, not just usually hold.
MCP (Model Context Protocol)
A standard way to connect Claude to external systems — databases, internal tools, company APIs — through a shared plug-in format instead of custom one-off code every time.
MCP Tools vs Resources vs Prompts
The three things an MCP connection can offer: Tools are actions Claude decides to call itself; Resources are data the surrounding app decides to hand Claude; Prompts are ready-made instructions a person picks, like a menu option.
.mcp.json
A config file listing which external MCP connections a project uses — shared with the whole team via version control, with any secret keys kept out of it and read from environment variables instead.
CLAUDE.md
A plain-text file Claude reads automatically at the start of every session in a project — the place for standing instructions like coding conventions or how the codebase is organized.
.claude/rules/
Instructions that only switch on for certain files (e.g. only when editing test files), instead of loading into every single session the way CLAUDE.md does.
Agent Skill
A packaged set of instructions Claude loads by itself when a task matches, without anyone typing a command — think of it as an instruction manual Claude picks up automatically off the shelf.
allowed-tools vs disallowed-tools
Two different settings that sound alike: allowed-tools just skips the usual 'are you sure?' prompt for tools you've pre-approved — it doesn't block anything else. disallowed-tools is what actually removes a tool from what's available.
Plan mode
A mode where Claude describes what it's about to do and waits for a yes before touching any files — used for bigger or riskier changes, skipped for small obvious ones.
Message Batches API
A cheaper way to send Claude a large pile of requests when nobody is waiting on the answer right away — costs about half as much, but can take up to a day to come back.
Prompt caching
A way to avoid Claude re-reading the same large, unchanging block of text (like a system prompt or a codebase) on every single request — it's remembered for a while, which is both cheaper and faster.
Context window
The total amount of conversation and text Claude can 'see' at once for a given request. When a conversation runs long, older parts may need to be summarized or dropped to make room.
Hub-and-spoke (multi-agent)
A setup where one coordinator agent hands out tasks to several helper agents and collects their answers — the helpers never talk directly to each other, only to the coordinator.
Anti-pattern
A design choice that looks reasonable but causes real problems in practice — this course names seven specific ones the exam likes to hide inside wrong answers.