Stateless Reducer Agent
also known as Pure-Function Agent, Event-Sourced Agent, 12-Factor Stateless Agent
Design the agent as a pure function (state, event) → newState; entire execution history is held in an external event log; enables pause / resume / replay / time-travel without bespoke checkpointing.
Context
A team builds an agent. The default is to hold state in process memory (Python objects, in-memory dicts). Pausing, resuming, or replaying the agent requires custom checkpointing logic that is inevitably incomplete.
Problem
In-memory agent state cannot be paused, resumed across processes, or time-travelled. Each capability requires bespoke checkpointing that misses edge cases. Differs from durable-workflow-snapshot (which is a snapshot mechanism) by being a programming-model constraint — the agent is *designed* as a reducer, not made into one after the fact.
Forces
- Stateless-reducer discipline constrains how agent code is structured.
- External event log adds infrastructure dependency.
- Some operations are naturally stateful (caches, connections) and need separate handling.
Example
A coding agent encounters a long-running test step. The runtime pauses by stopping event dispatch. A user requests resumption from a different worker. The new worker reads the agent's event log, replays the reducer from log start to current position, then resumes dispatch. Time-travel: the user later replays the log up to step 12 to debug a problem; the agent reconstructs its state at step 12 exactly.
Diagram
Solution
Therefore:
The agent's core is a pure function: takes (current state, next event) → (new state, side-effect descriptors). Side effects are descriptors, not executions — the runtime dispatches them. All events are appended to a durable log. Pause = stop dispatching. Resume = restart dispatching from current log position. Replay = re-run reducer against earlier log slice. Time-travel = re-run against any log slice. Pair with durable-workflow-snapshot, event-driven-agent, deterministic-control-flow-not-prompt, own-the team's-prompts.
What this pattern forbids. All agent state changes flow through the reducer; no hidden state in process memory; all events are persisted to the durable log.
And the patterns that stand alongside it, or against it —
- complementsDurable Workflow Snapshot★— Capture workflow execution state as a snapshot in a pluggable storage provider so a paused run can resume across deployments, process restarts, and host crashes.
- complementsEvent-Driven Agent★★— Trigger the agent on external events (webhooks, message queues, file changes) instead of user requests or schedules.
- complementsDeterministic Control Flow, Not Prompt★— Branching decisions live in deterministic application code while the LLM is invoked at strategic points to produce structured signals that the code branches on.
- complementsOwn Your Prompts (12-Factor Agents)★— Every prompt in a production agent is versioned, tested, and owned by the team in the application repo — never inherited as a framework default.
- complementsAgent Resumption★★— Persist agent execution state so a long-running run survives restarts, deploys, or user disconnects.
- complementsBlocking Sync Calls in Agent Loop✕— Anti-pattern: run synchronous, blocking I/O inside the agent loop or HTTP handler, capping concurrency at the number of OS threads.
- complementsSubject-First Agent Architecture (ENA Stateful Core)·— Invert the LLM-centric pipeline: the agent is a stateful subject whose decision logic chooses whether to invoke the LLM at all, treating the model as one tool among many.
- complementsOrchestrator as Bottleneck✕— Anti-pattern: route all agent runs through a single-process orchestrator that becomes the system-wide concurrency ceiling.
- complementsHidden State Coupling✕— Anti-pattern: agent workflows read or write undeclared shared state (caches, env vars, process globals) instead of explicit inputs and outputs.
Neighbourhood
Click any neighbour to follow the language. Scroll to zoom, drag to pan.