“Multi-agent” gets treated as the senior tier of “agent,” the architecture you graduate to once one model stops being enough. That instinct is usually backwards. A team showed me their architecture last month and it had nine agents in it. A planner, a researcher, a critic, a writer, a fact-checker, a router, two specialists, and one whose job I never fully understood. The task was: read a document and pull out the obligations. One model with one good prompt does that. They had built a small bureaucracy to summarize a PDF, and like every bureaucracy, most of its energy went into the agents talking to each other.
This is the dominant failure I see right now. People reach for multi-agent because more boxes and more arrows make a diagram look like serious architecture, the kind that gets nodded at in a review. My honest default runs the other direction: fewer agents, usually one, sometimes none.
What an “agent” actually buys you
An agent is a loop: the model picks a tool, sees the result, decides what to do next, repeats until it thinks it is done. That loop is where the cost sits, because every hop is another model call, another chance to misread the last step, another stretch of latency, another slice of the token bill. One agent is already a stochastic thing wrapped around a control flow you do not fully own.
Run several of them and have them hand work to each other, and what you have built is not more intelligence but a distributed system, a flaky one, where the messages between nodes are written in English by a model that hallucinates. Every handoff is a place where a fact gets dropped, a constraint gets softened, or a task mutates into a slightly different task. The supervisor asks for the top three risks; the specialist returns five, two of them invented; the critic blesses them because they read well. No one lied at any step; the information just decayed at every border.
Most multi-agent systems are not solving a multi-agent problem at all. They are one agent’s job that somebody chopped into stages because chopping felt like engineering. The moment you chop, you sign up for the orchestration tax: serialization between steps, a protocol for who talks to whom, retries when a sub-agent returns garbage, and the debugging session from hell when the output is wrong and you have five transcripts to read instead of one.
The cases where it genuinely pays
I am not against multiple agents; I have shipped them. The bar is just specific, and in my experience only three reasons hold up.
The first is real parallelism, not “these steps could run side by side in principle,” but “these subtasks do not depend on each other and the wall-clock time matters.” Fan out a research question across forty sources at once, let each branch read independently, fold the results back. That is a genuine win, because the work is actually independent and you are buying speed you cannot get from one sequential loop. The test is brutal and simple: if subtask B needs anything subtask A produced, they are not parallel, and you are kidding yourself.
The second reason is separation of privilege, and it is the one I care about most, because it is a security argument rather than a performance one. The agent that reads from the production database should not be the same agent that can post to a customer. The agent that drafts a refund should not be the agent that approves it. Splitting here has nothing to do with making the model smarter and everything to do with keeping the blast radius small. A compromised or confused agent should be able to touch exactly one bounded set of tools, and no more. I will split for this even when a single agent would technically work, because the failure I am designing against is not a wrong answer but a wrong action on money or data.
The third is genuinely distinct context. When two subtasks need different tools, different system prompts, and different reference material, and stuffing all of it into one context window makes the model worse at both, a clean split helps. A coding sub-agent with its repo tools and a compliance sub-agent with its policy corpus do not want to share a brain. Past a point, extra context in one window stops being richer and starts being noise, and the model begins confusing one job’s instructions for the other’s.
Notice what is not on that list. “It feels more organized.” “Each agent has a clear role.” “It mirrors how a human team works.” These are aesthetics dressed up as architecture. An org chart is a coordination cost humans pay because one human cannot hold everything, and a model can hold a great deal in one prompt. There is no sense in paying a coordination cost to solve a problem you do not have.
Supervisor and pipeline, and the complexity to refuse
When you do split, two shapes cover almost everything.
A pipeline is a fixed sequence: stage one’s output is stage two’s input, the path never branches, and you control the routing in plain code, not by asking a model where to go next. A supervisor is one orchestrator that holds the goal and delegates to specialists, deciding at runtime who gets the next piece. Pipelines are predictable and cheap to debug, while supervisors are flexible but cost more, because the supervisor itself is a model call in the loop, reasoning about delegation every turn.
Left: the supervisor pattern, with one model spending tokens to route and three sub-agents to coordinate. Right: the same capability as one agent calling the same tools directly, no inter-agent messages to decay.
The two sides of that diagram do the same job. The right-hand version has the same tools; it can read, search, and draft, exactly like the left-hand fleet. What it lacks is three handoffs where meaning leaks, a supervisor burning tokens to decide who speaks, and four transcripts to reconcile when it goes wrong. For most of what people build, the right side is not a downgrade but the version that still works on a Tuesday when something breaks and you have to find out why before the on-call patience runs out.
That leaves the complexity I refuse to build. I refuse agents that exist only to critique another agent, when an eval or a validation check in code does the same job deterministically and you can actually trust the result. I refuse a router-agent deciding control flow that a match statement would handle, because a model choosing a branch is a non-deterministic bug generator wearing a smart hat. I refuse “agent debates agent” setups, which are mostly a way to spend tokens performing rigor. I refuse any agent boundary that exists because the diagram looked thin without it.
The plain-code option deserves its own line, because it is the one people skip. A surprising share of “agentic” work is a fixed sequence of three known steps with one model call in the middle. That is not an agent, it is a function with an LLM in it, and you should write it as a function: testable, traceable, cheap, and it does the same thing every time you run it. Reach for an agent loop only when the path genuinely cannot be known ahead of time, and reach for several only when one of those three reasons is true and you can name which one out loud.
Before any team I work with earns a second agent, it has to answer one question: what does this agent do that a tool call inside the first one could not? Real parallelism, isolated privilege, or a context that genuinely needs its own brain are answers worth building on. “It’s cleaner” is not one of them, and a team that offers it does not have a multi-agent problem on its hands, only one agent and a diagram someone got attached to.