Lesson 3 of 6 in Agentic Architecture & Orchestration

1.3 · Orchestration Patterns

Once you know you're building an agentic system, the next question is how to structure it. There are four canonical orchestration patterns: chaining, routing, parallelization, and orchestrator-workers. Each fits a specific problem shape. The exam tests whether you can look at a scenario and match it to the right pattern — and whether you can reject architectures that look sophisticated but solve the wrong problem.

1.3.1 Prompt chaining — sequential dependency

Break a task into ordered steps, each with its own prompt. The output of step N feeds step N+1. You use chaining when the pipeline has clear handoffs and you can verify (or improve) each stage before it feeds the next.

Chaining is the workflow-shaped pattern. Steps are known in advance; you wrote them. The value comes from letting each step have a focused prompt, focused inputs, and focused evaluation — versus one megaprompt trying to do everything.

Key point — Use chains when steps are knowable AND sequential. Each step's success is checkable independently.
Content-generation chain
# Content generation chain
outline    = llm(prompt=OUTLINE_PROMPT, input=brief)
draft      = llm(prompt=DRAFT_PROMPT,   input=outline)
edited     = llm(prompt=EDIT_PROMPT,    input=draft)
final_html = llm(prompt=FORMAT_PROMPT,  input=edited)

1.3.2 Routing — one-of-N specialization

A classifier prompt inspects the incoming request and dispatches it to one of several specialized downstream prompts. Use routing when input types vary widely enough that a single 'do-everything' prompt would compromise on each — accuracy on one class comes at the cost of accuracy on another.

The typical shape is a small, cheap classifier at the top and larger specialist prompts (or entire agents) below. This is different from an orchestrator that plans dynamically: the router picks EXACTLY ONE downstream lane, based on a known taxonomy.

Support-desk router
# Support router
category = classify(request)  # billing | technical | returns | account
if   category == "billing":   return billing_agent(request)
elif category == "technical": return technical_agent(request)
elif category == "returns":   return returns_workflow(request)
elif category == "account":   return account_agent(request)

1.3.3 Parallelization — sectioning and voting

Two flavours. Sectioning splits a task into INDEPENDENT chunks, runs them in parallel, and aggregates. Use for embarrassingly-parallel work: processing 50 files, reviewing 10 sections of a contract, generating slides for 8 topics.

Voting runs the SAME task multiple times and combines the results — usually via majority vote or a consensus rule. Voting is the right answer when reliability matters more than cost: content moderation, safety filtering, high-stakes classification. You trade compute for correctness.

Key point — Sectioning is for SPEED on independent work. Voting is for RELIABILITY on the same work.
Sectioning vs voting
# Sectioning: independent work in parallel
results = parallel_map(review_file, files)   # each independent
report  = aggregate(results)

# Voting: same work, N times
verdicts = [classify(item) for _ in range(5)]
final    = majority_vote(verdicts)

1.3.4 Orchestrator-workers — dynamic decomposition

An orchestrator LLM PLANS the task at runtime and dispatches worker LLMs (usually subagents) to execute the pieces. Workers return summaries; the orchestrator synthesizes. This is the pattern behind multi-agent research systems, dynamic troubleshooting agents, and open-ended investigation tools.

This is where 'orchestrator-workers' diverges sharply from a workflow: in a workflow YOU wrote the steps; in orchestrator-workers the ORCHESTRATOR writes them at runtime based on what the task actually needs.

Exam trap — The exam sometimes offers 'orchestrator-workers' as the sophisticated-sounding answer for a task with knowable steps. Reject it. If you can enumerate the steps in advance, you don't need a runtime planner — a chain or a router is cheaper and more predictable.

1.3.5 Parallel dispatch: emit multiple Task calls in one turn

When you spawn subagents via the Agent SDK's Task tool, don't dispatch them one at a time. Emit MULTIPLE Task tool_use blocks in the SAME assistant response — the SDK executes them in parallel, cutting total wall-clock time roughly by the number of workers. Serial dispatch is a common performance mistake in coordinator prompts, and the exam tests it directly.

Serial vs parallel dispatch
# ❌ Serial: three round trips, three wait times
assistant turn 1: Task(agent="research_a")
  → wait → results back
assistant turn 2: Task(agent="research_b")
  → wait → results back
assistant turn 3: Task(agent="research_c")

# ✅ Parallel: one round trip, workers run concurrently
assistant turn 1:
    Task(agent="research_a", ...)
    Task(agent="research_b", ...)
    Task(agent="research_c", ...)
# → tool_results come back together after all three finish

1.3.6 Picking the right pattern

The decision framework: sequential dependency → chain. Known input variety with distinct downstream paths → route. Independent parallel subtasks → parallelize (sectioning). Same task needing high reliability → parallelize (voting). Unknown decomposition, the plan itself must be decided at runtime → orchestrator-workers. Real systems mix these: a router's downstream branches can each be chains, agents, or workflows in their own right.

Takeaways

  • Chain for sequential dependency with knowable steps
  • Route when input types are known and each needs a specialized downstream prompt
  • Sectioning for speed on independent subtasks; voting for reliability on the same task
  • Orchestrator-workers only when the plan itself must be decided at runtime
  • Parallel Task calls in one response are the SDK-native way to fan out subagents

Exam traps

Choosing orchestrator-workers for a task with knowable steps
If you can enumerate the steps in advance, a workflow or chain is cheaper and more predictable. Orchestrator-workers pays for runtime planning — only worth it when the plan is genuinely unknown up front.
Serial subagent dispatch when parallel is possible
Emitting one Task call per assistant turn, waiting for the result, then emitting the next is a common performance anti-pattern. Independent subtasks should be dispatched in a single response with multiple Task blocks.
Using a router when the correct answer is 'just improve the prompt'
A router adds real cost and failure modes. Before adding routing, check whether the underlying prompt could handle the variance with better instructions or few-shot examples.

Practice scenario

A research assistant needs to answer open-ended questions like 'How has EV charging infrastructure evolved in Europe over the past 3 years?' The final answer requires investigating regulations, manufacturers, charging networks, and consumer adoption — but which subtopics matter varies per question. Which orchestration pattern fits best?

← PreviousNext →