Twelve Agents, One Memory
How work gets split across specialised sub-agents without the coordination cost eating the benefit.
Work is delegated to 12 specialised sub-agents, each with its own tools and an explicit list of what it must refuse. They share no live state — coordination happens through files and through the orchestrator, because a shared context window was the thing that made earlier attempts unreliable.
Problem
A single agent handling procurement, finance, legal, content, research and operations accumulates two problems at once.
Tool sprawl. Every domain adds tools, and every tool definition consumes context on every call. Past a certain count the model spends more attention choosing between tools than using them, and reliability drops in a way that looks like model quality rather than configuration.
Prompt sprawl. Domain rules that should apply only to supplier questions are present during legal questions, and vice versa. They interfere.
The obvious fix — split into specialists — introduces a third problem, which is that most multi-agent systems spend more on coordination than they recover in focus.
Design
12 specialised agents, each defined by three things: the tools it may use, the domains it owns, and — critically — an explicit list of what it must not handle, with the correct destination named.
That refusal list is the part that makes it work. A specialist without one absorbs adjacent work it handles badly, and the resulting output looks like a capability problem rather than a routing one.
NOT FOR: purchase prices (→ procurement) · payroll (→ HR) · legal analysis (→ legal)
No shared live state. Sub-agents do not see each other's context. Coordination happens two ways only: through the orchestrator, which holds the task, and through files, which persist. A shared context window was tried in earlier designs and is the thing that made them unpredictable — every agent's reasoning polluted every other's.
Fan-out is explicit and bounded. Where a task genuinely spans domains, agents run in parallel from a written pairing table — a new supplier triggers procurement plus research, a contract with financial impact triggers finance plus legal. Cap: 5 parallel, roughly 25 turns each.
Every delegation carries a 5-field brief. Task with its reason, context, output shape, limits, required self-verification. The reason field is what lets a sub-agent make the judgement calls the brief did not anticipate.
Trade-offs
Routing is now a failure surface. A task sent to the wrong specialist produces confident, well-formatted, wrong-domain output. This is a real cost and the refusal lists exist to bound it, not eliminate it.
Context does not travel. A sub-agent starts cold every time, so the brief has to carry what it needs. Briefs are therefore longer than they feel they should be, and thin briefs are the most common cause of unusable results.
Parallel results need reconciliation. Two specialists can return contradictory findings. That is genuinely better than one agent silently picking a side — but somebody has to do the reconciling, and that somebody is the orchestrator.
Cost is higher per task. Each sub-agent has its own overhead. It pays off on tasks that would otherwise require one context to hold six domains, and it does not pay off on small ones. Delegating everything is how the pattern stops earning its keep.
How a task actually routes
The routing decision happens before any specialist is involved, and it is deliberately mechanical rather than clever.
First match wins. Each agent's definition carries its own trigger list, and the orchestrator matches against those rather than reasoning freely about which specialist "feels" right. Free reasoning about routing produces plausible mis-routes, and a plausible mis-route is expensive precisely because the output looks fine.
Multi-domain tasks fan out from a written table, not from judgement. A small set of task shapes have known pairings, and those pairings were derived from cases where a single specialist gave a confidently incomplete answer:
new supplier → procurement + research · contract with financial impact → finance + legal · property deal with legal exposure → real estate + legal · morning brief → operations + finance + research
The table is short and it earns its place by being written down. The same pairing derived fresh each time is derived differently each time.
Anything below a complexity threshold does not delegate at all. Delegation costs a brief, a cold start and a reconciliation. Below a few steps that overhead exceeds the benefit, and an orchestrator that delegates everything is slower and less accurate than one that does simple things directly.
A specialist that receives out-of-scope work refuses and names the destination. It does not attempt a partial answer. This is the single most important behaviour in the design, because the alternative — a specialist gamely doing its best outside its domain — produces exactly the output that is hardest to catch: well-formatted, confident, and wrong in a way the orchestrator cannot see.
What broke
Partial success reported as success. A fan-out of 5 returned a clean summary covering 4. The failed branch produced no output and its absence was invisible in the aggregate. Fix: every fan-out reports X of Y, names failed branches, and retries once before flagging.
Sub-agents inventing numbers. A brief that did not grant permission to fail produced a complete-looking answer with a fabricated component. An agent optimising for a full answer will produce one. Fix: explicit "not found is a valid result" in the limits field, plus confidence marking on every figure.
Delegated writes overwriting files. An agent told to record something wrote a fresh file over an existing one. Fix: read before write, append or edit if content exists, and write only into empty or new files.
When not to split
The pattern is easy to over-apply. Three signals that a domain should not become its own agent.
Fewer than a handful of tasks per month. A specialist that runs rarely is a definition file that goes stale — its tools change, its domain rules drift, and nobody notices because nothing exercises it. When it finally runs, it runs on assumptions from months ago.
No distinct tool set. If the proposed agent uses exactly the tools the orchestrator already has, the split buys nothing but a cold start. The gain comes from narrowing the tool surface; without that, it is overhead in a costume.
A boundary that cannot be stated as a refusal. If you cannot write the NOT FOR line — what this agent must decline and where it goes instead — the domain is not separable yet. Attempting the split anyway produces two agents that both half-own the same work, and the routing decision becomes a coin flip made freshly each time.
The reverse signal is worth naming too. A domain deserves its own agent when the orchestrator repeatedly loads the same 3 or 4 reference files together for one kind of question. That co-loading pattern is the domain announcing itself, and it is visible in the trigger table before anyone decides to formalise it.
Files
One definition file per agent — description, tools, domains, refusal list, and an embedded framework stack for its specialty. One routing table mapping task shapes to agents. One pairing table for the parallel cases. One log of dispatches, written automatically.
The routing table is the piece that needs the most maintenance and gets the least, because a wrong route produces plausible output rather than an error.