On this page
- What a multi-agent system is
- Who it is for, and who should stay with one agent
- The Handoff Tax, and how to price a split
- What we actually build
- How it works technically
- The build process, stage by stage
- What you get at handover
- Where these projects go wrong
- What it costs to run once live
- How to tell whether you need more than one agent
- How to start
What a multi-agent system is
A multi-agent system is several narrow agents, each with its own prompt, tools and permissions, coordinated by a supervisor that decomposes the request, dispatches work, checks what comes back and assembles the answer. It is not a smarter agent. It is the same agent loop repeated behind a routing layer, and the engineering that matters lives at the boundaries between the agents rather than inside any one of them.
The reason to split is specialisation: a worker with four tools and a short prompt decides better than one with thirty tools and a two thousand word prompt. The reason not to split is that every boundary costs context, tokens, latency and the ability to say which component was wrong.
- Tools, not topicsSplits that survive follow tool and permission boundaries. Splits along subject matter tend to collapse back into one agent.
- n plus 1A supervisor and n workers means n plus 1 briefings before any real work starts, and each briefing is paid on every run.
- One ownerEvery shared fact is resolved once, by one named agent, and passed down. Nothing is re-derived independently.
- Supervisor
- The agent that plans and routes but does no domain work. It decomposes the request, dispatches to workers, validates their results and synthesises the answer.
- Worker
- A narrow agent with one job, a small tool list and its own permission ceiling. It answers exactly the objective it was handed and reports what it could not settle.
- Handoff envelope
- The typed message passed from one agent to another. It carries the objective, the resolved inputs, the shared facts, the budget, the permission ceiling and the conditions for being finished.
- Hop
- One handoff between agents. Capping hops per run is the standard defence against two agents passing a task back and forth until the budget is gone.
If you do not yet run a single agent in production, start there. The patterns on AI agent development are prerequisites, and a team that has not shipped one agent will not debug five.
Who it is for, and who should stay with one agent
Multi-agent systems suit work that crosses real boundaries: different tools, different permissions, different data sensitivity, different owners. They do not suit work that is merely large. A long job with one tool set is a single agent with a bigger step budget.
| What you are seeing | The right move | Why |
|---|---|---|
| The prompt has grown past a thousand words and contradicts itself | Split | Contradictions mean two jobs sharing one instruction set. Splitting removes the contradiction rather than papering over it. |
| Some steps need write access to finance, others only read the CRM | Split | Permission boundaries are the cleanest split there is. Each worker gets the lowest ceiling that lets it finish. |
| Different steps need genuinely different tool sets with no overlap | Split | This is the split that pays. Small tool lists produce better tool choice, which is where most agent errors start. |
| The job is long but uses the same six tools throughout | Stay with one | You want a larger step budget and better context trimming, not a routing layer. |
| You want each department to own its own agent | Stay with one, for now | An org chart is not an architecture. Split on tools first, and let ownership follow the split. |
| The single agent is inaccurate and nobody knows why | Fix observability first | Splitting an unmeasured agent gives you five unmeasured agents and a routing layer to blame. |
Teams split because a single agent is performing badly, expecting the split itself to fix accuracy. It rarely does. A weak agent split into four becomes four weak agents plus a supervisor that has to reconcile their disagreements. Fix the tools and the evaluation set first, then split if the prompt is still fighting itself.
The Handoff Tax, and how to price a split
Every boundary between agents has a price, and it is payable on every run forever. Naming the six line items makes the split decision arithmetic rather than taste.
The ChatGPTalker Handoff Tax
Six costs you take on the moment work crosses from one agent to another. Add them up and compare against the specialisation gain. If the gain does not clearly exceed the tax, keep one agent.
The receiving agent knows only what the envelope carried. The loss is silent: a worker given a slightly wrong question returns a confident, well-evidenced answer to that wrong question. Test it by handing a worker's envelope to a competent colleague with no other context and asking whether they could do the job.
Every agent re-reads its own instructions, tool catalogue and task context on every call. Three specialists do not cost a third each. Each pays the full fixed cost of being briefed, so the floor is the briefing cost times the number of agents involved in a run.
Sequential workers add their wall clock times end to end. Parallel fan-out fixes that until the supervisor has to reconcile conflicting results, which is another model call over a context containing everything the workers returned.
When the answer is wrong, which agent was wrong? With one agent the trace answers it. With five you need per-agent inputs, outputs, evidence and a dispatch record, or every incident turns into a meeting.
Two workers handed the same underlying question at different moments can reach different conclusions, and the supervisor will happily synthesise both into one contradictory answer. The defence is to resolve shared facts once, upstream, and forbid re-derivation.
The supervisor is a model too, and its failure mode is the worst in the system. It dispatches confidently to the wrong specialist, receives competent work on an irrelevant question, and assembles a plausible answer out of it. Nothing downstream catches that.
Split on tool boundaries and permission boundaries. Those splits reduce the tax because the envelope carries less, the tool lists shrink and the authority ceiling drops. Splits along subject matter raise the tax without shrinking anything, which is why they quietly get merged back six months later.
What we actually build
The system is a registry, an envelope, a set of narrow workers, a supervisor and a trace that spans all of them. The workers are the easy part.
The worker registry
A single file listing every worker: its name, its one sentence job, its tool list, its permission ceiling and the shape of what it returns. The supervisor may dispatch only to a name in this registry, enforced in code rather than requested in the prompt. That prevents a supervisor inventing a plausible specialist and then hallucinating its reply.
The envelope and its validator
One typed message format for every handoff, validated on the way out and on the way in. A dispatch that fails validation never reaches a worker, and a result that fails validation never reaches the synthesis step. This is where most reliability comes from, and it is ordinary schema work rather than anything to do with models.
The fact ledger
A small store, scoped to one run, holding values that more than one worker needs: the customer tier, the applicable policy version, the currency, the cut-off date. Each entry records which tool call produced it. Workers read from it and are forbidden to re-derive its entries. This one component removes most self-contradicting output.
- The supervisor, with dispatch, ask and finish, and no domain tools at all.
- Narrow workers, each with a small tool list and its own permission ceiling.
- The registry, the envelope schema and validators on both directions of every hop.
- The run-scoped fact ledger with provenance on every entry.
- Hop counters, per-worker budgets and a duplicate-objective detector.
- A trace joined by run_id across every agent, queryable as one story rather than five logs.
How it works technically
A request enters the supervisor. It resolves the shared facts it can, writes a plan, and dispatches the first objective in a validated envelope. Each worker runs its own agent loop inside its budget, returns a typed result with evidence and an unresolved list, and the supervisor decides whether to accept, re-dispatch or escalate.
- The supervisor resolves shared facts first, before any dispatch, so no two workers can answer the same underlying question differently.
- It writes a plan naming the workers it intends to use and why. The plan is stored, which makes the routing decision reviewable later.
- Each dispatch is an envelope validated against the schema. An invalid envelope is a supervisor bug and never reaches a worker.
- The worker runs its own loop with its own tools, budget and permission ceiling. It cannot see the other workers and cannot dispatch.
- The result is validated: status, evidence for every assertion, and an explicit unresolved list. Missing evidence is a rejection, not a warning.
- The supervisor accepts, re-dispatches with a corrected objective, or escalates. Hop counts and duplicate objectives are checked at this point.
- Synthesis runs over accepted results only, and may not introduce a claim that no worker returned.
The envelope schema below is the piece worth stealing. Almost every multi-agent failure we have debugged traces back to an untyped handoff: a worker that received a summary instead of the document, a result accepted with no evidence, or two agents passing the same task back and forth because nothing counted hops.
{
"$id": "handoff_envelope.schema.json",
"type": "object",
"additionalProperties": false,
"required": ["run_id", "hop", "from", "to", "objective", "inputs", "authority", "budget", "done_when"],
"properties": {
"run_id": {"type": "string", "description": "Identical for every hop in one request. This is how the trace is reassembled later."},
"hop": {"type": "integer", "description": "Increments on every handoff. Reject anything above max_hops. This is what kills ping-pong."},
"from": {"type": "string"},
"to": {"type": "string", "description": "A worker name from the registry. The supervisor may not invent one."},
"objective": {"type": "string", "description": "One imperative sentence. If it needs two, it is two handoffs."},
"inputs": {"type": "object", "description": "Resolved values only. Never a pointer the worker has to fetch, never a summary of a document it needs in full."},
"facts": {
"type": "array",
"description": "Shared values resolved ONCE upstream. A worker must use these and must not re-derive them.",
"items": {"type": "object", "required": ["key", "value", "source_tool_call_id"]}
},
"authority": {"type": "string", "enum": ["R0", "R1", "R2", "R3", "R4"],
"description": "Highest reversibility class this worker may act at on this hop. Enforced in code, never by the prompt."},
"budget": {"type": "object", "properties": {"max_tool_calls": {"type": "integer"},
"max_tokens": {"type": "integer"},
"deadline_ms": {"type": "integer"}}},
"done_when": {"type": "array", "items": {"type": "string"},
"description": "Machine checkable conditions. The supervisor validates these before accepting a result."},
"return": {
"type": "object",
"required": ["status", "result", "evidence", "unresolved"],
"properties": {
"status": {"enum": ["done", "partial", "refused", "failed"]},
"result": {},
"evidence": {"type": "array", "items": {"type": "string"},
"description": "tool_call_ids supporting each asserted value. An assertion with no evidence is rejected."},
"unresolved": {"type": "array", "items": {"type": "string"},
"description": "What this worker could not settle. An empty array is a claim, not a default."},
"confidence": {"type": "number"}
}
}
}
}Three fields do the heavy lifting. The facts array kills consistency drift, because a worker that must use a supplied value cannot invent a different one. The authority field carries the permission ceiling per hop, so a research worker cannot be talked into sending an email. And unresolved makes uncertainty a first class output rather than something a worker quietly omits.
ROLE
You are the supervisor. You do not do the work. You decompose it, dispatch it,
verify what comes back and synthesise the answer. Your only tools are
dispatch(), ask_user() and finish().
DISPATCH RULES
Dispatch only to a worker in the registry below. Never invent a worker name.
One objective per dispatch, written as a single imperative sentence.
Resolve shared facts yourself before dispatching and put them in envelope.facts.
A worker must never look up a fact another worker has already resolved.
Set envelope.authority to the lowest class that lets the worker finish.
ACCEPTING A RESULT
Reject status="done" when any done_when condition is unmet.
Reject any asserted value whose evidence array is empty.
A worker returning unresolved items is doing its job. Do not paper over them.
STOPPING
Maximum 3 hops to any one worker and 12 dispatches per run.
If two workers disagree on a fact, do not average them and do not pick the more
confident one. Re-dispatch to the worker that owns that fact, or escalate.
If the same objective has been dispatched twice, escalate with reason="loop".
SYNTHESIS
Your final answer may contain only claims present in a worker result with
evidence attached. You may not add knowledge of your own, and you may not
smooth over a contradiction between two workers.
Topologies, and where each one breaks
| Shape | How it routes | Best for | Where it breaks |
|---|---|---|---|
| Supervisor and workers | One planner dispatches to named specialists and synthesises | Varied work with clear tool boundaries | The supervisor becomes the bottleneck and the single point of bad judgement |
| Pipeline | Fixed sequence, each stage transforms and passes on | Known order with clean stage contracts | Any case that needs to go backwards, because pipelines loop expensively |
| Router with a flat pool | A classifier picks one specialist and steps aside | Triage where exactly one specialist is right | Cases needing two specialists, because there is no synthesis step |
| Worker and critic pair | A second agent reviews with a different prompt and the same evidence | High cost outputs where a second look pays for itself | It doubles cost, and the critic drifts towards agreement unless its evidence access differs |
| Blackboard | Agents read and write shared state until a condition is met | Open ended research with no fixed order | Hardest to bound, easiest to loop, worst to debug. We use it rarely and always under a hop cap |
The build process, stage by stage
Six to twelve weeks, and it starts by trying not to build it. The first stage exists to give the split decision a chance to fail cheaply.
We instrument your existing single agent, or build one, and measure where it actually loses: wrong tool choice, contradictory instructions, permission workarounds, context exhaustion. If the losses are not concentrated at a tool or permission boundary, we recommend against splitting and fix the single agent instead.
The contracts come before the agents. Worker names, job statements, tool lists, permission ceilings, the envelope schema and its validators. Nothing here involves a model, and getting it wrong is what makes the rest expensive.
Each worker is built and evaluated in isolation against its own case set, called directly with hand-written envelopes. A worker that cannot pass its own evaluation set will not be rescued by a supervisor, and finding that out now is cheap.
The supervisor is built, then deliberately attacked: ambiguous requests, requests spanning two workers, requests belonging to no worker, and requests designed to make it invent a specialist. Routing errors found here are cheap. Routing errors found in production look like competent answers to the wrong question.
The whole system runs on live traffic and commits nothing. We compare its answer against the human one and, more importantly, read the dispatch plans to see whether the routing reasoning holds up when nobody is watching.
Live on a slice, with sampling recorded per worker rather than per run. A system-level accuracy number hides one bad worker inside four good ones, which is the specific way multi-agent quality problems stay invisible.
What you get at handover
Everything from a single agent handover, plus the artefacts that make a distributed system debuggable by somebody who was not there when it was built.
The trace viewer matters more here than anywhere else. Five agents produce five sets of logs, and reading them side by side to reconstruct one decision is a job nobody does twice. If a run cannot be read as one story, the system is undebuggable and gets switched off the first time it is blamed for something.
Where these projects go wrong
Single agent failures are mostly about tools and evaluation. Multi-agent failures are almost entirely about boundaries, and they are harder to see because every individual component looks fine.
The split followed the org chart
A sales agent, a support agent and a finance agent, because that is how the company is arranged. They share most of their tools, they need most of the same facts, and the supervisor spends its budget shuttling context between them. Six months later somebody merges two of them back and performance improves.
The supervisor summarised instead of passing evidence
It reads a document, writes a three line summary, and dispatches that. The worker then answers correctly from an input that lost the exception clause on page four. This is the single most common cause of confident wrong answers in a multi-agent system, and the fix is structural: envelopes carry resolved values and references to full sources, never a model's compression of them.
Nothing counted hops
Two workers each decide the task belongs to the other. Without a hop counter and a duplicate-objective check, they will pass it back and forth until a budget runs out, and the cost lands on a bill three weeks later. A hop cap is four lines of code and it is not optional.
Shared facts were re-derived per worker
Two workers independently look up which pricing policy applies, at slightly different moments or through slightly different tools, and get different answers. The supervisor synthesises both. The output contradicts itself inside one paragraph and looks, to a reader, like carelessness rather than an architecture defect. There is more on this pattern in how agents fail.
Quality was measured at the system level only
One aggregate accuracy figure across the whole run hides a single failing worker behind four competent ones, especially when that worker handles the least frequent case. Sample per worker, and weight by how much damage each worker can do rather than by how often it runs. This is what agent observability exists to support.
The dangerous multi-agent failure produces a well-written, well-evidenced answer to a question nobody asked, because the supervisor routed to the wrong worker and every downstream component did its job correctly on the wrong input. Nothing throws. Nothing retries. Only a human reading the dispatch plan catches it, which is why the plan is stored and sampled.
What it costs to run once live
A multi-agent system costs several times what one agent costs for the same request, and the multiple is mostly briefing overhead rather than useful work. Look at the multiple rather than the absolute figure, because the multiple survives price changes.
Defaults are illustrative, not quoted prices. The dispatch count assumes one call per worker plus one supervisor synthesis call. Replace prices from your provider's page today.
Two things the arithmetic understates. Supervisor synthesis runs over a context holding every worker result, so its calls are the largest in the system and grow with the number of workers. And a rejected result is paid for twice, once when the worker produced it and again when the corrected objective is re-dispatched, which is why validation strictness has a direct price.
| Cost line | How it scales | The lever |
|---|---|---|
| Worker tokens | Roughly linear in workers used per run | Route to fewer workers, shrink tool lists, trim envelopes |
| Briefing overhead | Linear in workers, paid whether or not the worker helps | Shorter worker prompts, smaller tool catalogues |
| Supervisor synthesis | Grows with the number and size of results | Ask workers for structured results rather than prose |
| Re-dispatch | Rises with validation strictness | Better objectives, not looser validation |
| Trace storage | Multiplies by the number of agents per run | Sample full payloads, always keep the dispatch plan |
| Maintenance | Grows with the number of boundaries | Fewer, better placed splits |
Before committing to a supervisor, try one agent with a smaller tool list and a retrieval step that fetches only the tools relevant to the request. It captures a good part of the specialisation gain without adding a boundary, and it takes days rather than weeks. If it is not enough, you will at least know precisely why.
How to tell whether you need more than one agent
The test is not how complicated the work feels. It is whether the work crosses a boundary that a single agent cannot hold without contradicting itself.
Two or more rows on the right, one of which is tools or permissions, means the split is probably real. Rows on the right that are all about organisation and none about tools means you have a staffing question rather than an architecture one, and the guide on when to use multiple agents works through the marginal cases.
How to start
Start by trying to avoid it. The cheapest multi-agent project is the one a two week measurement talks you out of.
- A scoping call
You describe the work and where the current approach strains. We are looking for boundaries: tools that do not overlap, permissions that must not be shared, data one part of the job should never see.
- The split test
We measure the existing agent, or build a single agent first, and locate where it actually loses. Roughly as often as not this stage ends with a recommendation not to split, which is a cheaper outcome than discovering it in week nine.
- Contracts before agents
Registry, envelope schema, fact ledger, permission ceilings and hop caps, agreed and written down before any worker exists.
- Build, attack, shadow, cut over
Workers evaluated in isolation, supervisor built last and attacked deliberately, then a shadow run at full topology and a cutover on a slice with per-worker sampling.
- The boundary review
We look at the dispatch plans and ask whether each boundary is still earning its tax. Merging two workers back together is a legitimate result and we have recommended it more than once.
ChatGPTalker, Multi-Agent Systems. A multi-agent system is several narrow agents with separate prompts, tools and permissions, coordinated by a supervisor that dispatches work and validates results. Splits should follow tool and permission boundaries, because every boundary costs context, tokens, latency and the ability to attribute a failure.