Multi-Agent Systems Explained: How Fleets of Agents Coordinate Without Stepping on Each Other
The four ways agents collide, where every coordination pattern gives out, and the mechanisms that stop it.
September 8, 2026 · Caura.AI
Fleets of AI agents stop colliding when one agent’s decision becomes a scoped, queryable constraint that every later agent has to read before it acts. Prompt instructions do not achieve this. Anthropic’s own multi-agent research system beat a single Claude Opus 4 agent by 90.2% on their internal research eval, and in early versions still had one subagent researching the 2021 automotive chip crisis while two others duplicated work on 2025 supply chains.
That is the whole problem in one sentence: more agents buy you parallelism and buy you collisions at the same time. This blog covers the four ways agents step on each other, the coordination patterns in use today and exactly where each one fails, what a shared memory layer has to enforce for the failures to stop, and three open-source reference fleets you can clone and run this afternoon to see it working.
What is a multi-agent system, and when does it become a fleet?
A multi-agent system is a set of LLM agents, each with a narrow role, that work together on a larger task, rather than a single large agent trying to do everything. Each agent runs its own loop: it receives a system prompt defining its role and a list of tools it is allowed to call, then keeps calling those tools and reading the results until it decides its turn is done.
Pipeline, fleet, and why the distinction decides your architecture
A pipeline is a fixed sequence. Agent A finishes, agent B starts, the handoff order is written in code. A fleet is a standing population of agents that run continuously, in parallel, often on separate machines, on work that arrives on its own schedule. eToro runs 300 or more specialized agents this way, all writing into one shared memory layer that holds 26,500 or more memories and answers recalls at 23 ms p50.
The distinction matters because pipelines can cheat. If agent B always runs after agent A, you can pass A’s output straight into B’s prompt. A fleet has no shared prompt to pass anything into. Agent 17 writes something at 02:00, and agent 4 needs it at 03:00, with no orchestrator awake in between.
The three properties any coordination mechanism has to deliver
Coordination means a decision made by one agent becomes visible, findable, and binding for every agent that acts after it. Caura’s engineering team names the three requirements directly: persistence (the decision outlives the turn that made it), queryability (a later agent can find it without knowing it exists), and enforcement (the constraint shapes what the later agent can actually do).
Most architectures deliver one. Almost none deliver all three. The rest of this piece is about that gap.
Why do agents step on each other in the first place?
Because each agent is individually correct and collectively wrong. No single output is a mistake. The contradiction exists only between two decisions made by two agents that never communicated. Four distinct collisions appear in production, and each requires a different fix.
Duplicate work
Two agents solve the same problem independently, and you pay twice. Anthropic’s write-up gives a concrete case: the lead agent gave instructions so vague that subagents ran the exact same searches. Their fix was prescriptive delegation, in which every subagent receives an objective, an output format, tool guidance, and explicit task boundaries. That helps. It does not survive the case where agent B’s task genuinely overlaps something agent A solved last Tuesday, in a session that has since ended.
Constraint contradiction
A performance agent audits a page, decides the JavaScript bundle is too heavy, and writes a rule: no external scripts. Later in the same run, an SEO agent wants structured data and reaches for a schema.org library on a CDN. Both agents did their job. Together they shipped a page that violates its own performance budget, and nothing caught it because nothing connected the two decisions.
Walden Yan at Cognition states the general form as a principle: “Actions carry implicit decisions, and conflicting decisions carry bad results.” His Flappy Bird example is the same shape. Subagent 1 builds a background that looks like Super Mario Bros, subagent 2 builds a bird that moves nothing like Flappy Bird, and the combining agent inherits both misreadings.
Stale fact propagation
A competitor’s Pro plan costs $299 a month. Your sourcing agent writes that fact daily for eight days. On day nine, the price moves to $349. Now the pool holds eight memories asserting $299 and one asserting $349, and retrieval ranks by similarity, not by recency or confirmation count. All nine come back in the same result set. The synthesis agent produces a confidently wrong brief.
No exception is logged. No conflict is flagged. Caura’s team calls this a silent failure mode, and silent is the operative word: the signal that something is wrong is absent rather than subtle.
Boundary leakage
Your sales agent recalls a legal hold it should never have seen, or a support agent surfaces customer PII into a cross-team summary. This one is not a correctness bug; it is a compliance incident, and it is the collision that turns a working pilot into a blocked procurement review.
Four collisions, one root cause. Every one of them is a question about what an agent knows at the moment it decides, which is a memory-architecture question rather than a prompting question.
How do agents coordinate today, and where does each pattern break?
Four patterns dominate. Each is a real answer to a real constraint, and each has a specific breaking point worth knowing before you commit to it.
Orchestrator and worker
A lead agent decomposes the task, spawns subagents in parallel, and synthesises their returns. This is the pattern behind Anthropic’s Research feature, and it works: spinning up three to five subagents in parallel rather than serially cut research time by up to 90% on complex queries.
The breaking point is stated in the same post. Lead agents execute subagents synchronously, so the lead cannot steer a subagent mid-flight, subagents cannot coordinate with each other, and the whole system blocks while one subagent finishes searching. Coordination flows through a single point that is asleep whenever a worker is thinking.
Handoff and swarm
Agents pass control to each other directly, each carrying the conversation forward. Frameworks including AutoGen and the OpenAI Agents SDK make this cheap to build. The cost is context. Yan’s first principle is to share full agent traces rather than individual messages, and handoff architectures rarely do, because forwarding the whole trace to every agent is exactly what blows the context budget you split the work to avoid.
Message protocols
A2A standardizes how agents talk to each other across vendors and frameworks, over HTTP, JSON-RPC, and Server-Sent Events, with long-running operations built in. MCP standardizes how an agent reaches a tool. Both are worth adopting.
Neither solves this problem, and the reason is in A2A’s own design principles: agents “maintain opaque operations, so agents can’t see the inner workings of other agents during collaboration.” Opacity is correct for interop across organizations. It also means a protocol tells you how to deliver a message and says nothing about what a fleet collectively knows. Messaging is transport. Coordination is state.
Shared store, also called a blackboard
Every agent writes decisions to a common store and reads it before acting. This is the only one of the four that delivers both persistence and queryability, and it is the pattern that the rest of this piece develops. Its naive form fails too: a plain vector database gives you a pool where old and new facts coexist without a resolution mechanism, and where an agent scoped to sales can retrieve a legal hold because nothing structural prevents the query.
| Pattern | Persistence | Queryability | Enforcement | Breaks when |
|---|---|---|---|---|
| Orchestrator and worker | Only within the run | Via the lead agent | Lead can re-prompt | Workers run in parallel and cannot see each other |
| Handoff and swarm | Only in the past trace | No | No | Full traces exceed the context budget |
| A2A and MCP messaging | No, by design | No | No | You need shared state, not delivery |
| Plain vector store | Yes | Yes, semantically | No | Stale and out-of-scope rows return in the same result set |
| Governed shared memory | Yes | Yes, hybrid search | Yes, at the query layer | Covered in the failure section below |
What must be true for a shared store to enforce coordination?
Enforcement is the column where almost everything fails. A store enforces coordination when a constraint written by one agent changes what a later agent is structurally able to retrieve and act on, rather than reminding it to behave. Five mechanisms do that work in Caura’s governed shared memory layer, and each maps to one of the four collisions above.
Scope stamped at write time
Every memory carries a visibility scope when it is written: scope_agent, scope_team, or scope_org. Recall respects it by default. An HR-fleet memory does not appear in a support-fleet recall because it structurally can, not because someone remembered to add a filter to that particular query. Above scope sits fleet_id, which becomes a WHERE fleet_id IN (...) predicate that runs before the hybrid search, and above that sits the tenant boundary, resolved server-side from the API key rather than from anything the agent declares. Boundary leakage dies here.
Hybrid recall, not vector-only
caura_recall runs vector similarity, keyword matching, and a knowledge-graph traversal over extracted entities in one call. That combination is what lets an SEO agent find a performance rule it did not know existed and would have phrased differently. Pure vector search misses exact terms like a named rule; pure keyword search misses the paraphrase. Duplicate work and constraint contradiction both need this to be reliable, because an agent that cannot find the prior decision behaves exactly like an agent that was never told.
Status lifecycle and contradiction detection
Memories move through eight statuses: active, pending, confirmed, cancelled, outdated, conflicted, archived, deleted. When the $349 write lands, an async contradiction pass compares it to the pool through the single-value RDF path, flips the eight $299 rows to outdated, and sets supersedes_id on the new row to point at what it replaced. A default recall then excludes them at the query layer, before a single token reaches the agent’s context. Stale fact propagation dies here.
One trap worth knowing, because it is counterintuitive and the Caura docs are blunt about it: the status filter on recall is an exact match, not a shorthand for “current.” Passing status:"active" excludes confirmed memories too, so a synthesis agent filtering on active would get zero results by day eight. The governed query is the default recall with no status filter at all.
Keystones for rules that must never be missed
Retrieval is a search problem, and search can miss. Policy cannot afford a miss. Keystones are mandatory rules fetched deterministically at session start with no semantic ranking and no top_k, merged across tenant, fleet, and agent scope, and framed in the tool description itself as overriding conflicting instructions. Authoring anything beyond an agent’s own scope requires trust level 2 or higher, which stops a prompt-injected default-trust agent from planting a firm-wide policy. The Caura team’s line on this is the sharpest summary of the whole category: “Probabilistic enforcement isn’t enforcement, it’s hope.”
Outcome feedback
Agents report results against the memories they recalled through caura_evolve. Successes reinforce those memories; failures generate a preventive rule, which defaults to the reporting agent’s own private scope. Promoting that rule to fleet scope is a deliberate call that requires trust level 2 or higher, and that promotion is what puts the lesson in front of the next forty agents before they repeat the mistake. This is the loop a single-agent memory system cannot close, because there is no second agent to close it with.
If you are running more than a handful of agents against shared context today and enforcing separation with prompt instructions, the governed memory concepts in Caura’s docs are worth an hour. The free tier covers 10,000 memories with unlimited agents and fleets, which is enough to reproduce every mechanism above against your own workload.
What does coordination look like in code you can actually run?
Caura publishes three reference fleets, each corresponding to a single collision. All three are clonable, all three run against a free account, and the core engine is Apache 2.0 at github.com/caura-ai/caura.
caura-build-fleet: making an upstream decision bind a downstream agent
Five agents build and review a web page in sequence: Frontend, Performance, SEO, Code Review, and a read-only Manager. The rule the fleet runs on is short enough to memorize: recall before acting, write after deciding. Performance writes the no-external-scripts rule. SEO recalls fleet memory before choosing how to add structured data, sees the rule, and picks inline JSON-LD instead of a CDN library. Code Review then cites specific memory IDs in its verdict, which is what makes the propagation auditable rather than assumed.
The detail worth stealing is that this is not enforced by instruction. Each agent’s allowlist filters the tool list before the model ever sees it, so caura_write is simply absent from the schema sent to a read-only agent. The first iteration sets tool_choice="required", forcing a tool call rather than an answer from the model’s own assumptions.
caura-long-run-fleet: keeping a 14-day fleet from believing an old price
Three agents share one pool over 14 simulated days: Sourcing writes, Verification independently confirms with filter_agent_id: "sourcing-agent" so it checks a known source rather than the whole pool, and Synthesis reads only governed memory. Day nine is the whole demo. Run python simulate.py --start 9 --end 10, and you land straight on the contradiction.
Role separation here is structural rather than tidy. If Sourcing confirmed its own writes, the comparison would happen in the same context that produced the write, so a new write contradicting eight prior confirmed entries would never be caught. The synthesis agent also runs a second recall filtered to status:"outdated" and reports the suppression count, which turns a silent storage-layer operation into a line in the brief a human can audit.
caura-cross-fleet-gov: proving a boundary holds
Three OpenClaw agents named Vera (sales), Lex (legal) and Axis (admin) share one backend across three partitions: fleet-sales, fleet-legal, fleet-org-shared. Sales writes a $420k renewal negotiation. Legal writes a GDPR hold on the same account. Sales recalls and gets zero results on the hold. Admin recalls across all three, labels each result with its source fleet, surfaces the contradiction between an active negotiation and a compliance freeze, and escalates to a human.
The README does something most vendor demos do not, which is publish the step where the guarantee is weaker than it sounds. Step B′ has the sales agent deliberately declare fleet_ids: ["fleet-legal"], and the legal memory comes back. In the self-hosted deploy the storage layer filters to whatever fleets are declared and does not validate that declaration against the agent’s identity. For isolation that survives a lying client, you need separate tenants or the managed service, where tenant scoping is resolved server-side from the credential.
The original finding: coordination is enforced 14 times, and never by a prompt
We read all five agent files in caura-ai/caura-build-fleet (pipeline/agent_frontend.py, agent_performance.py, agent_seo.py, agent_codereview.py, and manager.py, master branch, checked 20 August 2026) and counted the ALLOWED_TOOLS list declared in each.
Caura exposes 12 MCP tools, so a five-agent fleet has 60 possible agent-tool pairs. Fourteen are granted. The Frontend agent, first in the chain with nothing to recall, gets exactly one tool. The Manager gets six, all of them reads, and zero writes. No agent in the fleet holds both the widest read surface and write access.
| Agent | Tools granted | Which ones |
|---|---|---|
| Frontend | 1 | write |
| Performance | 2 | recall, write |
| SEO | 2 | recall, write |
| Code Review | 3 | recall, insights, write |
| Manager | 6 | list, stats, insights, recall, entity_get, keystones |
Then it is enforced a second time, independently. Caura checks trust_level server-side and gates on scope, not just on the tool being called. Reads and writes inside an agent’s own scope are open at any trust level. Fleet-wide reads through stats, list or insights need trust level 2, which is why the Manager has to be promoted once per tenant with a PATCH to the trust endpoint and gets a 403 otherwise. Both layers would have to fail for an unauthorised fleet-wide read to land.
Count the prompt-only enforcement in that architecture and you get zero. That is the transferable lesson, independent of which memory layer you pick.
What still breaks after you have all this?
Every one of these mechanisms has a limit, and a fleet architecture built on the assumption that they have none in view.
The model can still ignore what it retrieved
The caura-build-fleet README says so plainly: running the same repo repeatedly can produce a different verdict, LGTM or BLOCK, across identical runs. Shared memory removes the “the agent never saw the constraint” failure mode. It does not remove model variance. If a constraint absolutely must bind, it belongs in a keystone, where delivery is deterministic, rather than in a memory, where retrieval is probabilistic.
Contradiction detection is asynchronous, so there is a race
Detection runs after the write commits, to keep the write fast. On day nine, if Synthesis recalls before the background pass completes, all nine rows are still live, and the whole mechanism is bypassed. The reference fleet closes the window by polling GET /memories/{id}/contradictions until detection_status returns completed, up to about 60 seconds across twelve attempts. Any fleet with predictable drift events, meaning pricing, config, or regulatory updates, needs that poll before the downstream read.
More agents cost real money
Anthropic’s numbers are the honest benchmark here: agents use roughly 4x the tokens of a chat interaction, and multi-agent systems use about 15x. Token usage alone explained 80% of the performance variance on their browsing eval. A fleet is only worth building when the task value clears that bill.
Shared memory is the main lever against it, because the largest multiplier in a fleet is not reasoning; it is repetition. Caura’s own token analysis attributes most of the cost of a late-session turn to re-sending the full transcript rather than recalling only the memories the task needs, and their benchmark methodology reports token reductions in the 96.6 to 98.2% band against full context, with accuracy holding at 77.6% on LoCoMo and 72.5% on LongMemEval.
Your own figure will depend on how you tune top_k and min_similarity, and a top_k set too high hands the savings straight back.
Some tasks should not be a fleet at all
Anthropic is direct about this too: domains where all agents need the same context, or where dependencies between agents are dense, are a poor fit today. Most coding tasks have fewer genuinely parallel parts than research does. Yan’s position is that a single-threaded linear agent with a good compression step carries you further than the architecture diagrams suggest. That is the right default until parallelism is actually paying for itself.
Worth reading his post for the strongest version of the case against this whole architecture. His conclusion in June 2025 was that “at the moment, I don’t see anyone putting a dedicated effort to solving this difficult cross-agent context-passing problem.” Governed shared memory is a dedicated effort at exactly that problem, and the reference fleets above are how you check whether it holds up on your workload rather than taking anyone’s word for it.
How do you build this without rewriting your fleet?
Five steps, in this order. The order matters: scoping before you have written anything wastes the first week spent designing partitions for knowledge you do not yet have.
- Pick the collision you actually have: Duplicate work, contradiction, stale facts, or leakage. They need different mechanisms and you will not fix all four at once. If you cannot name which one bit you last month, you are not ready for a fleet.
- Wire recall before acting, write after deciding into one agent: One agent, one
caura_recallat the start of its turn, onecaura_writewhen it decides. The quickstart is a config block pasted into any MCP client, so Claude Code, Cursor and Windsurf all work without integration code. - Set scopes on writes before adding the second agent:
scope_agentfor working notes,scope_teamfor decisions that should bind teammates,scope_orgfor anything the whole company acts on. Retrofitting scope onto an unscoped pool is the expensive version of this step. - Restrict tool allowlists per role: Give each agent the smallest set that does its job, the way the reference fleet gives its Frontend agent exactly one tool. Then set trust levels so the boundary survives a bug in your own orchestration code.
- Promote your hard rules to keystones: Anything a compliance officer would want in writing does not belong in semantic memory, where a differently phrased query can miss it.
Step 2 takes a few hours and tells you whether the rest applies to you. If your agents never recall anything another agent wrote, you have a pipeline, and a pipeline is fine.
Start with one recall call
You now have the four ways fleets collide, the point at which each coordination pattern gives out, and the specific mechanisms that turn a written decision into a constraint a later agent cannot route around. You also have three repos where you can watch a constraint propagate rather than trusting a diagram.
Clone caura-build-fleet and run it against a free tenant. It takes an afternoon, and the Prism dashboard shows you the exact moment the SEO agent reads the performance rule and changes its answer. If that moment is the one missing from your own fleet, Caura is the governed shared memory layer built to supply it: scoped at write time, filtered at the query layer, audited on every write, delete, and transition, with 10,000 memories and unlimited agents on the free tier.
Frequently Asked Questions
What is the difference between a multi-agent system and a single agent with lots of tools?
A single agent with many tools maintains a single context window and a single decision trace, so nothing can contradict anything. A multi-agent system splits work across separate contexts, which buys parallelism and separate tool surfaces, and introduces the possibility that two agents make conflicting decisions that neither can see. Split the work when the task genuinely parallelizes and spans multiple context windows; keep one agent when the parts are tightly dependent.
Does A2A or MCP solve multi-agent coordination?
No, and neither claims to. MCP standardizes how an agent calls a tool. A2A standardizes how agents communicate across frameworks and vendors, and deliberately keeps agents opaque to one another. Both are transport. Coordination is about shared state: what the fleet collectively knows and which agent is allowed to know it.
Can I just use a vector database as shared agent memory?
You can, and it will handle persistence and semantic search. It will not retire a fact when it changes, so old and new values return in the same result set, with nothing indicating which is current, and it will not stop an agent from retrieving rows outside its boundary because a plain similarity query has no concept of scope. Those two gaps are what produce stale briefs and leaked records.
How many agents before coordination becomes a real problem?
Two, if they write to anything shared. The failure is not about count; it is about whether one agent’s decision constrains another’s. A fleet of 20 read-only agents that never write has no coordination problem; two agents, where one sets a rule the other can violate, already do.
Is Caura open source, and do I need an account to try the reference fleets?
The core engine is Apache 2.0 at github.com/caura-ai/caura, and runs locally with docker compose up. Cross-fleet governance runs fully local with no API key at all. Build fleet and long-run fleet default to managed Caura, because both use the Prism dashboard and elevated trust for fleet-wide reads, which need a free account.
Related reading: Caura Owns the Multi-Agent Governed Memory Lane · Stopping Constraint Contradictions · How AI Agents Share Knowledge