Cheat sheets

Multi-Agent Systems

Agents, handoffs, shared state and orchestrators. Pick a pattern, vote, checkpoint and fix the known failures.

  • Concepts and terms
  • Tasks and commands
  • Annotated code
  • Diagrams
  • Defaults and numbers
  • Troubleshooting
  • Questions and tips

Source

Four primitives#

runseach stephandoffhandoffappendpublishreadOrchestratorstatic, handoff,selectorCheckpointStorethread_id,super_stepAgent:researcherprompt + toolsAgent: writerstatelessAgent: reviewerstatelessSharedStatemessage poolBlackboardtopic pub/subVerifierread onlyrunseach stephandoffhandoffappendpublishreadOrchestratorstatic,handoff,selectorCheckpointStorethread_id,super_stepAgent:researcherprompt +toolsAgent:writerstatelessAgent:reviewerstatelessSharedStatemessagepoolBlackboardtopicpub/subVerifierread only

From Lesson 16.04, 16.04 code/main.py, Lesson 16.13, Lesson 16.22, 16.22 code/main.py

Coordinate agents#

TaskCode
Share a message poolstate = SharedState() then state.append(<msg>)
Run a fixed orderStaticOrchestrator(<order>).run(team, state)
Let the agent pick nextHandoffOrchestrator("<start>").run(team, state)
Let a selector pick nextLLMSelectorOrchestrator("<start>", round_robin_selector)
Hand off with a tooldef transfer_to_refunds() -> "Agent": return refund_agent
Run a group chatrun_groupchat(AGENTS, <selector>, max_rounds=8, label="<label>")
Fan out workersthreading.Thread(target=w.run, args=(sq, results, i))
Publish to a topicbb.publish("<writer>", "<topic>", "<content>", "<prompt>")

From 16.04 code/main.py, 16.05 code/main.py, 16.10 code/main.py, 16.11 code/main.py, 16.13 code/main.py

Vote, persist and protect#

TaskCode
Count votesplurality(votes)
Weight votes by confidencecp_wbft(votes, threshold=0.5)
Leaderless pickdecentllms(votes)
Save a checkpointstore.write(thread_id, super_step, dict(state))
Resume after a crashstore.latest(thread_id)
Give an agent a queueAgentQueue("<agent_id>").enqueue(<msg>)
Stop a retry stormif not breaker.allow(): ... then breaker.record(ok)

From 16.14 code/main.py, 16.22 code/main.py, 16.23 code/main.py

One supervisor run#

1Leadplan(query) splits the query into sub-questions.2LeadStarts one Worker thread for each sub-question.3WorkerStarts from a fresh context with one narrowquestion.4WorkerWrites a WorkerResult with summary andtokens_spent.5LeadJoins all threads. Wall clock is about theslowest worker.6Leadsynthesize(query, results) merges the answers.7LeadReports wall_clock_seconds, total_tokens andworker_count.

From 16.05 code/main.py, Lesson 16.05

Confidence-weighted vote#

def cp_wbft(votes: list[Vote], threshold: float = 0.5):
weights: dict[str, float] = {}
rep: dict[str, str] = {}
for v in votes:
key = v.canonical()cluster equal answers
weights[key] = weights.get(key, 0.0) + v.confidence
rep.setdefault(key, v.answer)
total = sum(weights.values()) or 1.0
winner_key = max(weights, key=weights.get)
if weights[winner_key] / total < threshold:
return None, weightstoo weak: retry or escalate
return rep[winner_key], weights

From 16.14 code/main.py

Pick a pattern#

Pipeline
Each agent transforms and passes on. One failed stage blocks the rest.
Fan-out / fan-in
Split into parallel agents, then merge. For independent subtasks.
Supervisor
Lead plans, delegates and synthesizes. Wrong for sequential tasks.
Hierarchical
Supervisors over supervisors. Only leaves work.
Group chat
Peers share a pool. A selector picks the next speaker.
Handoff
The active agent calls a tool that returns the next agent.
Blackboard
Topic pub/sub. Wins with many agents on long runs.
Single agent
Under 20 tool calls and 100k tokens, stay single.

From Lesson 16.01, Lesson 16.05, Lesson 16.06, Lesson 16.10, Lesson 16.11, Lesson 16.13

Handoff loop (Swarm style)#

def run_swarm(start_agent: Agent, user_messages: list[str]) -> list[Msg]:
history: list[Msg] = []
active = start_agentwho holds the chat
for user in user_messages:
history.append(Msg(role="user", content=user))
out = scripted_router(active, user)stands in for an LLM
if isinstance(out, Agent):a tool returned an agent
history.append(
Msg(role="assistant", content=f"(handoff to {out.name})", sender=active.name)
)
active = outswitch the active agent
out = scripted_router(active, user)
history.append(Msg(role="assistant", content=str(out), sender=active.name))
return historynothing persists

From 16.11 code/main.py

Defaults in the code#

SettingDefaultNote
max_steps10Every orchestrator run
max_rounds8Group chat demo cap
TERMINATETERMINATEToken that ends a group chat
threshold0.5cp_wbft acceptance share
rounds2Graph topology debate rounds
failure_threshold0.5Breaker opens above this error rate
window_size20Breaker outcomes in the window
open_cooldown_s0.5Seconds before half open

From 16.04 code/main.py, 16.10 code/main.py, 16.14 code/main.py, 16.15 code/main.py, 16.23 code/main.py

Troubleshooting#

SymptomCauseFix
One agent talks every turnHot speaker in the selectorAdd speaker balance to the selector
Context grows each turnEvery agent reads every messageGive agents projections
Two agents hand back and forthHandoff loopCap max_steps on the orchestrator
A wrong number spreads to allMemory poisoning in shared stateProvenance, append only, read-only verifier
Majority is wrong togetherMonoculture, same base modelMix base models
Workers research the wrong targetManager split drifted from the goalAdd a canary question worker
Workers disagree, one side winsSilent synthesis conflictRe-ask or report the disagreement
Downstream load grows 10xRetry stormCircuit breaker, capped retries

From Lesson 16.05, Lesson 16.06, Lesson 16.10, Lesson 16.11, Lesson 16.13, Lesson 16.14, Lesson 16.23, Lesson 16.15, 16.04 code/main.py

Glossary#

BFT
Byzantine fault tolerance. Tolerates f < n/3 faulty nodes.
CP-WBFT
Confidence-Probed Weighted BFT. Votes weighted by confidence.
MAST
Failure taxonomy. Specification, coordination, verification.
MARBLE
MultiAgentBench. Star, chain, tree and graph topologies.
Super-step
Unit of work between two checkpoints.
Outbox pattern
Write the side effect intent first. A separate executor runs it.

From Lesson 16.14, Lesson 16.23, Lesson 16.24, Lesson 16.22

Q&A#

What does multi-agent cost?
About 15 times the tokens of a single agent.
Why can the verifier not write?
A poisoned pool then cannot poison it.
Which threshold for 5 to 7 voters?
0.5 to 0.67. Below it, escalate.
More agents or other models?
Other models. Three models beat five copies of one.
Most common failure?
Specification problems, 41.77% of MAST failures.

From Lesson 16.05, Lesson 16.13, Lesson 16.14, Lesson 16.15, Lesson 16.23

Tips#

  • Shared state is the only stateful part. Look there first for bugs.
  • Keep hierarchies at depth 2 or less.
  • Bound debate rounds to 2 or 3.
  • Past about 4 agents in a graph, the coordination tax grows.
  • Use async I/O for LLM calls. Threads cost about 1MB each.
  • Put a dedup key in every side-effect call.

From Lesson 16.04, Lesson 16.06, Lesson 16.14, Lesson 16.15, Lesson 16.22