The iceberg of AI usage · Part 3 of 6
Theory of building multi-agent systems
July 5, 2026 · 6 min read
- ai
- claude-code
- multi-agent
Are you tired of writing prompts and explaining to the LLM what needs to be done every single time? Do you have complex tasks that consist of a multitude of subtasks? Do you want to extract the maximum quality out of an LLM's work? Great, this section and the whole rest of the article is for you!
For those who don't like theory — welcome to the next article, Building an agentic HR department.
What is it and what is it for?
A multi-agent system is a way of solving a composite task through decomposition into subtasks, each of which is delegated to a separate agent, with their work subsequently coordinated into a single result.
To put it more simply — it's when, instead of one agent that tries to implement everything, you decompose the task and hand the pieces out to several smaller specialized agents.
A fair question at this point: "Why decompose at all? Just write a prompt and be done with it..." — to which I'll answer with a single word: Context.
Every LLM has a context window. It's everything the model holds in a session (the prompt, the dialogue history, files it has read, tool descriptions, MCP server responses). The more stuff gets mixed into the window, the worse the model performs.
In effect, everything comes down to building abstractions over context so you can manipulate it competently.
The transition from one agent to a system
When you work with Claude Code, by default you're talking to a single agent — the main session. It reads files, calls tools, and answers you directly.
The transition happens when the main session stops doing everything itself and delegates part of the work to a subagent — a separate agent with its own context that gets handed a specific subtask. The subagent performs its subtask and returns the result to the main session.
We can explicitly identify four reasons for delegating work to a subagent:
- Context — walking through 50 files or processing long output is worth moving into a separate agent. It does the work in its own window and returns a compact digest.
- Specialization — a narrowly focused agent with a precise prompt and a small set of the right tools works better than a universal one, having less room for error. Remember the mistakes from the Common Claude Code setup mistakes article, the "Abstract agent roles" and "The agent can do everything" sections.
- Parallelism — independent subtasks can be executed simultaneously rather than sequentially.
- Isolation — one agent's failure doesn't interfere with the others' work.
If you're creating an agent and it doesn't cover any of these four reasons — you're probably complicating the system without necessity.
How to decompose a task
You can decompose in three ways, which are usually combined:
- By stages — when the steps go strictly in sequence (first gather the data, then analyze, then write it up).
- By independent subtasks — when the constituent parts of the task don't depend on each other and can run in parallel (check ten sources, process ten files).
- By roles — when different specializations are required (one agent writes, another checks).
Insufficient decomposition brings us back to the problem of an overloaded context. The optimal size is tuned to the specific task. There's no ready-made formula, and I won't invent one.
I recommend reading the documentation on subagent context.
Coordination patterns
There's no need to invent coordination methods from scratch. Anthropic has an article that breaks down the basic patterns. In short:
Prompt chaining — splitting a task into a sequence of steps, where each LLM call processes the result of the previous one. At any intermediate step you can add programmatic checks to make sure the process hasn't drifted from the original course.

Routing — classifying input data and directing it into a specialized follow-up task. This process lets you separate responsibilities and build more specialized prompts.

Parallelization — LLMs can sometimes work on a task simultaneously, with their results then combined programmatically.

Orchestrator-workers — a central LLM dynamically breaks tasks apart, delegates them to workers, and synthesizes their results.

Evaluator-optimizer — one LLM call generates a response while another provides evaluation and feedback in a loop.

Contracts, memory, verification
Let's look at three things agent interactions are built on:
- Contracts — agents pass results onward somehow (through shared storage or through an orchestrator that collects them). But more important than the mechanism itself is defining an explicit structure: what the agent receives as input and what it is obliged to return as output. Without it, the first agent returns a result in an arbitrary shape, and the second one can't parse it. The stricter the contract, the less unpredictable behavior.
- Memory — divided into short and long. Short memory lives within a single session (the context window). Long memory is external storage (files, a database) and calmly survives across sessions. We can guess in advance that long memory gives us more (of problems, in particular). We'll talk about memory in more detail in the Agent memory & lessons article, the "Agent memory" section.
- Verification — you can't take an agent at its word, because it can confidently return a plausible-looking error. Often we should use the Evaluator-optimizer pattern for verification or programmatically constrain agents with hooks. See the Orchestrating agents article, the "I don't trust LLMs" section.
Tradeoffs
Sounds cool, right? There's actually one big problem — tokens. Among the genius builders of solo unicorns it's customary to keep quiet about this, but as the system grows more complex and the tooling expands, you will pay more. Is that a problem for me? No. I'm willing to spend more tokens for the sake of quality.
Anthropic, in the article about their research system, shared that their agent setup consumed roughly 15 times more tokens than a regular chat. The quality is higher, but so is the cost. I recommend reading the article, by the way.
There's one more problem — debugging. In a system of five agents it's harder to track failures, and you have to additionally fuss over analytics.
The study "Why Do Multi-Agent LLM Systems Fail?" examines hundreds of runs across different frameworks and identifies 14 typical failure modes (an agent ignores its role, steps get stuck in a loop, an agent fails to recognize a stop condition, dialogue history gets lost).
The takeaway: add complexity exactly as much as the task requires, and no more! Cleanness of decomposition and strictness of contracts will give you more than the number of agents.