ThisCalculator

Everyday

Build Durable AI Agents With Explicit State Machines

Updated · Standard formula, shown below

Build Durable AI Agents With Explicit State Machines

Explicit state machines make AI agents easier to understand, test, and recover when a model, tool, or process fails. You define the agent’s allowed states and transitions, then use the model for bounded decisions rather than letting it control the entire workflow. You’ll need a clear task, a runtime that can save state, and access to any models or tools the agent will use.

What You’ll Need

  • A development environment and a language or workflow framework that supports structured data and persistent storage.
  • A written description of the agent’s task, success conditions, failure cases, and any actions requiring human approval.
  • Model access, if the workflow needs a language model, plus credentials stored outside source code.
  • Tool interfaces for actions such as searching, retrieving records, or sending messages. Use test doubles while developing.
  • A state store that supports durable writes, such as a database or a persistent workflow engine. Choose one appropriate to your reliability needs.

Step-by-Step

  1. Define the job and boundaries. Describe the input, expected output, and what counts as completion. List actions the agent may take and actions it must not take. For example, an agent may draft a response but require approval before sending it. Treat permissions and approval rules as application controls, not instructions the model can override.
  2. Map the workflow before writing prompts. Sketch a finite set of states, such as RECEIVED, VALIDATING, PLANNING, WAITING_FOR_APPROVAL, EXECUTING, COMPLETED, and FAILED. Add a PAUSED state if work can wait for an external event. Keep states distinct: each should describe one meaningful stage, not a vague combination of progress and outcome.
  3. Specify transitions and guards. For every state, record which events can move the workflow forward, what conditions must be true, and what happens otherwise. For example, PLANNING can transition to WAITING_FOR_APPROVAL only when the proposed action is valid and approval is required. Define terminal states and prevent transitions out of them unless a deliberate recovery path exists.
  4. Design a versioned state record. Persist a workflow ID, current state, state version, input or a durable reference to it, validated outputs, pending work, timestamps, and relevant error details. Record only the context needed to resume; avoid storing secrets or unnecessary personal data. Add a schema version so deployments can migrate older records safely.
  5. Make each transition a controlled operation. Implement a transition function that checks the current state, validates the event and guard, applies the change, and writes the new record. Use a transaction or compare-and-swap condition on the state version to prevent two workers from advancing the same workflow simultaneously. Reject unknown events rather than guessing.
  6. Keep model calls inside bounded steps. Ask the model for a specific output, such as a proposed plan matching a schema. Validate the response before using it: check required fields, allowed values, size limits, and business rules. If validation fails, retry within a limit or move to a defined failure or review state. Never let free-form model text directly select arbitrary code, permissions, or tools.
  7. Make tool actions safe to retry. A process may crash after a tool succeeds but before the workflow records success. Give each intended action a stable idempotency key when the tool supports one, and store its status. For tools without idempotency support, check whether the action already happened before repeating it, or route uncertain outcomes to human review. Do not assume exactly-once execution.
  8. Persist before waiting or doing risky work. Save the state and the information needed to resume before a long model call, external request, approval wait, or other interruption point. Use timeouts and bounded retries for transient failures. On restart, load the record and resume from the last committed transition rather than recreating the workflow from the original prompt.
  9. Add observability and controls. Log workflow IDs, state changes, transition reasons, tool outcomes, retry counts, and durations. Redact credentials and sensitive values. Set limits on model calls, elapsed time, and tool use. Provide a way to inspect, pause, cancel, and safely retry a workflow without editing production records by hand.
  10. Test transitions and recovery paths. Unit-test allowed and rejected transitions, guards, invalid model outputs, and terminal states. Simulate timeouts, duplicate events, worker crashes, partial tool success, and old state versions. Test that resuming after each interruption neither skips required checks nor repeats consequential actions. Start with a test environment and a small rollout before expanding usage.

Common Mistakes

  • Putting the whole process in one prompt: this hides progress and makes recovery difficult. Keep workflow control in ordinary code or a durable workflow engine.
  • Using vague states: labels such as IN_PROGRESS do not say what work is underway. Prefer states tied to specific actions and expected events.
  • Saving only conversation history: messages do not reliably capture tool status, approvals, or committed transitions. Persist structured workflow data.
  • Retrying every failure: permanent validation errors and uncertain side effects need different handling from temporary network failures. Classify errors and cap retries.
  • Trusting model output: plausible text can still be malformed or unsafe. Validate it and enforce permissions outside the model.
  • Changing state schemas without a migration plan: old workflows may become unreadable after deployment. Version schemas and test resuming records created by earlier releases.

Tips

  • Draw the state diagram and review it with the people who own the task before implementation.
  • Keep transitions small and explicit; one transition should represent one committed fact or completed action.
  • Use structured model output where available, but still validate it in application code.
  • Separate temporary errors, which may be retried, from permanent errors, which need correction or review.
  • Make the workflow inspectable: operators should be able to see the current state and why it reached that state.
  • Keep prompts, transition rules, and policy checks independently versioned where possible, so changes can be reviewed and rolled back.

Troubleshooting

The agent repeats an action after restarting: Check whether the external action succeeded before the workflow recorded it. Add an idempotency key, reconcile against the tool’s result, or require review when the outcome is uncertain.

A workflow appears stuck: Inspect its persisted state, last transition, pending event, and timeout. Confirm that a worker or callback can deliver the expected event. Add an explicit timeout transition to a retry, paused, or failed state instead of leaving work waiting forever.

Two workers process the same workflow: Use atomic state updates with a version check or a lease, and reject stale writes. Ensure duplicate event delivery is safe.

Model responses keep failing validation: Narrow the requested output, provide a precise schema and examples, and log validation errors without exposing sensitive data. Retry only a limited number of times; then route the workflow to a useful failure or review state.

A deployment breaks existing workflows: Check the record’s schema version and run a tested migration or compatible reader. Do not silently reset old workflows to their initial state.

Frequently Asked Questions

What is an explicit state machine for an AI agent?
It is a defined set of workflow states and permitted transitions. The application controls progress, while the model handles specific bounded tasks within that workflow.

Do I need a workflow engine?
No. A database and careful transition code can work for simple tasks. A durable workflow engine can help when you need long waits, retries, timers, or coordination across workers.

Should the model choose the next state?
Usually, application logic should decide transitions. The model may propose a classification or plan, but validate it and apply explicit guards before changing state.

How should I handle a human approval step?
Persist the proposed action and move to a waiting state. Resume only after receiving a verifiable approval or rejection event, and recheck that the proposal is still valid before execution.

Can I guarantee that a tool runs exactly once?
Not in general across a crash and an external service. Use idempotency keys or reconciliation where possible, and treat uncertain outcomes as a case for review.

What should I store to resume an agent?
Store the current state, validated workflow data, pending action status, schema version, and durable references needed to continue. Avoid relying on chat history alone.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.