The Reactive Reducer Pattern Series (Intro)
Same input. Same prompt.
Same model. Different outcome.
Run it again. Different outcome… again.
That’s the state of most agent orchestration.
You wire a supervisor, a handful of specialists, maybe a router, a retry loop, and you’ve built a system that works - until it doesn’t.
It’ll often fail in a way you can’t reproduce.
The user gets a wrong result, and you can’t tell why. The trace shows the agents talking - paraphrasing, summarizing, deciding - and the only thing standing between you and a token bill you didn’t budget for is how well the models happened to behave that day.
Three failure modes keep coming back, and they’re not really three problems. They’re one:
- Non-deterministic outcomes. The workflow’s path depends on what the agents said to each other, not on a declared graph. Re-run it and the path is different. You can’t replay it, so you can’t debug it.
- Poor user experiences. The user is watching a chain of agents guess at each other. A bad handoff, a lost summary, a routing call that poisons the rest of the task - the user feels it as “this thing is unreliable,” and they’re right.
- Token budgets exploding. Every agent carries the growing transcript of every other agent. Context grows with the number of hops, the number of specialists, the number of rounds. The bill grows with the conversation, and the conversation is unbounded.
The root cause is the same in all three: the agents are doing the control flow. They’re deciding who acts next, what gets passed along, and when the task is done. And a model deciding control flow is a non-deterministic control flow. You can prompt it to be careful. You can’t make it deterministic.
The reactive reducer
The fix isn’t a better prompt. It’s a different substrate for the whole thing.
An Aegis FSM is a reactive reducer. Three rules:
contextis the single source of truth. Every artifact, every decision, every vote is a typed field in a shared store. There are no handoff messages, no transcripts, no “the agent summarized it.” The handoff is a context write.- Agents advance the machine by writing context - never by requesting a transition. There’s no
requestTransitiontool, no sign-off call, no “may I move to the next step?” An actor’s only lever is to contribute a value. The machine decides what that value means. - A microstep loop fires the first eligible, guard-passing edge until the machine parks. When a write lands, the reducer re-runs: it checks the current state’s edges, evaluates their guards (CEL expressions over the context), fires the first one that passes, and repeats until no edge is eligible. Then it parks - durable, journaled, restart-safe - until the next write.
The machine moves itself. Actors only ever contribute values.
That loop is the whole design, and it’s what makes the three failure modes stop being problems:
- Determinism. The path is the declared edge set. The machine can only move along edges you drew, and it fires the first eligible one. Re-run the same
(state, context)and you get the same edge. The run is a sequence of(state, context-write, edge-fired)records - a complete, journaled replay. You can debug it because you can replay it. - Predictable experience. The user isn’t watching agents guess. They’re watching a machine advance through declared states, and every advance is a context write a guard reacted to. A bad handoff can’t happen, because there are no handoff messages - the next state’s objective interpolates the full value of the field the previous state wrote.
- Bounded tokens. An agent’s per-turn injection is the CONTEXT block (set fields, capped per value) plus its own objective. The full artifacts live in the store and are templated in full only into the state that needs them. Context cost is roughly constant in the number of fields, not the sum of the agents’ outputs. And every loop - the rework loop, the debate, the planner/executor re-plan, the refinement cycle - is bounded by a
verdictenum,policy.maxIterations, and the reducer’s no-progress guard. The token bill is bounded by the design, not by how well the models behaved.
That’s the thesis of the series: take the orchestration patterns everyone already uses, and implement each one as a reactive reducer. The pattern is the shape of the coordination. The reducer is the thing that makes the shape exact.
Two ways to run it
The same FSM runs at two very different scales, and that’s not a footnote - it’s why the pattern is worth the series.
Interactive runners. For the work you’re doing right now - a review, a research question, a deployment gate - the FSM runs in an interactive runtime. The machine parks, the runtime summons the acting agent over A2A, the agent writes context, the reducer re-runs. You watch it advance state by state, and because every write is journaled, you can pause, inspect the store, and resume. It’s a small, legible runner, and the legibility is the point: you can see exactly which state the machine is at and why it’s there.
Compiled to Mutiny / Flink. For high-volume orchestration at scale - thousands of concurrent runs, long-running event-driven workflows, distributed agent systems - the same reactive reducer compiles to a reactive runtime. The microstep loop is a stream of context writes and edge evaluations; the park is a durable, checkpointed state; the guards are the routing predicates. Mutiny gives you the async, backpressure-aware reactive substrate; Flink gives you the fault-tolerant, checkpointed, exactly-once stream semantics. The FSM doesn’t change - the runtime does. You author the machine once, and it runs interactive on your laptop or headless across a Flink cluster, with the same declared edges, the same guards, the same journaled store.
That’s the property that makes the reducer a pattern instead of a trick: the coordination logic is separate from the execution substrate. The pattern (the shape of the coordination) is declared once. The substrate (interactive runner, Mutiny, Flink) is a deployment decision. The same exact, deterministic, journaled machine runs at the scale of a single review and at the scale of a production event stream.
What this series covers
Thirteen patterns. One reducer. Each article takes one of the multi-agent orchestration patterns that keep showing up in real systems, and implements it as a concrete Aegis FSM: the pattern’s description and failure points, a full FSM YAML, the state machine as a diagram, and - the part that matters - what the reducer does to each failure point.
- Flow: Sequential Pipeline, Parallel Fan-Out / Fan-In
- Authority: Supervisor / Router, Hierarchical Manager / Worker
- Delegation: Peer Handoff / Swarm, Auction / Contract-Net, Dynamic Team Formation
- Reasoning: Debate / Consensus, Quorum / Voting, Generator / Critic / Refiner
- Planning: Planner / Executor
- Coordination: Blackboard / Shared-State, Event-Driven / Publish-Subscribe
If you want the whole series in one place - every pattern with its diagram and its failure points, side by side - the series landing page is the map. Otherwise, start where your workflow hurts most.
Up next: 1. Sequential Pipeline
Series:
- Intro
- 1. Sequential Pipeline
- 2. Parallel Fan-Out / Fan-In
- 3. Supervisor / Router
- 4. Hierarchical Manager / Worker
- 5. Peer Handoff / Swarm
- 6. Debate / Consensus
- 7. Blackboard / Shared-State
- 8. Planner / Executor
- 9. Generator / Critic / Refiner
- 10. Auction / Contract-Net
- 11. Event-Driven / Publish-Subscribe
- 12. Quorum / Voting
- 13. Dynamic Team Formation