Single round (default)
All steps
Parts of this pattern
- Task Input / output
- The overall job, such as 'Rename the API across the repo', with no subtasks defined yet.
- Orchestrator LLM call
- Plans the subtasks at run time, dispatches them to workers, then combines their results into one answer.
- Worker 1 LLM call
- Worker created for one subtask, here editing a.ts, doing only its assigned part.
- Worker 2 LLM call
- Worker created for the second subtask, here editing b.ts, working independently of the others.
- Worker 3 LLM call
- Worker created for the third subtask, here editing c.ts; the number of workers depends on the task.
- Result Input / output
- The combined result, such as one diff covering all three files with conflicts resolved.
- Task → Orchestrator
- The task goes to the orchestrator, which has to work out the steps itself.
Rename getUser to fetchUser everywhere in the repo, including callers and tests.
- Orchestrator → Worker 1
- A self-contained instruction for worker 1, created by the orchestrator's plan.
{"target": "a.ts", "instruction": "Rename getUser to fetchUser and update its two call sites."}
- Orchestrator → Worker 2
- A self-contained instruction for worker 2, sent in parallel with the others.
{"target": "b.ts", "instruction": "Rename the getUser import and its three usages to fetchUser."}
- Orchestrator → Worker 3
- A self-contained instruction for worker 3, sent in parallel with the others.
{"target": "c.ts", "instruction": "Update the getUser mock and assertions in the tests to fetchUser."}
- Worker 1 → Orchestrator
- Worker 1's finished change and note go back to the orchestrator.
Renamed getUser to fetchUser in a.ts (def + 2 call sites). Nothing left undone.
- Worker 2 → Orchestrator
- Worker 2's finished change and note go back to the orchestrator.
Updated the import and 3 usages in b.ts. Nothing left undone.
- Worker 3 → Orchestrator
- Worker 3's finished change and note go back to the orchestrator.
Updated mock and assertions in c.ts. Note: one snapshot test still references the old name.
- Orchestrator → Result
- The orchestrator's synthesis becomes the final result, with worker conflicts flagged and resolved.
Combined diff: a.ts, b.ts, c.ts renamed to fetchUser. Flagged: a snapshot test still uses the old name.
Iterative rounds
The orchestrator reviews each round of results and may send out another round; a separate finishing worker adds citations before output.
All steps
Parts of this pattern
- Question Input / output
- The research question, such as 'Which EU countries offer the best R&D tax credits for startups?'.
- Lead agent LLM call
- Plans each round of subtasks, reads the findings, and decides whether to send out another round or write the report.
- Agent 1 LLM call
- A research subagent with its own search tools, working on one objective from the current round.
- Agent 2 LLM call
- A second research subagent working in parallel on a different objective, with its own context.
- Agent 3 LLM call
- A third research subagent; a round has as many as the lead asks for, up to a cap.
- Findings Memory
- The lead's plan and every subagent's findings with their sources, kept outside the lead's context and re-read by the lead after each round.
- Citations LLM call
- A separate finishing step that attaches a source from the findings to every claim in the report.
- Report Input / output
- The final report, with a citation on every claim.
- Question → Lead agent
- The question goes to the lead agent, which plans the first round.
Which EU countries offer the best R&D tax credits for startups?
- Lead agent → Agent 1
- An objective for subagent 1 in the current round.
{"objective": "France: the Crédit d'Impôt Recherche rate and startup eligibility", "where_to_look": "official tax sites"}
- Lead agent → Agent 2
- An objective for subagent 2, sent in parallel.
{"objective": "Netherlands: WBSO rates for startups in 2026", "where_to_look": "rvo.nl"}
- Lead agent → Agent 3
- An objective for subagent 3, sent in parallel.
{"objective": "Ireland: the R&D tax credit rate and refund rules", "where_to_look": "revenue.ie"}
- Agent 1 → Findings
- Subagent 1's findings, each with a source URL, are added to the store.
France CIR: 30% of eligible R&D spend up to EUR 100M; young innovative firms get early refunds. (impots.gouv.fr)
- Agent 2 → Findings
- Subagent 2's findings are added to the store.
Netherlands WBSO: 40% wage-cost credit on the first EUR 350k for starters. (rvo.nl)
- Agent 3 → Findings
- Subagent 3's findings are added to the store; they may raise new questions.
Ireland: 30% credit, refundable in instalments. Unclear: how the 2026 budget changed the rate. (revenue.ie)
- Findings → Lead agentmore?
- After each round the lead re-reads all the findings and decides: send out another round, or write the report.
<findings>France CIR 30%... WBSO 40%... Ireland 30%, 2026 rate unclear</findings> More research needed: Ireland 2026.
- Lead agent → Citationsdraft
- When the lead decides the findings are enough, it writes the report and sends it, with the findings, to the citation step.
{"done": true, "report": "France and the Netherlands are the strongest options for early-stage startups..."}
- Citations → Report
- The report, with a source on every claim, is returned.
France and the Netherlands are the strongest options [1][2]... [1] impots.gouv.fr/... [2] rvo.nl/...
← → neighboursesc atlas
Orchestrator-Workers
Also known as Dynamic decomposition · Planner-workers
A central LLM works out the subtasks at run time, sends them to worker LLMs, then combines the results.
Single round: Popularized by Schluntz & Zhang (2024) · Anthropic
Anthropic named the pattern in 2024; it describes a central LLM that breaks down tasks dynamically, delegates them to worker LLMs and synthesizes their results.
Iterative rounds: Popularized by Hadfield et al. (2025) · Anthropic
"How we built our multi-agent research system" (2025): a lead agent spins up 3-5 subagents in parallel, decides whether more research is needed, and hands the report to a separate CitationAgent.
Measured over one run
Single round
- Nodes
- 6. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 5. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 5. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 1. Distinct example runs you can switch between on the diagram.
- Loop
- no. Whether the flow cycles back on itself until a condition is met.
- Parallel
- yes. Whether two or more messages are in flight at the same time.
- Branch
- no. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- medium. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- high. Relative token spend per request.
- Latency
- medium. Relative wall-clock time per request.
Iterative rounds
- Nodes
- 8. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 7. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 5. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 1. Distinct example runs you can switch between on the diagram.
- Loop
- yes. Whether the flow cycles back on itself until a condition is met.
- Parallel
- yes. Whether two or more messages are in flight at the same time.
- Branch
- yes. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- medium. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- high. Relative token spend per request.
- Latency
- medium. Relative wall-clock time per request.
Counted from the first scenario's timeline when the site is built.
Problem
Some tasks cannot be split up front. “Rename this API across the repo” touches three files in one codebase and thirty in another, and which files, and what each needs, depends on what the code looks like. A fixed pipeline cannot know the shape of the work before it sees the input.
How it works
The orchestrator reads the task and decides, at run time, what subtasks it needs. For the rename it might search the repo, find three call sites and define one subtask per file. It then dispatches each subtask to a worker: worker 1, worker 2 and worker 3. The workers are plain LLM calls with self-contained instructions, and they run in parallel.
As the workers finish, their results flow back to the orchestrator. It reconciles them, for instance by checking that the three edits agree on the new name, and returns a single result, here a combined diff.
The number of workers, and what each does, is chosen by the model per input. That is the whole difference from a fixed fan-out.
In the iterative variant, used by research systems, the orchestrator does not stop after one round. It reads what the workers found, decides whether more research is needed, and sends out another, usually smaller, round. When it has enough, a separate finishing worker adds citations before the report goes out.
When to use
- The subtasks cannot be predicted in advance and depend on the input.
- Coding changes that span multiple files, where the set of files varies by task.
- Research that gathers and analyzes information from several sources.
- Each subtask can be described in a few sentences without the full conversation.
When to avoid
- The subtasks are known ahead of time. Use parallel sectioning, which is cheaper and more predictable.
- The task is small enough for one call.
- Workers need tools, memory or autonomy of their own. That points to a supervisor with full agents.
Trade-offs
You buy flexibility with cost and latency. Every run has a planning call, N worker calls and a synthesis call, and total time is the planner plus the slowest worker plus the synthesizer. Behavior is also less predictable than a fixed workflow, because the plan changes with the input.
Failure modes
- Bad decomposition: the orchestrator splits the task into overlapping or dependent pieces. Ask for independent, self-contained subtasks and cap the worker count.
- Lost context: a worker lacks something it needed and guesses. Put everything it needs in its instruction.
- Conflicting results: two workers edit the same thing differently. Have the synthesis step check for conflicts explicitly, and do not just concatenate.
Build it with your AI
Single round
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Orchestrator-Workers pattern in this codebase, using the LLM client and language we already use.
## Goal
Carry out a task whose subtasks cannot be known in advance: an orchestrator model plans them at run time, workers do them in parallel, and the orchestrator combines the results.
## How it works
1. Call the orchestrator with the Orchestrator planning prompt, filling in the task, and parse the JSON reply into a list of subtasks, each with a target and an instruction.
2. Check the plan in code: at least one subtask, no more than the cap, and every subtask has a non-empty target and instruction. If the reply is not valid JSON or fails the check, re-ask once with the error, then stop with that error.
3. Start one worker per subtask, concurrently, with the Worker prompt; each worker sees only its own target and instruction.
4. Collect every worker's result, keyed by target. A worker that errors is retried once, then recorded as failed with its error.
5. Call the orchestrator again with the Synthesis prompt, passing the task and all the results, failures included, and return its combined answer.
## Prompts
### Orchestrator planning prompt
```markdown
Break the task below into independent subtasks, one per file or
source that needs separate work. Do not invent work the task does
not need.
<task>{{task}}</task>
Respond in JSON:
{"subtasks": [{"target": "...", "instruction": "self-contained instructions"}]}
```
### Worker prompt
```markdown
You are handling one part of a larger task. Do only this part.
<target>{{subtask.target}}</target>
<instruction>{{subtask.instruction}}</instruction>
Return the finished change and a one-line note on anything you
could not do.
```
### Synthesis prompt
```markdown
Combine the worker results into one coherent answer for the task.
Flag any conflicts between workers and resolve them.
<task>{{task}}</task>
<results>{{results}}</results>
```
## Stop rule
One plan, one round of workers and one synthesis, then stop. The orchestrator does not spawn a second round; if work is missing, the synthesis says so.
## Requirements
- Cap the number of subtasks (default 8) and the number of workers running at once (default 4).
- Make each worker's instruction self-contained: a worker gets no shared history and cannot see the other workers.
- The synthesis must list every failed subtask and every conflict between workers, never drop them.
- Log the plan, each worker's input, output and latency, and the synthesis input, under one run id.
- Add a test with a stub LLM whose plan has 3 subtasks; assert 3 worker calls with distinct targets and one synthesis call whose input holds all 3 results.
Iterative rounds
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Orchestrator-Workers pattern (Iterative rounds variant) in this codebase, using the LLM client and language we already use.
## Goal
Answer a research question with a lead model that sends out rounds of parallel subagents, decides after each round whether more research is needed, and passes the final report to a citation step.
## How it works
1. Call the lead with the Lead agent prompt, passing the question and the findings so far (none in round 1), and parse the JSON reply into done, subtasks and, when done, a report.
2. If done is false, start one subagent per subtask, concurrently, with the Subagent prompt; each has its own search tools and returns findings with their source URLs.
3. Append every subagent's findings to a findings store kept outside the lead's context; a subagent that errors or hits its tool-call cap returns what it has with a note saying so.
4. Call the lead again with the question and all the stored findings, and repeat until it replies done. When the round cap is reached, call it once more with final_round set, which requires a report.
5. Send the report and the findings to the citation step with the Citation prompt, which attaches a source to every claim, and return the cited report.
## Prompts
### Lead agent prompt
```markdown
You lead a research team. Decide what still needs finding out
to answer the question well, and split it into independent
subtasks for parallel researchers (at most {{max_subagents}}).
<question>{{question}}</question>
<findings>{{findings}}</findings>
Respond in JSON. If more research is needed:
{"done": false, "subtasks": [{"objective": "...", "where_to_look": "..."}]}
If the findings are enough:
{"done": true, "report": "the full answer, written from the findings"}
{{#if final_round}}
This is the last round: you must reply with done true and write
the best report the findings support, naming any gaps.
{{/if}}
```
### Subagent prompt
```markdown
You are one of several researchers working in parallel. Research
only this objective, using your search tools, and stop when you
have solid answers or after {{max_tool_calls}} tool calls.
<objective>{{objective}}</objective>
<hints>{{where_to_look}}</hints>
Return your findings as short statements, each with its source URL.
```
### Citation prompt
```markdown
Add citations to the report below. For every factual claim, attach
the URL from the findings that supports it. If no finding supports
a claim, mark it [unsourced]; never invent a source.
<report>{{report}}</report>
<findings>{{findings}}</findings>
```
## Stop rule
Stop when the lead replies done, or after 3 rounds. After the last round the lead is called once with final_round set and must write a report, noting gaps, which is marked incomplete. If that reply is still not a report, return the raw findings marked incomplete. The citation step runs once on any report.
## Requirements
- Cap rounds (default 3), subagents per round (default 5) and tool calls per subagent (default 10), all as parameters.
- If the lead's reply is not valid JSON, retry once with the parse error; if it fails again, take the final-round path: call the lead with final_round set, and fall back to the raw findings marked incomplete.
- Store the plan and the findings outside the lead's context, so a long run can be resumed and the lead re-reads only what it needs.
- The citation step may only cite URLs that appear in the findings; flag any claim it cannot source instead of inventing one.
- Add a test with a stub LLM whose lead returns 3 subtasks, then 2, then done; assert 5 subagent calls, 3 lead calls and 1 citation call.
Prompt templates
Single round
Break the task below into independent subtasks, one per file orsource that needs separate work. Do not invent work the task doesnot need.
<task>{{task}}</task>
Respond in JSON:{"subtasks": [{"target": "...", "instruction": "self-contained instructions"}]}You are handling one part of a larger task. Do only this part.
<target>{{subtask.target}}</target><instruction>{{subtask.instruction}}</instruction>
Return the finished change and a one-line note on anything youcould not do.Combine the worker results into one coherent answer for the task.Flag any conflicts between workers and resolve them.
<task>{{task}}</task><results>{{results}}</results>Iterative rounds
You lead a research team. Decide what still needs finding outto answer the question well, and split it into independentsubtasks for parallel researchers (at most {{max_subagents}}).
<question>{{question}}</question><findings>{{findings}}</findings>
Respond in JSON. If more research is needed:{"done": false, "subtasks": [{"objective": "...", "where_to_look": "..."}]}If the findings are enough:{"done": true, "report": "the full answer, written from the findings"}
{{#if final_round}}This is the last round: you must reply with done true and writethe best report the findings support, naming any gaps.{{/if}}You are one of several researchers working in parallel. Researchonly this objective, using your search tools, and stop when youhave solid answers or after {{max_tool_calls}} tool calls.
<objective>{{objective}}</objective><hints>{{where_to_look}}</hints>
Return your findings as short statements, each with its source URL.Add citations to the report below. For every factual claim, attachthe URL from the findings that supports it. If no finding supportsa claim, mark it [unsourced]; never invent a source.
<report>{{report}}</report><findings>{{findings}}</findings>Related patterns
Composes well with:
Sources
From the Agentic Atlas by Joran Kikke · Edit on GitHub · Suggest a correction