P3.3 deep dive · D1 + D2 · Agentic Architectures

Coordinator Routing.

How the coordinator decomposes a research query and dispatches subtasks across the hub-and-spoke topology.

6 prose blocks·4 decisions·5 failure modes·4 exam Qs

The coordinator owns semantic decomposition (not lexical), enumerates every relevant sub-domain before spawning anything, and dispatches research subagents in parallel via a synchronous-fork-then-join pattern. Coverage gaps live in the decomposition step. Not in the subagents.

Domain 1 + 2Hub-and-spokeAnthropic pattern
Scope
One sub-pattern of the parent. Slimmer surface, same exam rigour.
Exam
27% D1 · 18% D2. Each decision and failure mode names the canonical distractor.
Canonical patternD1 + D2
01 · The pattern

What it is

The coordinator is the single hub that receives the user's research query and turns it into a fan-out of self-contained subagent tasks. Its first and most load-bearing job is semantic decomposition: looking at a topic like creative industries and enumerating every sub-domain that matters (visual arts, music, writing, film, performing arts), not just the first one that surfaces from a keyword scan. Lexical decomposition stops at the words you can see in the query. Semantic decomposition asks what the user actually needs covered.

Once decomposition is complete, the coordinator dispatches subtasks via a synchronous-fork-then-join pattern. All N research subagents fire at once through asyncio.gather (Python) or Promise.all (TypeScript). The coordinator awaits the full set, then proceeds to verification. Latency becomes max(subagents) instead of sum(subagents). That parallelism is the architectural payoff and the reason hub-and-spoke beats a single mega-loop on any decomposable task.

Routing is strict hub-and-spoke: subagents never call each other. If subagent B depends on a finding from subagent A, the answer is not for B to import A. The answer is A returns to the coordinator, the coordinator constructs B's task prompt with A's finding embedded, and B starts in a fresh context. Every cross-subagent edge passes through the hub. This is what keeps isolation, parallelism, and visibility intact at the same time.

02 · How it runs

How it works

Step 1 is decomposition. The coordinator reads the query, identifies the topic class, and produces an explicit list of sub-domain tasks. For impact of AI on creative industries the list must include visual arts, music, writing, film, and performing arts. The decomposition function is unit-testable and should be reviewed before any spawn happens; a coverage bug here cannot be recovered downstream by tuning subagents or upgrading models.

Step 2 is fan-out. Each task becomes a messages.create call with its own system prompt, scoped tools whitelist, and a self-contained messages body. No history is inherited. The coordinator wraps the fan-out with a Semaphore(MAX_PARALLEL=5) to bound concurrency and a per-subagent retry budget (default 2) for timeout handling. stop_reason from each subagent tells the coordinator whether the response is complete, max-tokens partial, or tool-use mid-flight.

Step 3 is join. The coordinator awaits the full gather, inspects each subagent's status_code, and decides per-result: accept, retry with a narrower query, or transparently mark a gap. Successful findings get pooled and handed to the verification subagent. Timeouts return structured error context, not silence: {status: 'timeout', query, partial_results, alternatives}. The coordinator uses that envelope to make a real decision; an empty [] masquerading as success would force it to guess.

03 · Configuration decisions

The 4 decisions

Each row pairs the right answer with the most-tested distractor. The Why column explains the failure mode behind the wrong choice.

DecisionRight answerWrong answerWhy
User asks about creative industries. How do you decompose?Semantic enumeration: visual arts, music, writing, film, performing artsLexical split on the words creative and industriesLexical splits miss every sub-domain that wasn't named. Semantic decomposition asks what the user actually needs covered and enumerates the full set before spawning.
Subagent B needs a finding from Subagent A. How does B get it?A returns to coordinator. Coordinator embeds A's finding in B's task promptA calls B directly with the findingDirect calls break isolation, kill parallelism (B blocks on A even when independent), and hide the dependency from the coordinator's orchestration graph.
Final report is missing 4 of 5 sub-domains. Where do you debug first?The coordinator's decomposition function. The bug is upstreamTune subagent prompts or upgrade their modelIf the coordinator never enumerated music or writing, no subagent could research them. Decomposition is the load-bearing step. Fix it first.
How many subagents to fan out?Bounded by Semaphore(MAX_PARALLEL=5). Diminishing returns past 5-7Unbounded. Spawn one per sub-domain regardless of countUnbounded fan-out hits API concurrency limits, rate-limit backpressure, and coordinator-side context contention. Cap, measure, tune to your workload.
04 · Failure modes

Where it breaks

5 failure pairs. Each one is one exam pattern. The fix is always architectural, never a prose plea to the model.

Lexical decomposition

Coordinator splits creative industries on the word creative. Spawns one subagent for creative writing. Misses music, film, visual arts, performing arts entirely.

✅ Fix

Replace lexical split with a semantic enumerator. For each topic class, list ALL relevant sub-domains in code, not the first one the regex catches.

Sequential fan-out

Coordinator awaits subagent 1 before spawning subagent 2. Latency = sum(subagents) ~ 25s for 5 tasks. Parallel architecture wasted.

✅ Fix

Use asyncio.gather(*tasks) (Python) or Promise.all(tasks) (TS). All N subagents fire at once. Latency drops to max(subagents) ~ 5s.

Direct subagent-to-subagent call

Researcher A imports Researcher B and passes a finding directly. B inherits A's call-site context. Coordinator loses visibility on the dependency.

✅ Fix

Route through the coordinator. A returns its finding; coordinator builds B's task prompt with the finding embedded. Hub-and-spoke is non-negotiable.

Unbounded fan-out

Coordinator spawns 50 subagents at once for a long taxonomy. Anthropic API rate-limits half of them; retry storms compound the problem.

✅ Fix

Wrap fan-out in Semaphore(MAX_PARALLEL=5). Set a retry budget per subagent (default 2). Beyond that, accept partial data and mark the gap.

Silent timeout treated as success

Web-search subagent times out, returns []. Coordinator interprets empty list as no information exists. Final report has a silent gap with no acknowledgement.

✅ Fix

Return {status: 'timeout', query, partial_results, alternatives}. Coordinator inspects status_code, retries narrower or marks the gap transparently in synthesis.

05 · Exam patterns

Exam patterns

5 V2 questions wired to this deep dive. Each shows all 4 options with rationale, the mental model under test, and the priority order across distractors.

A research system decomposes 'impact of AI on creative industries' into three subtopics: visual arts, music, writing. The web-search subagent finds results for all three. The synthesis subagent produces a report covering only visual arts. Why?
A web-search subagent times out and returns an empty result list. The coordinator treats this as 'no information available' and moves forward. The final report is incomplete. What is the architectural fix?
A research report cites two conflicting statistics: '45% of creative workers use AI' (Pew) and '12% use AI daily' (McKinsey). Should synthesis pick the more likely one?
Subagent A (academic papers) finds a key research direction. Subagent B (web search) needs that finding to guide its queries. Should A pass it directly to B?
A synthesis subagent needs to verify ~100 facts in a final report. Calling verify_fact sequentially takes 60+ seconds. What is the architectural fix?
06 · Concepts in play

Concepts wired

4 primitives compose this sub-pattern. Each card links to the concept page where the primitive is taught in isolation.

07 · Sibling deep dives

Continue the parent

2 more sub-patterns under Multi-Agent Research System. Each one drills into a different load-bearing decision.

08 · FAQ

Frequently asked

Should decomposition happen at runtime or be hardcoded?
Hybrid. For known topic classes (creative industries, healthcare, finance), maintain a hardcoded sub-domain map. For novel topics, fall back to a lightweight model-generated decomposition with a generic structure (academic literature, industry case studies, empirical adoption data). Hardcoded is faster and tested. Model-generated is adaptive but needs review.
How does the coordinator know when all subagents are done?
asyncio.gather / Promise.all resolves when every task has either returned or raised. The coordinator inspects each result's stop_reason and status_code to decide accept, retry, or mark a gap. There is no polling. The runtime owns the join.
Can the coordinator update its decomposition mid-run if a subagent surfaces an unexpected sub-domain?
Yes, but only between phases. Phase 1 (research) completes; coordinator inspects the pooled findings; if a missing sub-domain emerges, the coordinator can spawn a follow-up research subagent before verification. Mid-phase decomposition changes break the parallel model and create coordination chaos. Wait for the join.
P3.3 deep dive · D1 · Agentic Architectures · Deep dive

Coordinator Routing, complete.

You've covered the full ten-section breakdown for this primitive, definition, mechanics, code, false positives, comparison, decision tree, exam patterns, and FAQ. One technical primitive down on the path to CCA-F.

Share your win →