Orchestrator–Workers: decompose the task at runtime
When you can't know the subtasks in advance, let an orchestrator LLM break the work down on the fly, delegate to workers, and synthesise their output.
Prompt chaining and parallelization assume you know the subtasks ahead of time. Often you don't. A code change might touch two files or twenty; a research question might need one source or ten. The orchestrator–workers pattern handles this: a central LLM decomposes the task at runtime, delegates each piece to a worker, and synthesises the results.
How it works
The orchestrator reads the task and decides — for this specific input — what the subtasks are and how many workers to spawn. Each worker is an LLM call focused on its slice. A synthesiser then combines the worker outputs into a single coherent result. The key difference from parallelization: the subtasks aren't hardcoded, they're chosen by the model based on what the input actually needs.
- The number and shape of subtasks are decided at runtime, not baked in.
- Workers stay focused, so each piece is high quality.
- The synthesiser owns coherence — resolving overlaps and conflicts between workers.
const subtasks = await orchestrator(task); // model decides the breakdown
const results = await Promise.all(
subtasks.map((s) => worker(s)) // one focused call each
);
return await synthesiser(task, results); // merge into one answerWhen to use it
Use it for open-ended tasks where the decomposition can't be predicted — multi-file coding changes, research across an unknown number of sources, complex document generation. The trade-off is control: because the model decides the plan, you need strong observability and guardrails so a runaway orchestrator doesn't spawn fifty workers on a simple request.
When you can't predict the subtasks, stop hardcoding them — let the model plan, and make sure you can watch it do so.