Module 1: Why Multi-Agent (and When Not To)
The cost of coordination
Description
Lesson 02 defined what a multi-agent system is: several agents, each with its own decision, coordinated by a mechanism that splits the work and gathers the results. This lesson answers the question that definition leaves open: how much does that mechanism cost? Not in the abstract — in numbers you can calculate before writing a single line of orchestration.
Every additional agent a system consults adds, at minimum, three measurable costs: one model call to decide who to delegate to, that specialist's internal calls to solve its part, and the messages ("hops") that travel back and forth between the coordinator and the specialist. You'll run a formula that grows with the number of specialists consulted, and a second, simpler model that shows how every additional step is also one more opportunity for something to go wrong. Neither example runs the full runner yet — that's lesson 05, with the real comparison of two systems — here you build the vocabulary and the numeric intuition that lesson 05 will apply to a concrete case.
Connection to the module
Lesson 01 said it in prose: "more agents = more calls, more steps, more error surface." This
lesson turns it into executable code. Lesson 04 uses this same vocabulary — model calls, hops —
to compare the cost of an agent with many tools against splitting those tools across several
agents. Lesson 05 applies this lesson's formula to a real case, with agent-fundamentals's
runner actually running.
Analogy: every new person in the chain is a chance for miscommunication
Pick back up the team-of-people analogy from lesson 01. If you solve a task alone, there's exactly one place where something can go wrong: your own work. If you ask someone else to solve a piece and hand it back to you, you've added two new places: the moment you explain the task to them (did they understand it correctly?) and the moment they hand the result back to you (did they communicate it correctly?). Neither of those is "work" in the sense of advancing the task — they're coordination overhead, and every new person in the chain multiplies them.
That's exactly what a multi-agent system pays for: every specialist a supervisor consults adds a "who do I send this to" decision and one message out and one back — before the specialist even starts working on the part only it can solve.
Worked example: cost grows with the number of specialists
We model two paths for solving a task that needs the work of n_specialists specialists: a
single agent that does all the work itself (with no coordination messages at all), and a
supervisor that delegates to n_specialists distinct agents. The number of internal calls it
takes a specialist to solve its part — 3, on average, for a typical Reservo task with one quote
and one action — is the same real number you'll see executed in lesson 05.
def single_agent_cost(n_specialists, calls_per_specialist=3):
"""A single agent solves the work of the N areas itself -- no
routing, no synthesis, no messages between agents."""
return {"model_calls": calls_per_specialist * n_specialists, "hops": 0}
def supervised_cost(n_specialists, calls_per_specialist=3):
"""A supervisor delegates to N specialists: 1 routing call, each
specialist's internal calls, 1 synthesis call, and 2 hops
(out and back) per specialist consulted."""
route_calls = 1
compose_calls = 1
return {
"model_calls": route_calls + calls_per_specialist * n_specialists + compose_calls,
"hops": 2 * n_specialists,
}
print(f"{'specialists':>14} | {'1 agent (calls/hops)':>24} | "
f"{'supervisor+N (calls/hops)':>26} | {'extra calls':>16}")
for n in (1, 2, 3):
single = single_agent_cost(n)
multi = supervised_cost(n)
extra = multi["model_calls"] - single["model_calls"]
print(f"{n:>14} | {single['model_calls']:>10} / {single['hops']:<10} | "
f"{multi['model_calls']:>12} / {multi['hops']:<10} | {extra:>16}")
What to expect:
specialists | 1 agent (calls/hops) | supervisor+N (calls/hops) | extra calls
1 | 3 / 0 | 5 / 2 | 2
2 | 6 / 0 | 8 / 4 | 2
3 | 9 / 0 | 11 / 6 | 2
Read the table carefully, because it holds two different stories. The extra calls column
stays constant at 2, no matter how many specialists you consult — it's the supervisor's own
fixed cost (one routing call, one synthesis call), and it doesn't grow with n because in this
model the supervisor decides once who gets all the work, not once per specialist. The hops
column, on the other hand, does grow: 2 * n, because every new specialist adds its own round
trip. With a single specialist (n=1), the supervisor system uses exactly 5 calls and 2
hops against a single agent's 3 calls and 0 hops — the exact number you'll confirm, run
end to end with the real runner, in lesson 05.
The second cost: more steps, more error surface
Counting calls and hops measures the cost in work. There's a second, different cost that matters just as much: every model call and every tool call is a step where something can fail — a malformed argument, a timeout, a wrong routing decision. If we model each step with a fixed probability of failing (a number invented for illustration, not a real measurement of any system), the probability that the whole path finishes with no failure at all drops with every additional step — not linearly, but multiplicatively.
def end_to_end_success(steps, failure_rate_per_step=0.02):
"""Simple, illustrative model: if each step has a fixed probability
of failing, the probability that ALL steps go well is the product
of each one, separately, going well."""
return (1 - failure_rate_per_step) ** steps
steps_single = 3 # lesson 05's single agent: 3 calls
steps_multi = 5 # lesson 05's 2-agent system: 5 calls
success_single = end_to_end_success(steps_single)
success_multi = end_to_end_success(steps_multi)
print(f"System A (1 agent, {steps_single} steps): "
f"{success_single:.4f} ({success_single * 100:.2f}% end-to-end success)")
print(f"System B (2 agents, {steps_multi} steps): "
f"{success_multi:.4f} ({success_multi * 100:.2f}% end-to-end success)")
print(f"difference: {(success_single - success_multi) * 100:.2f} percentage points "
f"less reliable in System B, with the same 2% risk per step")
What to expect:
System A (1 agent, 3 steps): 0.9412 (94.12% end-to-end success)
System B (2 agents, 5 steps): 0.9039 (90.39% end-to-end success)
difference: 3.73 percentage points less reliable in System B, with the same 2% risk per step
The point isn't that 0.02 is the real probability of a call failing in production — that
figure depends on the system, the provider, and a thousand factors this guide doesn't measure.
The point is structural: with the same failure rate per step, a 5-step path is
arithmetically less reliable than a 3-step one, because success probability multiplies, it
doesn't subtract. Every extra call coordination adds isn't just time and cost — it's one more
chance for the whole system to fail, even if every individual step is exactly as reliable as any
other.
Why this lesson doesn't run the full runner yet
It might seem odd that this lesson, so focused on "the cost of coordinating," doesn't run
run_agent_parallel or build any real AgentMessage. That's deliberate: the formulas above
(single_agent_cost, supervised_cost, end_to_end_success) are models — they capture the
shape in which cost grows, for any task with that structure, without tying themselves to a
specific Reservo task. Lesson 05 takes exactly the n=1 case from the table above — a system
with a single specialist consulted — and makes it concrete: a real Reservo task, a real runner, a
real script, and the same numbers (3 vs. 5, 0 vs. 2 hops) confirmed with the complete history
printed on screen, not with a formula.
Common mistakes
-
Confusing "extra calls" (fixed) with "hops" (grows with N). In this lesson's model, adding a third specialist doesn't add a third routing or synthesis call — the supervisor still decides only once — but it does add 2 more hops. Treating both costs as if they grow the same way leads to underestimating one or overestimating the other.
-
Taking the reliability model's
0.02as a real production number. It's an illustrative value chosen to keep the example readable, not a measurement of any system — the point to take away is the multiplicative shape of the drop, not the exact figure. -
Thinking the cost of coordinating always justifies avoiding multi-agent. This lesson measures the cost; it doesn't say the cost is never worth paying. Lesson 06 shows real cases where it is, despite the cost measured here.
-
Assuming
calls_per_specialist=3is a universal constant. It's this guide's number, for the concrete task you'll see in lesson 05 (quoting and booking). A task with more internal steps — or with retries for errors, a topic fromagent-fundamentalsM7 — would have a higher number, and the gap between the two paths would grow in the same proportion. -
Forgetting
single_agent_costisn't free either. A single agent doingn_specialiststimes more internal work also has a cost that grows withn— it just grows without the extra cost of routing, synthesis, and hops. The comparison is always relative, never "multi-agent costs something, one agent costs nothing."
Exercises
Exercise 1: Read the formula without running it (Easy)
Without running any code: (a) if n_specialists=4, how many model calls does supervised_cost
use with calls_per_specialist=3? (b) how many hops? (c) how many extra calls does it have over
single_agent_cost for the same n?
See solution
(a) route_calls + calls_per_specialist * n_specialists + compose_calls = 1 + 3*4 + 1 =
14 calls.
(b) 2 * n_specialists = 2 * 4 = 8 hops.
(c) single_agent_cost(4) = 3 * 4 = 12 calls. The difference is 14 - 12 = 2 extra
calls — the same fixed cost as always (1 routing + 1 synthesis), no matter that n went up
from 1 to 4. This is exactly the pattern the worked example's table shows: extra calls stay at 2
across every row.
Exercise 2: Extend the table and graph the growth of hops (Medium)
Run supervised_cost and single_agent_cost for n_specialists from 1 to 6, and print, in
addition to the worked example's columns, the supervised system's hops / model_calls ratio for
each row (rounded to 2 decimals). Does the ratio grow, shrink, or stay stable as n increases?
See solution
def single_agent_cost(n_specialists, calls_per_specialist=3):
return {"model_calls": calls_per_specialist * n_specialists, "hops": 0}
def supervised_cost(n_specialists, calls_per_specialist=3):
route_calls = 1
compose_calls = 1
return {
"model_calls": route_calls + calls_per_specialist * n_specialists + compose_calls,
"hops": 2 * n_specialists,
}
print(f"{'n':>3} | {'calls':>6} | {'hops':>5} | {'hops/calls':>11}")
for n in range(1, 7):
multi = supervised_cost(n)
ratio = multi["hops"] / multi["model_calls"]
print(f"{n:>3} | {multi['model_calls']:>6} | {multi['hops']:>5} | {ratio:>11.2f}")
Expected output:
n | calls | hops | hops/calls
1 | 5 | 2 | 0.40
2 | 8 | 4 | 0.50
3 | 11 | 6 | 0.55
4 | 14 | 8 | 0.57
5 | 17 | 10 | 0.59
6 | 20 | 12 | 0.60
Explanation: the ratio grows, though more and more slowly (0.40 → 0.50 → 0.55 → 0.57 →
0.59 → 0.60, approaching a ceiling). It makes algebraic sense: hops grow as 2n (pure, no fixed
cost) while calls grow as 3n + 2 (with the fixed routing-and-synthesis cost added once); as n
grows, the fixed cost weighs less and less on the total, and the hops proportion approaches
2/3 ≈ 0.67 — the limit the ratio would have if the fixed cost didn't exist. In systems with
many specialists, almost all the coordination cost ends up being hops, not the supervisor's two
fixed calls.
Exercise 3: Design a cost model for the pipeline pattern (Hard)
Modules 2 and 3 of this guide distinguish the supervisor pattern (a coordinator decides who
to delegate to) from the pipeline pattern (a fixed sequence of agents, each feeding the next,
with no routing decision at each step). Write a function pipeline_cost(n_stages, calls_per_stage=3) that models the cost of a pipeline of n_stages agents in sequence, where
there's no routing call per stage (the order is already fixed in advance) but there is 1
hop between each consecutive stage (one stage's result passes to the next). Compare its result
with supervised_cost for n=3 and explain, in one sentence, why the pipeline should cost fewer
hops than the supervisor for the same number of stages.
See solution
def pipeline_cost(n_stages, calls_per_stage=3):
"""A pipeline has NO routing call per stage -- the order is already
fixed -- but it does have one hop between each consecutive stage
(n_stages - 1 hops for n_stages chained stages)."""
return {
"model_calls": calls_per_stage * n_stages,
"hops": max(0, n_stages - 1),
}
def supervised_cost(n_specialists, calls_per_specialist=3):
route_calls = 1
compose_calls = 1
return {
"model_calls": route_calls + calls_per_specialist * n_specialists + compose_calls,
"hops": 2 * n_specialists,
}
pipe = pipeline_cost(3)
sup = supervised_cost(3)
print(f"pipeline (3 stages): {pipe['model_calls']} calls, {pipe['hops']} hops")
print(f"supervisor (3 agents): {sup['model_calls']} calls, {sup['hops']} hops")
Expected output:
pipeline (3 stages): 9 calls, 2 hops
supervisor (3 agents): 11 calls, 6 hops
Explanation: the pipeline uses fewer calls (9 vs. 11, because it doesn't pay the
supervisor's routing or synthesis call) and far fewer hops (2 vs. 6). The underlying reason:
in a pipeline, each stage only needs to pass its result to the next one — one hop per join
between consecutive stages, n_stages - 1 in total — while in a supervisor each specialist has
to go out and back to the central coordinator — 2 hops per specialist, no matter how many
specialists there are in total. This is exactly the cost advantage Module 3 of this guide will
exploit when a task always needs the same steps, in the same order: a pipeline is cheaper to
coordinate than a supervisor, at the cost of losing the flexibility to decide the path at each
step.
Summary and next step
- Every specialist a multi-agent system consults adds, at minimum, internal model calls (to solve its part) and hops (to receive the task and hand back the result) — a cost a single agent, solving everything itself, doesn't pay.
- We ran
single_agent_costandsupervised_cost: for a single specialist consulted, the supervisor pattern uses 2 extra calls (5 vs. 3) and 2 hops (vs. 0) against a single agent — the exact concrete case lesson 05 will confirm with the real runner. - A second, distinct, and equally measurable cost: with the same failure rate per step, a path
with more steps is arithmetically less reliable (
0.98**3 = 94.12%vs.0.98**5 = 90.39%in our illustrative model) — more error surface, not just more time. - Neither cost says "never use multi-agent" — it says "know the price before you pay it." Lesson 06 shows when the price is worth it.
Next lesson: 04 — One agent with many tools vs. many agents. With the cost vocabulary now built, we apply it to the other side of the decision: is it better to grow a single agent's tool registry, or to split those tools across several specialists?
Additional resources
- Anthropic — Building effective agents — Why adding steps and agents has a cost in latency and reliability that must be justified against the benefit, not assumed free.
- Anthropic — Multi-agent research system — The real coordination cost Anthropic reports in a production multi-agent system (more tokens, more calls) versus a single agent.
- Python — Functions and
**for exponentiation — The operator used inend_to_end_successfor the compound reliability model. - Python 3.14 — What's New — The version this lesson's code all runs on.