CCAR-F Claude Certified Architect — Foundations

Chapter 03 — Multi-Agent Orchestration

Domain 1: Agentic Architecture & Orchestration (27%) — task statements 1.2, 1.3, 1.7

This is the densest chapter in the book and covers the highest-yield material on the exam. Scenario 3 (Multi-Agent Research System) is built entirely on it, and Scenarios 1 and 4 draw on it heavily.


1. The coordinator–subagent pattern

The architecture is hub-and-spoke. One coordinator owns the task; specialized subagents do bounded pieces of work and report back.

                    ┌──────────────┐
          ┌────────▶│  coordinator │◀────────┐
          │         └──────────────┘         │
          │            ▲       ▲             │
          ▼            │       │             ▼
   ┌────────────┐  ┌───┴────┐ ┌┴─────────┐  ┌──────────────┐
   │ web-search │  │  doc-  │ │synthesis │  │   report-    │
   │            │  │analysis│ │          │  │  generation  │
   └────────────┘  └────────┘ └──────────┘  └──────────────┘

🎯 The two structural rules

Rule 1: all inter-subagent communication routes through the coordinator. Subagents don't talk to each other. If the synthesis agent needs what the web-search agent found, the coordinator passes it. There is no side channel — spokes connect only to the hub.

Rule 2: subagents have isolated context and do not inherit the parent's history. This is the single most tested fact in Domain 1. A subagent starts fresh. It does not see:

  • the user's original request
  • the coordinator's reasoning
  • earlier subagents' outputs
  • any tool results the coordinator has accumulated

It sees only what the coordinator puts in its prompt.

⚠️ The trap here is subtle: the isolation is a feature, not a bug. It's what keeps a 200-file codebase exploration from flooding the coordinator's context. Options that propose "share the full conversation history with all subagents" are wrong on both counts — it isn't how the mechanism works, and it would destroy the benefit.

Consequences you must be able to derive

Because subagents are isolated… …you must
They don't know the user's actual question Restate the goal and constraints in every subagent prompt
They don't know what other subagents covered Partition scope explicitly to prevent duplicated work
They don't have IDs, filenames, or prior findings Pass those values literally in the prompt
Their output is all the coordinator gets Specify the return format; ask for structured data, not verbose reasoning

2. Decomposition quality — the coordinator's job

The coordinator's decomposition is where multi-agent systems actually fail, and the exam knows it.

🚫 Overly narrow decomposition

The guide's canonical failure: a research request produces an incomplete report. The logs show every subagent completed successfully and returned good work — but the coordinator only ever created subtasks in one narrow slice of the topic (its example: a broad arts query decomposed into only visual-arts subtasks).

The diagnosis is the coordinator, not the subagents. Every subagent did its job correctly within the scope it was given. The scope was wrong.

🎯 This is a repeating item pattern. Whenever a stem tells you the subagents succeeded and the output is still incomplete, look at what the coordinator asked for. The distractors will offer to improve the subagents' prompts, add more subagents, or increase their context — all of which fix a component that isn't broken.

Techniques the coordinator should apply

Scope partitioning. Assign each subagent a disjoint slice, stated explicitly: "cover regulatory filings only; another agent is handling press coverage." Without this, isolated subagents converge on the same obvious sources.

Dynamic subagent selection. Choose which specialists to spawn based on the request, rather than always running the full roster. A question with no document corpus doesn't need the document-analysis agent.

Iterative refinement loops. After collecting results, the coordinator evaluates coverage against the original goal and re-delegates to fill gaps. One round of fan-out then synthesis is the naive version; the coordinator should be able to say "the competitive-landscape dimension is thin, spawn another pass on it." This is the direct structural remedy for narrow decomposition.

Goal-oriented prompts over procedural ones. Tell the subagent what a good result looks like, not the steps to produce it:

❌ "Search for the company name, then open the top three results, then extract revenue figures."

✅ "Establish this company's revenue for FY2025 with at least two independent sources. Report each figure with its source URL and publication date. If sources disagree, report all values with attribution rather than choosing one."

The second version lets the subagent adapt its path while making the quality bar checkable. The exam consistently prefers goal-and-criteria prompts over step lists for subagents.


3. Invoking subagents — the Task tool

📎 The mechanism: the coordinator spawns subagents by calling the Task tool.

Two facts that appear as items:

  1. allowedTools for the coordinator must include "Task". If the coordinator can't call Task, it can't delegate — and the symptom is that it silently tries to do all the work itself. This is a classic "why isn't delegation happening" item.
  2. Parallel subagents are launched by emitting multiple Task tool calls in a single coordinator response. Sequential Task calls across successive turns run serially. If an item asks how to parallelize independent research streams, the answer is multiple Task calls in one turn — not threads, not async in your own code, not a separate orchestration service.
# Coordinator configuration sketch
options = {
    "allowedTools": ["Task", "Read", "Grep"],   # Task is required to delegate
    "agents": {
        "web-research": AgentDefinition(
            description="Searches the public web for current information on a "
                        "named topic. Use for market data, news, and public filings.",
            prompt="You are a web research specialist. Return findings as a JSON "
                   "list of {claim, source_url, publication_date}. Do not "
                   "summarize or interpret — report claims with provenance.",
            tools=["WebSearch", "WebFetch"],     # scoped: no file access
        ),
        "document-analysis": AgentDefinition(
            description="Extracts and verifies claims from documents already "
                        "present in the workspace. Use when the user supplied files.",
            prompt="You are a document analyst. For each requested data point, "
                   "return {value, source_file, page_or_section, verbatim_quote}. "
                   "If a data point is absent, return null — never infer it.",
            tools=["Read", "Grep", "Glob"],      # scoped: no web access
        ),
    },
}

AgentDefinition — the three things it carries

Field Purpose 🎯 Why the exam cares
description Tells the coordinator when to select this subagent This is tool-description logic applied to agents: overlapping descriptions cause the coordinator to pick the wrong specialist
prompt (system prompt) Defines the subagent's role, standards, and output format This is where you compensate for context isolation and pin the return shape
tools / tool restrictions Limits what this subagent can do Least privilege (Reflex 4); prevents agents from wandering outside their specialization

⚠️ Note the symmetry: a subagent's description is to the coordinator what a tool's description is to the model. Every principle in Chapter 05 about description quality applies here too. If the coordinator keeps routing document questions to the web-research agent, fix the descriptions.

Explicit context passing

Because of isolation, the delegating prompt carries the payload:

Task(
  subagent_type="document-analysis",
  prompt="""
  Goal: determine the total contract value in the supplied MSA.

  Context you need (you do not have access to prior conversation):
  - Customer ID: CUST-88213
  - The MSA is at contracts/2025/msa-88213.pdf
  - A previous pass found a stated total of $1.2M in the executive summary,
    but the schedule of fees was not checked.
  - Another agent is handling the SOW documents. Do not read those.

  Return: {stated_total, computed_total_from_schedule, conflict_detected, source_pages}
  """
)

Every element there exists because the subagent can't get it any other way: the identifier, the path, the prior finding, the scope boundary, and the return shape.


4. Session state and continuity

Task statement 1.7. Small surface, reliably tested.

📎 Mechanism What it does
--resume <session-name> Continues a previously saved session with its full history
fork_session Branches from an existing session, so the original is preserved and the branch explores independently
Fresh session + structured summary Starts clean, seeded with a hand-built summary of what matters

🧠 The judgement the exam wants

Resume when the history is still true. Continuing a coherent multi-day task where the workspace hasn't changed underneath you.

Fork when you want to try a variant without losing the original. Two candidate refactors from the same analysis point; parallel exploration from a shared baseline.

Start fresh with a structured summary when the old session's tool results are stale. This is the tested case. A session from yesterday holds file contents that have since changed, directory listings that are wrong, and test output that no longer applies. Resuming it means the model reasons over stale tool results it believes are current — and the guide is explicit that a fresh session seeded with a structured summary beats resuming with stale results.

⚠️ Partial credit trap: "inform the resumed session that files have changed" is a real mitigation and will appear as an option. It's weaker than starting fresh, because the stale content is still in the context competing for attention — you've added a correction, not removed the wrong data. Prefer it only when the stem says the history contains something expensive and irreplaceable.


5. Worked examples

Example 1 — narrow decomposition

A multi-agent research system produces reports that reviewers describe as "thin" and missing whole aspects of the requested topic. Investigation of the execution logs shows that every subagent returned complete, well-sourced results for the subtask it was assigned, and no subagent reported an error. The subtasks assigned all concerned one narrow facet of the topic. What is the most likely root cause?

A. The subagents' system prompts are too restrictive. B. The coordinator is decomposing the request too narrowly. C. The synthesis agent is discarding relevant findings. D. The subagents lack sufficient context window to cover the full topic.

Answer and reasoning

B.

The stem rules out every downstream component explicitly: subagents returned complete results, no errors, and the subtasks themselves were narrow. Work that was never assigned cannot be recovered by any downstream agent.

  • A — Restrictive prompts would show up as subagents refusing or under-delivering on their assigned subtask. They delivered fully.
  • C — The synthesis agent can only work with what it receives. If the missing aspects were never researched, discarding isn't the failure.
  • D — The more context distractor. Context size doesn't determine which subtasks get created; the coordinator does.

Fix direction: scope partitioning across the topic's dimensions, plus an iterative refinement loop where the coordinator checks coverage against the original request and re-delegates gaps.

Reflex applied: #5 and the layer-diagnosis table — subagents healthy + output incomplete = coordinator decomposition.

Example 2 — parallelization

The coordinator in a research system currently issues one Task call per turn, waiting for each subagent to finish before starting the next. Four research streams are fully independent. How should the architect enable them to run concurrently?

A. Emit multiple Task tool calls within a single coordinator response. B. Set parallel: true in the coordinator's AgentDefinition. C. Run four separate coordinator processes and merge their outputs. D. Increase the coordinator's max_tokens so it can plan all four at once.

Answer and reasoning

A.

Concurrency comes from the model emitting several tool_use blocks for Task in one assistant turn; the harness executes them in parallel and returns all results together.

  • B — No such field. Non-existent-surface distractor (Chapter 01 §5).
  • C — Works in a sense, but abandons coordination entirely: no shared scope partitioning, no gap re-delegation, and you now own the merge. Over-engineered and structurally worse.
  • Dmax_tokens bounds output length, not execution concurrency.

Reflex applied: #2 (smallest correct mechanism) plus knowing the actual Task-tool semantics.


6. Decision reflexes (reproduce from memory)

  • Hub-and-spoke: all subagent-to-subagent communication goes through the coordinator.
  • Subagents inherit nothing. Restate goal, IDs, paths, prior findings, scope boundary, and return format in every delegating prompt.
  • Subagents healthy + output incomplete → coordinator decomposition. Fix with scope partitioning and iterative re-delegation.
  • Delegation happens via the Task tool; the coordinator's allowedTools must include "Task".
  • Parallelism = multiple Task calls in one response.
  • AgentDefinition = description (for coordinator routing) + prompt (role, standards, output shape) + scoped tools (least privilege).
  • Give subagents goals and quality criteria, not procedural step lists.
  • --resume when history is still true · fork_session to branch without losing the original · fresh session + structured summary when tool results are stale.