Studying Agentic Architecture and Orchestration: the CCA Exam's Largest Domain
Agentic Architecture & Orchestration is worth 27% of the CCA Foundations exam, more than any other domain.
It covers how you design systems where Claude doesn't just answer one question, but plans, calls tools, hands work to other agents, and decides when it's done.
This article walks through the orchestration patterns that show up most often in exam scenarios, with runnable Python illustrations built on the anthropic SDK.
Summary
Multi-agent systems trade simplicity for capability, and the exam tests whether you know when that trade is worth making.
A single well-scoped agent with good tools beats a poorly decomposed multi-agent system almost every time.
The core patterns worth knowing are sequential pipelines, supervisor-worker topologies, and parallel fan-out with a merge step.
Every pattern needs an explicit termination condition, or it risks looping past the point of being useful.
Orchestration questions on the exam usually hinge on picking the smallest architecture that solves the problem, not the most sophisticated one.
Recipe
Quick-reference recipe card - the minimal shape of a supervisor-worker loop.
from anthropic import Anthropic
client = Anthropic()
def run_worker(task: str, model: str = "claude-sonnet-5") -> str:
"""A single-purpose worker agent that does one job and returns."""
response = client.messages.create(
model=model,
max_tokens=1024,
system="You are a focused worker agent. Do exactly the task given. Return only the result.",
messages=[{"role": "user", "content": task}],
)
return response.content[0].text
def run_supervisor(goal: str, max_steps: int = 5) -> str:
"""A supervisor that decomposes a goal into worker tasks and stops on completion."""
completed_work = []
for step in range(max_steps):
plan_prompt = f"Goal: {goal}\nCompleted so far: {completed_work}\nNext single subtask, or DONE if finished:"
plan = run_worker(plan_prompt, model="claude-sonnet-5")
if plan.strip().upper().startswith("DONE"):
break
result = run_worker(plan)
completed_work.append({"task": plan, "result": result})
return "\n".join(w["result"] for w in completed_work)When to reach for this:
- The goal decomposes naturally into a small, bounded number of independent subtasks.
- Each subtask benefits from a narrower system prompt than the overall goal would need.
- You need an explicit stop condition rather than an open-ended conversation.
- You're willing to pay the latency and cost of multiple model calls for better task isolation.
Working Example
from anthropic import Anthropic
from dataclasses import dataclass
client = Anthropic()
@dataclass
class AgentResult:
agent_name: str
output: str
def draft_agent(topic: str) -> AgentResult:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
system="You draft a short technical outline. Return only the outline, no preamble.",
messages=[{"role": "user", "content": f"Outline: {topic}"}],
)
return AgentResult("draft", response.content[0].text)
def critic_agent(draft: str) -> AgentResult:
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=512,
system="You critique a technical outline for gaps and factual risk. Be terse. Return only the critique.",
messages=[{"role": "user", "content": draft}],
)
return AgentResult("critic", response.content[0].text)
def reviser_agent(draft: str, critique: str) -> AgentResult:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=768,
system="You revise a draft outline given a critique. Return only the revised outline.",
messages=[{"role": "user", "content": f"Draft:\n{draft}\n\nCritique:\n{critique}"}],
)
return AgentResult("reviser", response.content[0].text)
def orchestrate_draft_critique_revise(topic: str) -> str:
"""A three-agent sequential pipeline: draft -> critic -> reviser.
Each agent has one job and a narrow system prompt, which is the
pattern the exam calls 'single-responsibility agent design.'
"""
draft = draft_agent(topic)
critique = critic_agent(draft.output)
final = reviser_agent(draft.output, critique.output)
return final.output
if __name__ == "__main__":
result = orchestrate_draft_critique_revise("Zero-downtime database migration strategy")
print(result)What this demonstrates:
- A sequential pipeline where each agent's output becomes the next agent's input, with no shared mutable state.
- Deliberate model mixing: a stronger model (Opus 4.8) for the critique step, where judgment quality matters most, and a faster model (Sonnet 5) for drafting and revision.
- Single-responsibility system prompts per agent, which the exam tests as a design principle distinct from prompt engineering itself.
- No loop or termination logic needed here, because the pipeline has a fixed, known length, which is itself a design choice worth recognizing.
Deep Dive
How It Works
- A sequential pipeline passes output forward through a fixed chain of agents; it's the right shape when the number of steps is known in advance.
- A supervisor-worker topology has one agent plan and dispatch, and one or more worker agents execute; it's the right shape when the number of steps is not known until runtime.
- A parallel fan-out dispatches the same or related subtasks to multiple agents concurrently, then merges results; it's the right shape when subtasks are independent and latency matters more than sequencing.
- Every non-trivial orchestration needs an explicit termination condition: a step budget, a "DONE" signal the supervisor can emit, or a validation check that confirms the goal is met.
- Context handoff between agents is a design decision, not a given: pass only what the next agent needs, not the entire conversation history, or you inflate every downstream call's token cost.
Orchestration Patterns at a Glance
| Pattern | Shape | Best for | Termination |
|---|---|---|---|
| Sequential pipeline | A -> B -> C | Known, fixed number of transformation steps | Fixed length, no loop needed |
| Supervisor-worker | Supervisor plans, dispatches to workers | Unknown subtask count, decomposable goals | Supervisor emits DONE or hits step budget |
| Parallel fan-out | One dispatcher, N concurrent workers, one merge | Independent subtasks, latency-sensitive | All workers return, or a timeout fires |
| Single agent + tools | One agent, multiple tool calls in one loop | Most production tasks; simplest to reason about and debug | Agent stops requesting tools |
Termination and Loop Safety
MAX_STEPS = 8
def safe_supervisor_loop(goal: str) -> str:
step = 0
history = []
while step < MAX_STEPS:
step += 1
next_action = run_worker(f"Goal: {goal}\nHistory: {history}\nNext step or DONE:")
if "DONE" in next_action.upper():
break
history.append(next_action)
else:
# Loop exhausted MAX_STEPS without a DONE signal - treat as a failure, not a success.
raise RuntimeError(f"Supervisor did not terminate within {MAX_STEPS} steps for goal: {goal}")
return "\n".join(history)A hard step budget combined with an explicit failure path (rather than silently returning a partial result) is the pattern the exam rewards: an agent that can't tell you it failed is worse than one that raises.
Python Notes
# Prefer typed dataclasses or TypedDicts for inter-agent payloads over raw dicts,
# so a schema mismatch between agents fails fast instead of surfacing as a
# confusing downstream prompt-formatting bug.
from typing import TypedDict
class SubtaskResult(TypedDict):
agent: str
task: str
output: strGotchas
- Adding a second agent when a bigger tool would do. A single agent with a well-designed tool often replaces a whole "helper agent." Fix: try expanding the tool surface before you reach for orchestration.
- No termination condition on a supervisor loop. Left unbounded, a planning loop can run until it exhausts budget or context. Fix: always set a hard step ceiling and treat exceeding it as a raised error, not silent truncation.
- Passing full conversation history to every worker. This multiplies token cost linearly with pipeline depth for no benefit. Fix: pass only the specific fields the next agent actually needs.
- Using the same model and system prompt for every agent in the pipeline. This wastes the chance to match model strength to task difficulty. Fix: reserve a stronger model for judgment-heavy steps like critique or synthesis.
- Treating parallel fan-out as free. Concurrent calls still consume rate limits and cost the same per-call price; fan-out reduces latency, not cost. Fix: size the fan-out to actual independent subtask count, not for its own sake.
- No merge strategy defined before fan-out starts. If you don't know how you'll reconcile conflicting worker outputs, you'll improvise it badly under pressure. Fix: design the merge (for example, "supervisor arbitrates," "majority vote," "concatenate") before dispatching.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Single agent with a tool loop | The task is bounded and one agent with tools can reason through it end to end | The task genuinely requires distinct roles or independent parallel work |
| Sequential pipeline | Steps and their order are known ahead of time | The number or order of steps depends on intermediate results |
| Supervisor-worker | Subtask count is unknown until runtime and the goal decomposes cleanly | The goal is simple enough that decomposition adds overhead without benefit |
| Parallel fan-out | Subtasks are independent and latency matters more than coordination cost | Subtasks depend on each other's output, which forces you back to sequential |
FAQs
Why is this domain worth more than any other on the exam?
Because orchestration decisions (single agent vs. multi-agent, which topology, how termination is handled) tend to be the decisions that make or break a production system's reliability, more than any single prompt or tool definition does.
Is a multi-agent system always more capable than a single agent?
No. A single well-scoped agent with good tools is often more reliable and cheaper than a poorly decomposed multi-agent system; the exam specifically tests judgment about when multi-agent adds real value versus just coordination overhead.
What's the difference between a sequential pipeline and a supervisor-worker pattern?
- A sequential pipeline has a fixed, known chain of steps decided at design time.
- A supervisor-worker pattern has a planner that decides the next step at runtime, because the subtask count isn't known in advance.
How do I know when an agent loop needs a hard step limit?
Any loop where the exit condition depends on the model's own output (like emitting "DONE") needs a hard step ceiling as a backstop, since a model can fail to emit that signal.
Should every agent in a pipeline use the same model?
Not necessarily. Matching a stronger model to judgment-heavy steps (like critique or synthesis) and a faster model to mechanical steps (like drafting or formatting) is a cost-and-quality trade-off the exam expects you to reason about.
What does "context handoff" mean in orchestration design?
It refers to deciding exactly what information passes from one agent to the next, rather than defaulting to passing the entire conversation history, which inflates token cost with every additional agent in the chain.
Is parallel fan-out cheaper than sequential processing?
No, it's typically not cheaper. Fan-out reduces wall-clock latency by running independent calls concurrently, but each call still costs the same in tokens; don't confuse "faster" with "cheaper."
What's a common mistake candidates make when answering orchestration questions?
Defaulting to the most complex architecture (multi-agent, multi-step) when a single agent with better tool design solves the scenario more reliably and cheaply.
How does this domain relate to Tool Design & MCP Integration?
They overlap heavily: whether an agent needs a helper agent or just a better tool is itself an orchestration decision, and a badly scoped tool often masquerades as an "orchestration problem" on the exam.
What should a merge step do when parallel workers disagree?
The merge strategy should be decided before dispatch, whether that's a supervisor arbitrating between outputs, majority vote, or straightforward concatenation, rather than improvised after the fact.
Does the exam expect me to memorize specific orchestration frameworks?
The domain tests the underlying patterns (sequential, supervisor-worker, parallel fan-out, single-agent-plus-tools) and the judgment behind choosing between them, not memorization of any particular third-party framework's API.
Why does the working example use a dataclass for inter-agent payloads?
Typed payloads make schema mismatches between agents fail fast and visibly, instead of surfacing later as a confusing formatting bug inside a downstream prompt.
Related
- What the Claude Certified Architect Exam Actually Tests - the overall exam mental model this domain fits into.
- CCA Foundations Exam Domains at a Glance - where this 27% domain sits relative to the other four.
- Tool Design, MCP Integration, and Context Management: CCA Domain Checklist - the tool-design decisions that often determine whether orchestration is even necessary.
- Case Study: Building a Production Customer Support Agent End to End - these orchestration patterns applied to a full production build.
- CCA Foundations Best Practices - practical guidance for applying orchestration patterns to real builds.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the official
anthropicPython SDK (latest 0.x release). Model names, pricing, exam format, and SDK versions move quickly - verify current specifics at platform.claude.com/docs and the official CCA exam guide before relying on them.