The first time I split a single agent into two, I thought I was solving a parallelism problem. What I actually did was create two new failure modes I did not have before.

Treated like an architecture purity question, the single-vs-multi-agent decision pulls engineers into absolutes. One agent is too monolithic, so many agents must be better.

Or the opposite claim: multiple agents introduce too much coordination overhead, so one agent is always the right call. Both framings are wrong.

The real question is what kind of failure you can afford.

What you actually get with a single agent

A single agent loop is synchronous by default. Perceive, think, act, remember.

Repeat. When it works, it works cleanly.

When it fails, you get one trace, one error, one place to look.

A single-agent loop can still fail at its tool boundary rather than in the loop architecture. Production AI agent error patterns explains those tool-call failures.

An agent would call a search tool that returned an empty array, or a database query that timed out after thirty seconds, and it would either retry sensibly or sit there spinning. Whatever broke, it broke in one place I could point at.

A single agent working a complex task accumulates its whole history inside the context window. That history includes tool results, intermediate thoughts, and files read earlier in the task.

Past a certain point, paying to feed that history into every reasoning step costs more than the step is worth, and the agent starts forgetting how the task began by the time it reaches the end. None of that is a software bug.

It is a physics problem rooted in the layered memory model for AI systems.

Serialization is the other constraint. A single agent does its steps in order, so if a task means scrape ten pages, summarize each, then compare them, the agent grinds through all ten scrapes one at a time before it touches the comparison.

Batching prompts buys some throughput, but the loop itself runs nothing in parallel.

Where multi-agent systems pay off

Two reasons pushed me toward multi-agent architectures. Specialization came first.

A coding agent that also has to drive a file browser, a shell, and a PR reviewer is holding twenty-odd tool schemas in its head at once, and it starts misfiring: calling the shell when it meant to read a file, passing a diff to the wrong tool. Splitting those into separate agents let each one carry a handful of tools it understood cold.

That is the pattern I later recognized as the supervisor agent pattern in production. The supervisor becomes an agentic router when it chooses which specialist receives each request.

Isolation was the second reason. A research agent that goes off the rails and starts hallucinating sources should not be able to corrupt the state of a code generation agent working the same ticket.

Giving each its own memory, context, and failure boundary keeps one wreck from spreading. Think of it like watertight compartments in a ship's hull: flooding one does not sink the rest.

Speed gains are real but conditional. When two agents work independent sub-problems at the same time, latency drops toward the longest single branch rather than the sum of all of them.

Break a task into three parallel workstreams and you can see something close to a 3x cut in wall-clock time. That only holds if the work is genuinely parallelizable and the agents are not stalling on each other for shared state.

SINGLE VS MULTI-AGENT

The failure modes nobody talks about

What the architecture debates skip over is where multi-agent systems actually break: in transit, between agents.

A single agent fails inside a loop you control. A multi-agent system fails across message boundaries, and the failures are quieter for it.

The supervisor sends a task to a sub-agent and gets back JSON shaped nothing like what it expected. A sub-agent finishes its work cleanly, then the memory update never lands in the shared store.

The coordinator dispatches tasks to three workers and one of them drops off the network without raising a single error.

Building a pipeline on event-driven agent architectures taught me this the slow way. The event bus was rock solid in testing.

Under production load, message delivery turned non-deterministic. Agents would finish their work and publish results that nobody consumed, because the consumer had restarted and re-subscribed under a fresh consumer group.

Every dashboard said the system was alive. No actual work was moving through it.

Error propagation is the other trap. Inside a single agent, an error stays local to the loop.

Across agents, one bad output cascades the moment a downstream agent trusts it without validation, which is exactly what I described under production AI agent errors. Hand a planner agent garbage findings from a research agent and it will build its entire plan on that rotten foundation, confidently.

Memory becomes exponentially more complex

Single-agent memory is one problem. Multi-agent memory is several interconnected ones.

Shared memory drags consistency into the picture. When Agent A writes to the shared store and Agent B reads from it a second later, has B actually seen A's write yet, or is it reading a value from before the commit landed?

Event-driven message passing trades that for a different headache: each agent holds its own view of state, and keeping those views in sync becomes my job, by hand.

One failure burned me badly enough that I still remember the shape of it. A planning agent read the shared store expecting the research agent's findings to be there.

The research agent had finished, no error, clean exit. It had written those findings to its own isolated memory, never to the shared store.

The planner read an empty slot, assumed nothing had been found, and planned around a hole.

So I ended up wiring explicit synchronization into the workflow: each agent confirmed its writes had propagated before the next agent was cleared to start. That bought correctness at the cost of latency, and it made the workflow more serial, which chipped away at the very reason I had split into multiple agents to begin with.

The shared versus isolated memory guide separates that coordination choice from the wider memory hierarchy. The tradeoff is which failure mode the system can contain and explain.

When to make the call

My heuristic is plain. For a task with one clear goal whose steps run linear or lightly branched, say "read this repo, find the bug, open a PR", a single agent with good context window management gets there faster and springs fewer surprises.

When the work splits into genuinely independent streams, demands tool sets that share no schemas, or needs real concurrency to hit a latency target, I reach for multiple agents.

The decision is operational, not architectural. The question I sit with is which failure I am choosing to live with.

A single agent that fails completely tends to be easier to recover than a multi-agent system that fails partially and keeps running in a broken state, reporting success the whole time.

I have shipped both. The multi-agent systems felt more impressive going in.

The single-agent systems were easier to debug when things went wrong.