Don't Build Multi-Agents
Source: Walden Yan (Cognition); Cognition blog post · 2025-06-12
In some cases, libraries such as https://github.com/openai/swarm by OpenAI and https://github.com/microsoft/autogen by Microsoft actively push concepts which I believe to be the wrong way of building agents. Namely, using multi-agent architectures, and I’ll explain why.
Let’s start with reliability. When agents have to actually be reliable while running for long periods of time and maintain coherent conversations, there are certain things you must do to contain the potential for compounding errors. Otherwise, if you’re not careful, things fall apart quickly. At the core of reliability is Context Engineering.
In 2025, the models out there are extremely intelligent. But even the smartest human won’t be able to do their job effectively without the context of what they’re being asked to do. “Prompt engineering” was coined as a term for the effort needing to write your task in the ideal format for a LLM chatbot. “Context engineering” is the next level of this. It is about doing this automatically in a dynamic system. It takes more nuance and is effectively the #1 job of engineers building AI agents.
Take an example of a common type of agent.
This is a tempting architecture, especially if you work in a domain of tasks with several parallel components to it. However, it is very fragile. The key failure point is this:
Suppose your Task is “build a Flappy Bird clone”. This gets divided into Subtask 1 “build a moving game background with green pipes and hit boxes” and Subtask 2 “build a bird that you can move up and down”.It turns out subagent 1 actually mistook your subtask and started building a background that looks like Super Mario Bros. Subagent 2 built you a bird, but it doesn’t look like a game asset and it moves nothing like the one in Flappy Bird. Now the final agent is left with the undesirable task of combining these two miscommunications.
This may seem contrived, but most real-world tasks have many layers of nuance that all have the potential to be miscommunicated. You might think that a simple solution would be to just copy over the original task as context to the subagents as well. That way, they don’t misunderstand their subtask. But remember that in a real production system, the conversation is most likely multi-turn, the agent probably had to make some tool calls to decide how to break down the task, and any number of details could have consequences on the interpretation of the task.
Principle 1. Share context, and share full agent traces, not just individual messages.
Let’s take another revision at our agent, this time making sure each agent has the context of the previous agents.
Unfortunately, we aren’t quite out of the woods. When you give your agent the same Flappy Bird cloning task, this time, you might end up with a bird and background with completely different visual styles. Subagent 1 and subagent 2 cannot not see what the other was doing and so their work ends up being inconsistent with each other.
The actions subagent 1 took and the actions subagent 2 took were based on conflicting assumptions not prescribed upfront.
Principle 2. Actions carry implicit decisions, and conflicting decisions carry bad results.
I would argue that Principles 1 & 2 are so critical, and so rarely worth violating, that you should by default rule out any agent architectures that don’t abide by them. You might think this is constraining, but there is actually a wide space of different architectures you could still explore for your agent.
The simplest way to follow the principles is to just use a single-threaded linear agent:
Here, the context is continuous. However, you might run into issues for very large tasks with so many subparts that context windows start to overflow.
In this world, we introduce a new LLM model whose key purpose is to compress a history of actions & conversation into key details, events, and decisions. This is hard to get right. It takes investment into figuring out what ends up being the key information and creating a system that is good at this. Depending on the domain, you might even consider fine-tuning a smaller model (this is in fact something we’ve done at Cognition).
The benefit you get is an agent that is effective at longer contexts. You will still eventually hit a limit though. For the avid reader, I encourage you to think of better ways to manage arbitrarily long contexts. It ends up being quite a deep rabbit hole!
If you’re an agent-builder, ensure your agent’s every action is informed by the context of all relevant decisions made by other parts of the system. Ideally, every action would just see everything else. Unfortunately, this is not always possible due to limited context windows and practical tradeoffs, and you may need to decide what level of complexity you are willing to take on for the level of reliability you aim for.
As you think about architecting your agents to avoid conflicting decision-making, here are some real-world examples to ponder:Claude Code SubagentsAs of June 2025, Claude Code is an example of an agent that spawns subtasks. However, it never does work in parallel with the subtask agent, and the subtask agent is usually only tasked with answering a question, not writing any code. Why? The subtask agent lacks context from the main agent that would otherwise be needed to do anything beyond answering a well-defined question. And if they were to run multiple parallel subagents, they might give conflicting responses, resulting in the reliability issues we saw with our earlier examples of agents. The benefit of having a subagent in this case is that all the subagent’s investigative work does not need to remain in the history of the main agent, allowing for longer traces before running out of context. The designers of Claude Code took a purposefully simple approach.Edit Apply ModelsIn 2024, many models were really bad at editing code. A common practice among coding agents, IDEs, app builders, etc. (including Devin) was to use an “edit apply model.”
Lines of inquiry this paper opens 10
Research framings built by reading the notes related to this paper — the questions it feeds into.
Why do autonomous agents fail and how well can they detect failures?- Why do agents stall on long-horizon workplace tasks specifically?
- Can environment mismatches cause failures even when individual agents work correctly?
- Why should system topology be chosen explicitly rather than implied by roles?
- How do organizational rules prevent conflicts across multiple agent roles?
- How do organizational rules and structures differ from agent roles in design?
- Should parallel agents be specialized with graph abstractions instead of general subagents?
- What gaps exist between MOISE+ formal design and actual agent behavior?
- Can organizational design choices be transferred between different model bindings?