
IMPLEMENTATION
Multi-Agent Patterns as Workflow Loops
The multi-agent patterns everyone diagrams (two-agent loops, group chat, manager-worker, hierarchies) all reduce to the same node-and-edge graph. What actually decides whether one runs safely is the termination logic, not the shape.
TL;DR
Every multi-agent pattern people draw as a distinct diagram, two agents ping-ponging, a group chat, a manager and its workers, a reporting hierarchy, compiles down to the same graph: agent nodes, a conditional node deciding what runs next, and an edge that can point backward. The diagram is not where these systems fail. The termination logic is.
A conditional node that decides "keep going" is a model making a judgment call, as capable of being wrong, or of never firing, as any other model output. We think most designs spend their attention on who talks to whom and treat how the conversation is guaranteed to stop as an afterthought, which is backward.
Two of these shapes are worth building without much hesitation: the two-agent loop and manager-worker delegation, because in both, one turn's output has an obvious, checkable stopping condition. Group chat and deep hierarchies are the ones we'd think hard about, because the signal for "stop" is buried in more agents' worth of noise.
The fix isn't a smarter decider. It's a hard budget on every loop, a rerun counter that fails closed, and a termination check that doesn't depend on a model correctly reporting its own completion.
Overview
The design patterns for multi-agent systems, manager-worker, peer collaboration, debate, get covered as concepts in a companion post on agent design patterns: what each buys you and when it's the right call. This one is about what happens after that decision, when you have to actually wire the pattern up as something that runs, loops, and eventually stops.
Every one of these patterns, no matter how different the diagram looks, reduces to the same three ingredients: agent nodes that produce output, a conditional node that inspects that output and decides what happens next, and an edge from the conditional back to an earlier node, which is what makes the whole thing a loop instead of a straight line. A two-agent back-and-forth, a group chat, and a five-layer reporting hierarchy are the same graph with different numbers of nodes and different rules about who talks to whom.
Agent → Conditional("continue?") → back to Agent, or → End
That structural sameness is useful, because it means the interesting engineering problem isn't the topology. It's the conditional node: what it's checking, how it decides, and what stops it from deciding "keep going" forever.
The shape of the graph is the easy part. The conditional node that decides whether to loop back or stop is the hard part, and it's the piece that actually determines whether the system is safe to run unattended.
The Two-Agent Loop
The simplest version: one agent produces something, a second agent (or a human) responds, and a conditional checks whether the exchange is done. An assistant looping with a human until the user says they're satisfied is one version. Two agents ping-ponging, one drafting and one reviewing, until the reviewer signs off, is another.
This is the pattern worth building with the least hesitation, because the stopping condition is usually concrete: the human says "done," or the reviewer's output contains a pass/fail field you can check without asking a model to interpret free text. The failure mode worth naming anyway: an assistant-assistant loop with no human and no external signal is structurally the same self-review problem covered in the companion post's section on reflection. Agent B critiquing Agent A's output from the same context Agent A had access to isn't an independent check, it's the same blind spot with an extra model call attached. If the second agent in the loop can't see anything Agent A didn't already have, the loop converges on agreement, not correctness.
Group Chat
Group chat patterns add an aggregator that broadcasts the conversation to several agents each round, collects their responses, and asks a conditional whether the group is "done." It looks like the natural generalization of the two-agent loop. In practice it's the pattern we'd think hardest about before shipping.
The problem is that every extra agent in the room is another voice the conditional has to make sense of, and "is the group done" is a much fuzzier judgment than "did the reviewer approve this." Three or four agents producing a paragraph each, every round, for several rounds, produces a transcript that's expensive to run and genuinely hard for anything, model or human, to summarize into a clean stop signal. The rounds keep going not because more rounds are helping, but because nothing in the design forces a crisp answer to "helping compared to what."
If a task seems to want group chat, ask first whether it's actually manager-worker with the manager label missing. Most tasks that feel like they need several agents talking freely turn out to decompose into independent pieces once you look for the seams, and independent pieces don't need to be in the same room.
Manager-Worker Delegation
A manager dispatches subtasks to workers, collects their results, and a conditional decides whether the overall task needs another round of delegation. This is the multi-agent shape we'd default to, for the same reason the companion post gives it top billing conceptually: when the workers' subtasks are genuinely independent, the manager's stopping condition is just "have all the dispatched subtasks returned, and did they succeed," which is a checkable fact rather than a judgment call.
manager -> [workerA, workerB] -> managerDecider
managerDecider: all results present and valid? -> end
managerDecider: a worker failed or returned incomplete? -> re-dispatch that worker onlyThe detail worth getting right is re-dispatching only the worker that actually failed, not the whole round. A manager that reruns every worker because one came back wrong turns a targeted retry into a full do-over, tripling cost for a problem that lived in one branch. Track success per worker, not per round, and the conditional's job gets much easier: it's checking a small set of pass/fail flags instead of re-reading everything and re-deciding from scratch.
Hierarchical Delegation
Nest manager-worker one or more levels deep, a director delegating to team leads who delegate to workers, and each layer gets its own loop and its own conditional deciding whether to send work back down. On paper this is just manager-worker recursively applied. In practice it's the shape most likely to burn through a step budget without anyone noticing, because a failure at the bottom can trigger a rerun that ripples upward through every layer above it before anyone catches that the total work being redone has multiplied.
Take a worker whose output a team lead rejects. The worker retries, burning its own budget. If the team lead's own output then also gets rejected by the director, the team lead reruns its entire delegation to the worker, not just its own summarization step, and the worker's retries start over inside that new round. Three layers each allowed five retries isn't fifteen retries in the worst case. It's up to a hundred and twenty-five, because the layers compound multiplicatively rather than adding.
We'd only build a hierarchy past two levels when the organizational structure it mirrors is genuinely that deep, and even then, give every layer its own hard-capped budget rather than one global counter, so a bad worker can exhaust its own retries without silently eating the director's.
Termination Is the Whole Problem
Done -> [end] Running -> Failed (loop counter exceeds budget) -> [end]
Every loop needs the Failed exit as much as the Done exit. Without it, "continue" has no ceiling. -->
Figure 1 — Every one of these patterns is this state machine underneath. The Failed exit, triggered by a counter rather than a judgment call, is what makes "continue" a safe answer instead of an open-ended one.
Every pattern above shares one dependency: a conditional node that has to correctly recognize when the task is actually finished. That's a harder job than it looks, because the same model producing the work is frequently the model being asked to grade it, and a model can report success on output that's subtly wrong, or fail to recognize completion and keep looping past the point where more rounds help.
Two things fix most of what goes wrong here, and neither is "make the decider smarter."
A hard, per-loop counter that fails closed. Every conditional node needs a rerun limit, and hitting it needs to route to an explicit failed state, not a silent stop that looks like success downstream. A loop that quietly stops at its limit and returns whatever it had is a loop that fails the same way every time and never tells anyone.
A termination signal that doesn't depend on free-text interpretation. "Does the response say DONE" is a worse check than "does the response contain a structured field with an explicit status," because the first depends on the model reliably producing an exact string under pressure and the second is something you can validate without asking a model anything at all. Where the task allows it, push the stop condition into something checkable, a schema field, a count matching an expected total, rather than a judgment prompt asking the model whether it thinks it's done.
A conditional node that can only say "continue" or "stop" is missing a state. Give it a third: "stop, and flag this for a human," for the cases where the loop has run out of budget but the task genuinely isn't resolved. Silently returning a partial answer as if it were a final one is worse than admitting the loop didn't finish.
Conclusion
The diagrams for these patterns are the least interesting part of building one. Agent nodes, a conditional, an edge that loops back, that's the whole vocabulary, and every pattern from a two-agent exchange to a five-layer hierarchy is built from the same three pieces in a different arrangement. What separates a multi-agent system that runs safely from one that quietly burns budget or loops forever is the part nobody draws: the counter that fails closed, and a stop condition that doesn't rely on a model correctly reporting on itself.
Build the two-agent loop and manager-worker delegation first; their stopping conditions are close to free. Reach for group chat and deep hierarchies only when the task genuinely can't be flattened into something simpler, and when you do, give every layer its own budget rather than trusting one global counter to catch everything underneath it.
Topology is a design choice. Termination is a safety requirement. Get the second one wrong and it doesn't matter how well the first one was chosen.