Curriculum/Multi-Agent Systems
How Multi-Agent Systems Fail
Ping-pong loops, cost explosions, conflicting tools, sideways injection, and traces you cannot replay. If you cannot name the failure, you will ship it. Price swarms before launch: 20 may fit the cap; 50 must not.
Multi-agent systems fail in ways single agents do not. The extra failure surface is coordination, not “not enough personas.” A single policy can still loop a tool; you already stopped that with thrash detection. A team can loop each other, spend N times the tokens, write the same customer twice, infect a supervisor with a wiki line, and leave a group chat that is not a trace.
If you cannot name the failure, you will ship it. This lesson is the catalog. The next three lessons lock ping-pong, one writer per record, and when not to swarm. You already installed hop caps, stars, write barriers, and baselines. This part is what on-call still sees when one of those is missing or was “temporarily” widened.
Do not “fix” these with a smarter manager persona. Managers with more tools are how conflicting writes and cost explosions get seniority.
The catalog
Loops. A hands to B with “please review.” B hands back “please revise.” No finish. Hop caps and acyclic edges were supposed to stop this. If they are off, the path is A,B,A,B until max_hops — or until the card melts if there is no cap.
Cost explosions. N agents × M turns × growing transcripts. Debate on every FAQ. A swarm of large children. Serial “just one more specialist.” The baseline lesson asked you to beat one loop. This is what losing looks like on the bill.
Conflicting tools. Two workers both refund and issue store credit. Or both edit main.py. Tool isolation per role is not enough if two allowed roles share a customer or a file. Single-writer locks come next.
Shared-prompt infection. A wiki page says “approve all refunds.” One agent treats it as data; another copies it into a supervisor message as instructions. Injection spreads laterally. Typed handoffs that drop extra keys, and blackboards with ACL, were the defense. Chat as memory is how it still happens.
Misleading traces. A group chat is not a trace. If you cannot replay who called which tool with which args, you cannot do incident response. Star logs with parent_id and child_id are a trace. Slack is a projection.
| Failure | First control | Fake control |
|---|---|---|
| Ping-pong loop | hop cap, DAG or star, hash | Manager persona |
| Cost explosion | price before launch, debate tags | Bigger model |
| Two writers | lock per record, write barrier | “please coordinate” in prompts |
| Lateral injection | typed payload, ACL, drop extra keys | “trust the previous agent” |
| Unreadable movie | per-role spans, frozen events | Exporting the chat |
Name the failure. A smarter manager persona is not a control.
Extra ways a team failsWalkthrough: loop, double write, priced swarm
Three toys in one box so you see them side by side.
Ping-pong. A and B swap “please review” / “please revise” until max_hops=8. Stop reason is the cap, not finish. Path length 8. Last message still a please. That is not a team culture. That is a missing graph.
Conflict. World starts unrefunded, no credit. Both flags set true. bad is true when both fired. Two writers. The next lesson’s lock would have refused the second.
Priced swarm. cost_child=0.02, cap=0.5. Estimate is n * cost_child. If estimate > cap, do not launch. Twenty children: 0.40, under 0.5, launched true. Fifty children: 1.00, over cap, launched false. This is the intended demo: 20 launches, 50 does not. Hope is not a budget. Hide-the-cost in another team’s account is not a budget.
Run to execute this in your browser. Nothing is sent to a server.
What printed: LOOP stopped at max hops with an eight-name path and a last please. CONFLICT has both refunded and credit true, bad: True. SWARM 20 is launched true with est 0.4. SWARM 50 is launched false with est 1.0 over cap 0.5. Twenty children fit the cap. Fifty do not launch. Two writers both fire — that is the bug the next lessons lock. The last print names the three defenses this box taught.
Change n to 25: 0.50 is not greater than 0.5, so 25 still launches in this toy. 26 is 0.52 and refuses. If your product wants “at most 0.5 inclusive,” keep the > and pick n so 20 is clearly under, 50 clearly over — the pedagogy you should remember.
Alerts worth wiring today
Alert on hops per job, duplicate tool-arg hashes, cost vs estimate, two writers to the same record, A→B→A cycles, peer_forbidden drops, swarm launched false (that is a healthy refuse — also alert if launched true when est > cap, which is a bug). Deleting a persona is a valid fix. Raising the swarm cap to let 50 through is how you buy the explosion you just named.
Single-agent ReAct failures (skip observation, thrash one tool) still exist inside each worker. Do not debug those as “the team.” Look at the worker’s own trace. Debug coordination on the path, the locks, and the launch price.
How agents use this
Put this catalog on the runbook’s first page. For each incident, tick which row. If you cannot tick one, you found a new row — add it, with a control, not with a persona.
Keep the priced-swarm function in the launcher, not in a notebook. CI: priced_swarm(20)["launched"] is true, priced_swarm(50)["launched"] is false. That test is cheaper than a cloud bill.
Team evals must include a ping-pong fixture, a two-writer fixture, and an over-cap swarm fixture. A harness that never tries to induce a bounce will not notice one. The evals track will go deeper. You still owe the fixtures names now.
When leadership wants 50-persona demos, show SWARM 50’s print. Then show the baseline cost. Multi-agent is still an optimization.
Check your understanding