The Big Question
The previous lesson built a single agent: an LLM inside a loop, with tools, memory, observations, and stopping conditions. That agent can plan a trip, search the web, call APIs, and revise its next step.
Now imagine a larger task: build an ML-powered weather application. The system needs to inspect data, choose features, write code, test edge cases, document the design, and review whether the forecast is trustworthy.
Should one agent do all of that, or should the work be divided across specialists?
That is the motivation for multi-agent systems. They are not a new kind of language model. They are software architectures that coordinate multiple LLM-driven workers.
Core Intuition
A single agent is like one capable generalist. A multi-agent system is like a small product team. One role plans, another researches, another implements, another tests, and another reviews.
The point is not that five agents magically become five times smarter. The point is that complex work often benefits from decomposition:
-> Planner
-> Researcher + Engineer + Tester
-> Reviewer
-> Coordinator
-> Final answer
Each agent receives a narrower context and a clearer objective. The researcher does not need to write the UI. The tester does not need to design the whole product. The reviewer can focus on catching mistakes rather than producing the first draft.
Interactive Demo
Project goal
- Predict tomorrow temperature from historical weather data.
- Expose a small web interface.
- Include tests and a short README.
- Flag any missing data or unreliable forecast.
Architecture
Planner-worker
Message trace
Shared memory
- Goal and constraints
- Task decomposition
- Worker outputs
- Open questions
- Reviewer findings
Compare a single agent with several coordination patterns. Notice the central trade-off: specialization, parallelism, and review can improve quality, but every extra agent adds messages, latency, cost, and failure surfaces.
A Simple Mathematical View
In a single-agent loop, one policy maps the current state to the next action. In a multi-agent system, each agent has its own role, context, tools, and policy.
Here, is the policy for agent , is the state visible to that agent, and is the action or message it produces.
A simple pipeline composes these policies:
Intuitively, the output of one agent becomes part of the input to the next. A researcher produces notes, an engineer turns notes into code, a tester turns code into failures or approvals, and a reviewer turns the whole trace into a final judgment.
More flexible systems maintain shared state:
The coordinator chooses which agent acts at time , records the action and observation, and updates the shared workspace. That workspace may be a task board, scratchpad, vector database, document store, or structured log.
Why Use Multiple Agents?
Specialization
A narrow role is easier to specify than a giant instruction. The researcher finds evidence. The engineer implements. The reviewer searches for mistakes. This often produces cleaner behavior than asking one prompt to do everything.
Context reduction
A single agent can drown in context. With specialists, each agent sees the subset it needs. The tester can receive the requirements and code, while the documentation writer receives the final design and limitations.
Parallelism
Some work is independent. A research agent can inspect data sources while a UI agent drafts the interface and a testing agent prepares test cases. Parallelism can reduce wall-clock latency even if total token cost rises.
Verification
Production and critique are different jobs. A reviewer agent can ask: did the model leak future data, ignore missing values, invent a metric, or skip a test? Separating creation from review is one of the strongest reasons to use multiple agents.
Roles In A Multi-Agent System
| Role | Responsibility | Weather app example |
|---|---|---|
| Planner | Decomposes the goal into subtasks | Break the weather app into data, model, UI, tests, and docs |
| Researcher | Finds information and constraints | Identify useful weather features and data quality risks |
| Engineer | Implements the solution | Write the training script, API route, and UI |
| Tester | Checks behavior | Run unit tests and verify forecast edge cases |
| Reviewer | Critiques the result | Look for leakage, missing validation, and unsafe assumptions |
| Coordinator | Assigns work and merges outputs | Decide who acts next and produce the final report |
Common Architectures
Multi-agent design is mostly control-flow design. You are deciding who acts, what context they receive, how they communicate, and who has authority to merge or reject results.
| Architecture | Shape | Strength | Risk |
|---|---|---|---|
| Sequential pipeline | A -> B -> C | Simple and debuggable | Slow if every step waits for the previous one |
| Planner-worker | Planner -> workers -> planner | Good for decomposable projects | Planner can become a bottleneck |
| Supervisor | Supervisor delegates, checks, and merges | Clear control and permissions | Central component carries lots of responsibility |
| Debate | Agents argue, judge decides | Useful for critique and alternatives | Can produce confident consensus without truth |
| Blackboard | Agents write to shared workspace | Good for asynchronous collaboration | Shared state can become messy |
| Hierarchy | Manager -> team leads -> workers | Scales to larger workflows | Harder to trace and evaluate |
Communication And Memory
Agents communicate by passing messages. Those messages may be natural language, JSON, tool outputs, test results, retrieved documents, or structured handoff packets.
A useful handoff is specific:
{
"task": "Write tests for the weather prediction endpoint",
"context": "The endpoint accepts city and date, then returns a temperature forecast",
"constraints": ["test missing city", "test malformed date", "test confidence warning"],
"expected_output": "A test file plus a short list of uncovered risks"
}Shared memory is the workspace that keeps agents aligned. It can store the original goal, constraints, intermediate findings, tool outputs, decisions, and open questions. Without shared memory, agents can drift into separate realities.
Task Decomposition
The hardest part of multi-agent design is usually not creating agents. It is dividing the task correctly. Good decomposition gives each worker a clear boundary.
Good decomposition
Each subtask has a clear owner, input, output, and success criterion
Bad decomposition
Several agents do overlapping work or depend on missing context
Good handoff
Here is the task, constraints, evidence, output format, and open questions
Bad handoff
Continue from here
For the weather app, a good decomposition might be: data audit, feature plan, model implementation, interface implementation, test suite, documentation, and review. A bad decomposition would ask three agents to independently build the entire app and then hope their outputs merge cleanly.
Implementation From Scratch
A minimal multi-agent framework does not require a special library. You need agent objects, messages, a coordinator, and a shared state object.
from dataclasses import dataclass, field
@dataclass
class Message:
sender: str
recipient: str
content: str
@dataclass
class Agent:
name: str
role: str
tools: list[str] = field(default_factory=list)
def run(self, task: str, memory: dict) -> Message:
# In a real system this would call an LLM with:
# role + task + relevant memory + available tools.
return Message(
sender=self.name,
recipient="coordinator",
content=f"{self.name} completed: {task}"
)
class Coordinator:
def __init__(self, agents: list[Agent]):
self.agents = {agent.name: agent for agent in agents}
self.memory = {"notes": [], "risks": []}
def assign(self, agent_name: str, task: str) -> Message:
agent = self.agents[agent_name]
message = agent.run(task, self.memory)
self.memory["notes"].append(message.content)
return message
agents = [
Agent("planner", "decompose the project"),
Agent("researcher", "inspect data and constraints"),
Agent("engineer", "implement the app", tools=["code_runner"]),
Agent("tester", "write and run tests", tools=["test_runner"]),
Agent("reviewer", "find mistakes and risks"),
]
coordinator = Coordinator(agents)
coordinator.assign("planner", "split the weather app into concrete tasks")
coordinator.assign("researcher", "find data quality risks")
coordinator.assign("engineer", "implement the prediction endpoint")
coordinator.assign("tester", "test the endpoint")
coordinator.assign("reviewer", "review the full plan and code")This toy version uses mocked outputs, but the structure is real. In production, each run method would call a model, pass relevant memory, expose only approved tools, validate the returned message, and append the result to an audit log.
Independent workers can also run in parallel:
import asyncio
async def run_worker(agent, task, memory):
return await call_llm(agent.role, task, memory)
results = await asyncio.gather(
run_worker(researcher, "audit the dataset", memory),
run_worker(ui_designer, "draft the interface", memory),
run_worker(tester, "write edge-case tests", memory),
)
memory["worker_results"] = results
final = await call_llm(
coordinator.role,
"merge worker results and produce the final plan",
memory,
)When Agents Disagree
Disagreement is normal. One agent may recommend a linear regression baseline, while another recommends gradient boosting. One may say the dataset is clean, while another finds missing station readings.
Common resolution strategies include voting, confidence weighting, a judge model, deterministic tests, external tools, and human review. The safest systems do not treat consensus as truth. They ask what evidence supports each claim.
Security And Permissions
Multi-agent systems increase the attack surface. A researcher that reads untrusted web pages can pass malicious instructions to an engineer. A coding agent with shell access can make changes a reviewer never approved. A supervisor can accidentally grant broad permissions to the wrong role.
Use least privilege. The documentation writer does not need deployment credentials. The researcher does not need write access to production data. High-impact actions should require human approval, and every tool call should be logged.
How To Evaluate A Multi-Agent System
Compare against a single-agent baseline. If the multi-agent version costs three times more and takes twice as long, it should produce a measurable improvement.
| Metric | Question |
|---|---|
| Task completion | Did the full system satisfy the user goal? |
| Role adherence | Did each agent do the job it was assigned? |
| Handoff quality | Were messages complete enough for the next agent? |
| Contradiction rate | Did agents produce incompatible claims? |
| Reviewer catch rate | How often did critics find real problems? |
| Latency and cost | How many model calls, tokens, tool calls, and seconds were used? |
| Scalability | Does adding more workers improve throughput or only add overhead? |
Single Agent Versus Multi-Agent
| Feature | Single agent | Multi-agent |
|---|---|---|
| Simplicity | High | Lower |
| Parallelism | Limited | Strong when tasks are independent |
| Context efficiency | Can overload one context window | Can give each role narrower context |
| Verification | Self-critique only | Separate reviewer or judge roles |
| Cost | Usually lower | Usually higher |
| Debugging | Shorter trace | Longer trace with more handoffs |
| Scalability | Moderate | Higher if coordination is disciplined |
Interview Discussion
What is a multi-agent system?
A software system that coordinates multiple agentic components, usually with different roles, contexts, tools, and responsibilities.
Why might multiple agents outperform one agent?
They can specialize, reduce context overload, run independent work in parallel, and separate production from review.
Why might multiple agents perform worse?
They add communication overhead, cost, latency, conflicting outputs, more complex debugging, and more security surfaces.
Does debate guarantee correctness?
No. A debate can improve critique, but agreement between agents is not evidence by itself. Use tools, tests, retrieved evidence, and human review for high-stakes work.
What is the most important design choice?
Task decomposition. Poor decomposition creates duplicated work, missing context, and brittle handoffs.
Active Recall
1. Why is a multi-agent system not automatically smarter than a single agent?
2. What are the main benefits of specialization?
3. How does shared memory help agents stay aligned?
4. What is the difference between a sequential pipeline and a planner-worker system?
5. Why can parallel workers reduce latency but increase cost?
6. What should a good handoff message contain?
7. Why should reviewers have a separate role from producers?
8. What metrics would you use to compare a multi-agent system against a single-agent baseline?
Failure Modes
- Too many agents: The system spends more effort coordinating than solving.
- Communication loops: Agents keep asking one another for clarification without progress.
- Context divergence: Different agents work from different assumptions.
- Duplicate work: Several workers solve the same subtask independently.
- Supervisor bottleneck: All decisions wait on one overloaded coordinator.
- Conflicting outputs: The final answer merges incompatible claims.
- Hallucinated instructions: One agent invents constraints and passes them downstream.
- Higher cost: More model calls and longer traces increase spend.
Connection To LLM Application Evaluation
The LLM Applications unit has now moved from prompting, to retrieval, to tools, to single agents, to coordinated teams of agents.
The next question is unavoidable: how do we know any of this actually works? That motivates evaluation, where we measure correctness, robustness, latency, cost, and user experience instead of relying on impressive demos.