Multi-agent patterns
Orchestrator and worker, critic and reflection, context isolation and hand-off protocols — and why more agents rarely means more capability.
The patterns worth knowing
Splitting one agent into several is an engineering technique, not an intelligence upgrade. Every additional agent is another model call, another failure point and another log stream. Use a pattern only when it buys something specific.
| Pattern | Structure | What it buys | What it costs |
|---|---|---|---|
| Orchestrator and workers | One planner dispatches isolated subtasks | Context isolation; independent subtasks run in parallel | Fan-out multiplies tokens and latency; aggregation can lose detail |
| Critic and reflection | Generator plus a reviewer that scores against criteria | Catches errors a single pass misses | Extra call per round; a vague critic approves everything |
| Pipeline | Fixed sequence of specialists | Each stage gets a narrow prompt and toolset | Rigid; no adaptation when input is unexpected |
| Debate | Agents argue, then a judge decides | Useful for judgement under ambiguity | Expensive, non-deterministic, hard to evaluate |
| Hand-off | One agent transfers control to another | Focus per phase, without one giant prompt | The receiving agent loses everything the sender knew |
The single real benefit is context isolation. A worker that sees only its own subtask and its own tools makes fewer mistakes than one carrying the entire conversation. If your split does not isolate context, it is just extra calls.
Orchestrator and workers
def orchestrate(goal, max_workers=4):
subtasks = plan_subtasks(goal) # model call, schema-validated
subtasks = subtasks[:max_workers]
results = parallel_map(
lambda t: run_worker(t), # each gets a FRESH context
subtasks,
)
return synthesise(goal, results) # one call, all results in
def run_worker(subtask):
# no history, no other subtasks, only the tools this task needs
tools = select_tools(subtask["tool_scope"])
return agent(subtask["instruction"], tools=tools, max_steps=4)- Give each worker only the tools it needs. Tool selection inside a worker is where most cross-contamination happens.
- Cap the fan-out. Four workers at eight steps each is thirty-two model calls, and provider rate limits will make the wall-clock time worse than running sequentially.
- Make workers return structured results with a stable shape, so the synthesis step reads data rather than prose.
- Keep the orchestration decision outside the workers. A worker that can spawn more workers is a recursion you did not budget for.
- Parallel writes need coordination: two workers updating the same record will fight. Serialise writes through the orchestrator.
def orchestrator_with_writes(goal):
reads = [t for t in plan_subtasks(goal) if t["kind"] == "read"]
reads_done = parallel_map(run_worker, reads[:4])
writes = plan_writes(goal, reads_done) # planned with real results
for w in writes: # serialised, never parallel
run_worker(w)
return synthesise(goal, reads_done)Critic and reflection
A critic works only if it has explicit criteria and the authority to fail the output. A critic asked whether the answer looks good will nearly always say yes, because agreement is the cheapest continuation.
CRITERIA = [
"Every claim cites a source id returned by a tool",
"No number appears that is not present in a tool result",
"The question asked in the goal is answered directly in the first sentence",
]
def generate_then_review(goal, max_rounds=2):
draft = agent(goal)
for _ in range(max_rounds):
verdict = critic(goal=goal, draft=draft, criteria=CRITERIA)
# verdict: {"failures": [{"criterion": 0, "evidence": "...", "fix": "..."}]}
if not verdict["failures"]:
return draft
draft = revise(goal, draft, verdict["failures"])
return draft # cap reached: return best effort, flagged- Number the criteria and make the critic cite the criterion index. Vague complaints cannot be acted on.
- Cap the rounds. Reflection loops converge slowly and are the most common cause of runaway cost.
- Use the critic as a gate, not a co-author: it should describe what is wrong, and the generator should fix it.
- Log every verdict. The failures the critic repeatedly finds tell you what to fix in the generator's prompt.
FAQ
How many agents is too many?
Do agents need to talk to each other?
Related
Planning and task decomposition Evaluating agents
Last refreshed 2026-09-18.