Multi-Agent Systems
A multi-agent system splits a big job between several agents, each with its own role, instructions and tools.
Why Use More Than One Agent?
- Focus: each agent has a short, clear instruction instead of one huge prompt.
- Parallel work: several agents can research different parts at the same time.
- Checking: one agent can review another's work.
- Smaller context: each agent sees only what it needs.
Common Patterns
| Pattern | How it works | Example |
|---|---|---|
| Orchestrator and workers | A main agent splits the task and gives parts to worker agents | Research 5 competitors, one worker each |
| Pipeline | Agents work in order, each passing output to the next | Researcher, then writer, then editor |
| Writer and reviewer | One agent creates, another checks and sends back fixes | Code writer and code reviewer |
| Debate | Two agents argue for different options, a judge decides | Choosing between two business plans |
A Simple Pipeline
Here each "agent" is a Python function standing in for a model call with its own role. The output of one is the input of the next:
Example
def researcher(topic):
return [f"{topic} saves time", f"{topic} needs good prompts", f"{topic} can make mistakes"]
def writer(points):
return "AI tools help freelancers. " + " ".join(p.capitalize() + "." for p in points)
def editor(text):
return text.replace("AI tools help freelancers.", "AI tools help Pakistani freelancers.")
draft = editor(writer(researcher("using AI")))
print(draft)AI tools help Pakistani freelancers. Using AI saves time. Using AI needs good prompts. Using AI can make mistakes.
In a real system, each function would call a model with a role prompt such as "You are an editor. Improve clarity and fix grammar. Do not add new facts."
Orchestrator and Workers
The orchestrator plans, hands out sub-tasks and combines the results:
Example
def worker(shop):
prices = {"Shop A": 3200, "Shop B": 2950, "Shop C": 3100}
return {"shop": shop, "price": prices[shop]}
def orchestrator(task, shops):
print("Task:", task)
results = [worker(s) for s in shops] # could run in parallel
best = min(results, key=lambda r: r["price"])
return f"Cheapest is {best['shop']} at Rs {best['price']}"
print(orchestrator("Find the cheapest school bag", ["Shop A", "Shop B", "Shop C"]))Task: Find the cheapest school bag Cheapest is Shop B at Rs 2950
Writer and Reviewer
This pattern is popular because a fresh "pair of eyes" catches mistakes:
Example
Writer agent: "Write a Python function to calculate GST at 18%."
Reviewer agent: "Check the code for bugs and edge cases. Reply APPROVED
or list the problems."
Loop: repeat until APPROVED or 3 rounds have passed.When One Agent is Better
Multi-agent systems are not always better:
- More agents means more AI calls, so more cost and time.
- Agents can misunderstand each other, and errors pass down the chain.
- They are harder to debug: which agent made the mistake?
A good rule: start with one agent with good tools. Split into several agents only when the single agent clearly struggles, for example because the task is too large for one context window or needs truly separate skills.
When agents pass work to each other, make each hand-off a clear, structured message (for example a short JSON object), not a long chat transcript.
Exercise
Exercise
In the orchestrator and workers pattern, what does the orchestrator do?
