Multi-Agent System Architecture Patterns
Choosing the wrong coordination pattern is why multi-agent systems fail in production, not design.

Multi-agent architecture isn't one thing. It's a set of distinct patterns, each with its own coordination model, its own trust boundaries, and its own way of breaking, and picking the wrong one is why so many of these systems fall apart in production instead of in design review, months earlier, when a whiteboard sketch would have caught it for free.
The moment a second agent enters a system, the questions change entirely. Who controls sequencing? How does state actually move from one agent to another? What happens when one of them fails halfway through a task, and does the rest of the system even notice, or does it just keep running on stale assumptions? These are distributed systems questions first and model-capability questions a distant second. There's a name for the instinct to answer them with the wrong tool anyway: the prompting fallacy, where a team sees a coordination failure and reaches for a prompt tweak or a model swap instead of fixing the structure underneath it. A better prompt has never once given an orchestrator a way to resume after it crashes. That capability comes from the architecture, full stop.
At its core, multi-agent architecture is the structural pattern by which a complex task gets divided among specialized agents that coordinate over time. Simple to say. Harder to get right in practice, and the gap between those two is basically what this piece is about. Research on this has grown fast the past couple of years, enterprise interest has followed close behind, but full production deployment is still rare, and when you ask organizations what's holding them back, system complexity comes up more than anything else does. Choose a coordination pattern without understanding what it optimizes for, and you find out its failure modes the hard way: after launch, in front of users, instead of on a whiteboard where fixing it costs nothing.
When multi-agent architecture is and isn't the right call
Microsoft's own guidance here is worth quoting almost verbatim: use the lowest level of complexity that reliably meets your requirements. That's the standard: the lowest one that actually works, not the most impressive architecture or the one with the most agents, which is a less exciting sentence to write than most vendor docs go for, and I respect that they wrote it anyway.
So how do you know a single agent has hit its ceiling? A few signals tend to show up together, and worth watching for all of them rather than jumping at the first one. Tool selection starts failing once too many tools get crammed into context, and the agent hesitates between plausible choices or just picks wrong. Long-horizon tasks blow past the context window before the work's half done. The reasoning spans genuinely separate domains of expertise, the kind where one agent would need to know tax law and API design at the same time. Or parallelism would actually change how fast the system finishes, and running everything through one sequential agent is leaving throughput on the table for no good reason.
None of that makes multi-agent automatically the right answer, though. Consider the single agent that hasn't actually been pushed to its limit yet, and is failing for reasons a cleaner tool schema or a sharper prompt would fix outright; bolting on a second agent here just adds a second thing that can break. Well-bounded, naturally sequential tasks are often handled more reliably by one agent working step by step than by the same task carved into pieces and handed to a coordination layer that now needs its own debugging. And if the coordination overhead ends up costing more than the complexity it's supposed to manage, that's the system telling you something you should probably listen to.
Cost is part of this too, and it's not a rounding error. Coordination between agents burns real tokens at scale: every handoff, every synthesis step, every round of an orchestrator reviewing a worker's output costs something a single-agent loop never pays. Multi-agent runs cost materially more per session than single-agent ones do, and that gap compounds fast once you're running thousands of sessions a day instead of a handful in a demo.
Assuming multi-agent is the right call for your task, the pattern you pick determines what the system can and can't do. That's the rest of this piece.
The orchestrator-worker pattern and where centralized control pays off
Most people invent this one independently before they know its name. A single orchestrator takes the complex task, splits it into pieces, and hands those pieces to a pool of worker agents; the workers do their part and report back, and the orchestrator collects everything and stitches together the final result.
What this buys you is centralized control and predictable sequencing. You always know who's in charge, and task decomposition happens in one place instead of getting negotiated between agents mid-flight. There are two flavors worth telling apart. In the synchronous version, the orchestrator waits for each worker to finish before moving on; easy to reason about, easy to debug, but slow, since nothing overlaps. In the event-driven version, the orchestrator emits tasks as events onto a message bus and workers pick them up asynchronously, so throughput goes up, but so does the headache of reconstructing what happened once something breaks.
Trust runs one direction. Workers are subordinate, usually confined to isolated environments with limited scope, and the orchestrator holds the only authority in the room. That also makes it the single point of failure: if the orchestrator process dies mid-task, the whole decomposition it was managing vanishes unless that state got persisted somewhere outside the process itself. A lot of orchestrator-worker builds quietly fall apart right here, because ephemeral runtimes were never built to survive a crash halfway through.
The pattern earns its keep in document processing pipelines, research synthesis, and multi-step code generation, anywhere the subtasks are genuinely separable and don't need to argue with each other. It strains when tasks resist clean upfront decomposition, or when the orchestrator itself becomes the bottleneck under real concurrency, since every worker still has to check back in with the same central authority no matter how many of them are running.
Hierarchical multi-agent systems and the tradeoff between global efficiency and local autonomy
Hierarchical systems look like orchestrator-worker on first glance, but the shape underneath is different: agents sit in tiers, and delegation runs down a chain instead of fanning out flat from one hub. A planner delegates to a manager, the manager delegates to specialists, and those specialists might coordinate sub-agents of their own below that. Chains, not spokes.
Why bother with tiers at all? Some tasks are too complex, and span too many domains, for any single orchestrator to hold the full context needed to manage every subtask directly at once. Recent taxonomic work on these systems points to a few control dimensions that actually decide how a hierarchy behaves in practice. Does context flow top-down only, bottom-up only, or both directions? Do higher tiers plan on longer time horizons than the tiers executing below them, thinking in days while specialists act in seconds? And which tier gets to override or cancel work happening beneath it?
That last question is where the real tradeoff of the whole pattern lives: global efficiency against local autonomy. A top-level planner optimizing for the whole system might override a specialist's judgment call, and that's global efficiency doing its job. But a specialist that has to pause and wait for sign-off every time it wants to adapt to what it's actually seeing loses the exact autonomy that made it worth specializing in the first place. Neither side wins by default. Which way you lean should depend on the task in front of you, not on some architectural preference you brought in the door.
Each tier boundary doubles as a trust handoff. An agent at tier two trusts tier three's output without full visibility into how that output was made, which is a quieter version of the same problem distributed systems have always had with black-box dependencies. A setup that shows up a lot in enterprise deployments: a planner-executor pair at the top, handing work down to a specialist swarm below, with a critic-refiner loop watching quality across the tiers. Sensible enough, but it has a known failure mode. A mistake made at a lower tier can climb upward before anything catches it, and once it has, re-running the whole chain to fix it gets expensive fast.
Pipeline architecture and why sequential flow is underrated for production reliability
Pipelines get less attention than they've earned, maybe because they're almost too simple to write a paper about. Agents sit as stages in a line, one's output feeds the next one's input, and there's no orchestrator required, because the sequence itself does the coordinating.
What that buys you is determinism and something you can actually audit. You always know which stage produced a given output, which sounds minor until you're the one at 2 a.m. trying to figure out why a document came out malformed. Trust runs stage to stage rather than through a chain of command, simpler than the hierarchical model, though it comes with a real cost: a poisoned output at stage two flows straight into stage three unless stage three bothers to check what it received.
Stages can run synchronously, blocking until the one before finishes, or asynchronously with a queue sitting between them. Async pipelines shrug off uneven stage latency far better. If stage two occasionally takes ten times longer than usual, a synchronous pipeline grinds to a halt waiting on it, while an async one just lets the queue soak it up.
Pipelines excel at ETL-style document processing, at multi-step content generation with genuinely separate transformation stages (extract, summarize, format, validate), and at compliance workflows where each stage needs to stand on its own for an audit. They fall apart fast, though, on tasks that need backtracking, branching on intermediate results, or real parallel execution, since the linear shape forces artificial order onto work that was never actually sequential. LlamaIndex Workflows is built around an event-driven model that fits document-heavy pipelines well for that reason.
Hub-and-spoke architecture and how it handles specialist coordination without agent-to-agent coupling
Picture a central hub agent routing incoming tasks out to specialist spoke agents. The spokes never talk to each other. Every bit of coordination runs back through the hub, no exceptions.
The difference from orchestrator-worker is subtle but it matters: the hub's job is routing and aggregation, not decomposing a task from scratch. Spokes are predefined specialists with fixed roles, not general-purpose workers waiting to be told what to do next. The hub keeps a routing table, or a routing policy, deciding which spoke handles which request type. From the hub's perspective, spokes look stateless: input goes in, the specialized thing happens, output comes back.
That isolation is the actual payoff. A compromised or failing spoke can't reach across and drag another spoke down with it, because there's no channel between them to exploit in the first place. The hub is the one trust authority, which maps cleanly onto sandboxed execution: each spoke in its own contained environment, no path into another spoke's runtime even if something inside it goes badly wrong.
This fits customer-facing systems naturally, where request types map onto distinct specialists (billing, support, technical troubleshooting), and enterprise workflows built around clear functional domains. The scaling problem is the hub itself: at high concurrency, everything funneling through one router turns into a bottleneck. The usual fix is making the hub stateless and horizontally scalable, but that just pushes the state problem outward, onto whatever external system now has to track it instead.
Peer-to-peer and swarm patterns and when emergent coordination is worth the unpredictability
Take the central coordinator away entirely and you get peer-to-peer. Agents talk straight to each other, no hub, no orchestrator, no chain of command, and in swarm variants there isn't even a fixed conversation structure. Agents follow local rules, and something like collective behavior emerges from all of them acting at once, which is either the most elegant idea in this piece or the riskiest one, depending on how much you need to explain the outcome afterward.
What you get for giving up central control: resilience, since there's no single point of failure to take the whole system down with it, real parallelism, and room to let several agents explore a solution space independently instead of marching through it in lockstep. Coordination happens through direct negotiation between agents, through a shared state store they all read and write, or through agents just reacting to a shared environment as it shifts around them.
How does this hold up once a task gets complicated? Not especially well, honestly. Peer-to-peer handles simple tasks fine, but it struggles the moment subtasks develop real dependencies on each other; implicit negotiation between peers is a weak stand-in for explicit sequencing once the order of operations actually matters. Trust is the hardest problem of any pattern in this piece, because every agent is potentially a peer to every other one, and a single compromised agent has a wider blast radius here than it would in a hub or a hierarchy, where its reach gets contained by design rather than by luck. Swarm behavior specifically needs shared state that many agents read and write at once, which turns consistency and conflict resolution into live design problems instead of solved ones.
Where does this actually earn its keep? Simulation and modeling tasks that benefit from several independent agent perspectives. Debate-style reasoning systems where agents are supposed to critique each other rather than agree too fast. Genuine exploration problems with no clean decomposition to begin with. Outside those, go carefully: emergent behavior is much harder to test, audit, and explain after the fact, and anyone operating under compliance requirements should walk in knowing exactly what they're trading away for that resilience.
How production systems mix patterns rather than pick one
Here's what tends to surprise people coming out of the research literature: almost nobody in production runs one pattern end to end. Enterprises stack patterns at different layers of the same system, because different parts of a task genuinely call for different coordination models, and pretending otherwise just means fighting the shape of your own problem.
A few configurations keep showing up. A hierarchical planner-executor pair sits at the top, delegating to a specialist swarm below it, and that swarm coordinates internally through peer-to-peer negotiation. Or a pipeline carries the main task flow start to finish, but wherever a stage needs parallel execution, an orchestrator-worker pattern takes over just for that stage before handing control back. Sometimes a hub-and-spoke router sits at the entry point, and once a request gets classified, it's handed off into a hierarchical sub-system built for that specific domain. Layered across all of it, a critic-refiner loop often sits watching quality, less a pattern of its own than a cross-cutting concern bolted onto whatever's underneath.
The governing principle isn't complicated, even if it's easy to break in practice: match the coordination model to what each layer's task actually demands rather than to some preference for architectural consistency across the whole diagram. A system doesn't need to look elegant on a whiteboard. It needs each layer coordinating the way that layer's job requires.
Frameworks reflect this mixing pretty directly. LangGraph's graph-based orchestration suits stateful multi-agent flows where different nodes in the graph can represent entirely different pattern types side by side. CrewAI's role-based model maps naturally onto hub-and-spoke or hierarchical setups, especially when you're prototyping fast. The OpenAI Agents SDK goes a different way: four deliberately minimal primitives, agents, handoffs, guardrails, sessions, leaving pattern composition to the developer rather than baking one in from the start.
Mixing patterns like this doesn't make the infrastructure underneath simpler. If anything, it raises the bar. Every boundary between patterns is a coordination handoff, and each one has to be observable, recoverable, and isolated from the others without leaking. The infrastructure layer is what holds all of that together across pattern types, which is the last thing worth asking about.
What each pattern demands from the runtime underneath it
Every pattern above shares one requirement that's easy to forget until it bites: state has to survive across agent calls. The runtime can never assume an agent's work finishes inside a single synchronous request-response cycle, because almost none of these patterns work that way.
General-purpose infrastructure tends to fail agents in a few specific, recognizable ways. Serverless platforms with short execution timeouts cut off long-running orchestrators mid-task, with no path back to where they left off. Stateless container models lose the entire task decomposition graph the second the orchestrator's container gets recycled. Shared container environments let one agent's execution bleed into another's, quietly breaking the isolation that hub-and-spoke and hierarchical trust boundaries were supposed to guarantee.
Each pattern also has its own specific demand on top of that shared baseline. Orchestrator-worker needs durable state badly: every worker call has to get journaled somewhere, so the system can resume after a failure instead of re-running subtasks that already finished successfully. Hierarchical systems need each tier boundary to produce a consistent, auditable state handoff, one you can replay later to trace where the chain actually broke. Pipelines need stage outputs durable between stages; if stage three fails, re-running everything from stage one isn't something a production system at real scale can afford to do. Hub-and-spoke needs each spoke isolated in its own execution environment, so one spoke's failure or compromise can't spread, and it needs the hub to spin up fresh spoke instances fast, without tacking latency onto every routing decision. Peer-to-peer and swarm need shared state that stays consistent under load and tolerates conflicts, since plenty of agents may be reading and writing it at once.
That provisioning-speed point deserves its own moment, because it's easy to underrate. For any pattern that fans out to many agents at once (orchestrator-worker, hub-and-spoke, swarm), spinning up isolated environments has to happen in milliseconds rather than seconds. Provisioning latency that looks trivial in isolation compounds across every coordination step in the system, and it shows up later as a real, measurable hit to end-to-end task performance.
The primitive that makes any of this survivable is durable execution: journaling every step, every LLM call, every tool invocation, every external API request, so any agent in any pattern can pick back up from the last completed checkpoint instead of starting over from zero. Temporal, Inngest, and AWS Bedrock AgentCore each bring some version of this, and purpose-built agent runtimes increasingly build it in from the start rather than leaving teams to bolt it on after something breaks in production.
There's a transparency angle here too, and it's not a footnote. Teams running complex, multi-pattern systems eventually need to see what the runtime is actually doing at each handoff, and a black-box execution environment makes that kind of scrutiny nearly impossible right when you need it most, usually at 2 a.m., usually after something already went wrong.


