Multi-Agent Systems

A multi-agent system coordinates several specialized model-driven components so complex work can be decomposed, parallelized, reviewed, and merged.

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:

Goal
-> 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

Multi-agent coordination lab

Project goal

Build an ML-powered weather application.
  • 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

Active team

Planner-worker

CoordinatorResearcherEngineerTesterReviewer
Expected quality
94%
Latency
3.1s
Relative cost
3.7x
Coordination risk
45%

Message trace

Coordinator
Creates subtasks and assigns each one to a specialist.
Researcher + Engineer + Tester
Run in parallel where dependencies allow.
Coordinator
Merges worker notes from the shared task board.
Reviewer
Checks data leakage, unit mismatch, and missing tests.

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.

ai=πi(si)a_i = \pi_i(s_i)

Here, πi\pi_i is the policy for agent ii, sis_i is the state visible to that agent, and aia_i is the action or message it produces.

A simple pipeline composes these policies:

Π=πnπ2π1\Pi = \pi_n \circ \cdots \circ \pi_2 \circ \pi_1

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:

St+1=Update(St,it,ait,ot)S_{t+1} = \operatorname{Update}(S_t, i_t, a_{i_t}, o_t)

The coordinator chooses which agent acts at time tt, 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

RoleResponsibilityWeather app example
PlannerDecomposes the goal into subtasksBreak the weather app into data, model, UI, tests, and docs
ResearcherFinds information and constraintsIdentify useful weather features and data quality risks
EngineerImplements the solutionWrite the training script, API route, and UI
TesterChecks behaviorRun unit tests and verify forecast edge cases
ReviewerCritiques the resultLook for leakage, missing validation, and unsafe assumptions
CoordinatorAssigns work and merges outputsDecide 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.

ArchitectureShapeStrengthRisk
Sequential pipelineA -> B -> CSimple and debuggableSlow if every step waits for the previous one
Planner-workerPlanner -> workers -> plannerGood for decomposable projectsPlanner can become a bottleneck
SupervisorSupervisor delegates, checks, and mergesClear control and permissionsCentral component carries lots of responsibility
DebateAgents argue, judge decidesUseful for critique and alternativesCan produce confident consensus without truth
BlackboardAgents write to shared workspaceGood for asynchronous collaborationShared state can become messy
HierarchyManager -> team leads -> workersScales to larger workflowsHarder 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.

MetricQuestion
Task completionDid the full system satisfy the user goal?
Role adherenceDid each agent do the job it was assigned?
Handoff qualityWere messages complete enough for the next agent?
Contradiction rateDid agents produce incompatible claims?
Reviewer catch rateHow often did critics find real problems?
Latency and costHow many model calls, tokens, tool calls, and seconds were used?
ScalabilityDoes adding more workers improve throughput or only add overhead?

Single Agent Versus Multi-Agent

FeatureSingle agentMulti-agent
SimplicityHighLower
ParallelismLimitedStrong when tasks are independent
Context efficiencyCan overload one context windowCan give each role narrower context
VerificationSelf-critique onlySeparate reviewer or judge roles
CostUsually lowerUsually higher
DebuggingShorter traceLonger trace with more handoffs
ScalabilityModerateHigher 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.