Your agentic automation will break at 2am because the network flakes, a vendor API times out, the worker restarts mid-step, and you do not know what already happened.
The fix is not “better prompts” or “more agents”. It is durable execution: resumable workflows with persisted state, explicit retries, idempotent side effects, and an audit trail you can debug under pressure.
The 2am failure modes nobody demos
Multi-agent demos look fine because everything happens in one process, in one sitting, with a human watching. Production does not work like that. Even if your model output is perfect, the automation still fails for operational reasons.
Here are the common ones you will meet within the first few weeks:
- At-least-once execution meets non-idempotent side effects. Your worker retries a tool call and you accidentally double-charge, double-email, or double-create tickets.
- Partial failures and ambiguous outcomes. The HTTP request timed out. Did the vendor apply it? You cannot tell, and “just retry” may be wrong.
- Lost in-memory state. A long-running run spans deploys, pod evictions, token refreshes, database failovers, or simply a crash. Without persisted state, “resume” means “start again”.
- Human-in-the-loop isn’t durable. Someone approves in Slack, your worker dies, and you have no consistent way to continue from the exact same state (or to prove what was approved).
- Concurrency and duplicate triggers. A webhook is redelivered, a scheduler runs twice, or a user clicks twice; now you have two runs racing to mutate the same business entity.
- Cost and latency runaway. Repair loops that are safe in a notebook become expensive when they run repeatedly on retries or on duplicated executions.
Frameworks are increasingly explicit about the “production glue” required. LangGraph, for example, has a whole fault-tolerance story (timeouts, retry policies, error handlers) because the boilerplate often exceeds the business logic in real deployments. (langchain.com)
If you have not built this kind of plumbing before, it is easy to accidentally recreate an unreliable job runner—except now it also calls LLMs.
Durable execution: the boring layer your agents sit on
Durable execution means you can write logic that appears to run once-to-completion even though the underlying system will crash, replay, retry and reschedule. Workflow engines typically do this by persisting progress (event history or checkpoints) so a run can be recovered deterministically after failures. Temporal describes workflow executions as durable in this exact sense: your workflow code should complete whether it runs for seconds or years, with activities handling failure-prone work. (github.com)
The important shift is architectural:
- Your “agent” is not a loop in a web request.
- Your “agent run” is a workflow instance with a stable identity.
- Your “tools” are activities/steps with clear retry and idempotency semantics.
Once you adopt this, you stop asking “how do we stop the agent hallucinating” and start asking “how do we make progress safely when everything fails in the normal ways”.
The Durable Agent stack (what you actually need)
Think of “agentic automation” as a stack. LLM orchestration is one layer; production reliability sits underneath it.
1) A workflow/orchestration layer with persisted state
You need a place where long-running runs live: inputs, intermediate state, and where you are in the process. That can be a dedicated workflow engine (for example, Temporal) or a library with a proper checkpoint store (for example, LangGraph’s checkpointing patterns). Temporal also emphasises that you split logic into workflows plus activities for external side effects. (temporal.io)
LangGraph explicitly supports checkpointing for thread state persistence and retention, and its docs call out configuration details (including avoiding duplicate persistence with subgraphs). (kb.langchain.com)
What to decide up front:
- Where is state stored (Postgres, durable KV, workflow engine backend)?
- What is the workflow identity (order ID, ticket ID, case ID, correlation ID)?
- What constitutes “resume” versus “restart”?
If you cannot answer these, you do not have an agent system yet—you have a demo.
2) Idempotent tools and explicit side-effect boundaries
Durability is worthless if retries duplicate side effects. Your system will retry. Your vendor will timeout. Your worker will replay. Your “tool” layer must be designed for this.
AWS’s Durable Execution guidance is blunt: at-least-once is only safe for idempotent operations (reads, upserts, calls with idempotency keys, anything safe to re-run). (docs.aws.amazon.com)
Practically, this means:
- Every mutating tool call takes an idempotency key derived from the workflow identity + step name + logical attempt.
- Prefer upserts over creates.
- Store “I did X” in your own database before (or atomically with) telling the outside world you did it.
Also assume races. Durable Workflow documentation puts it well: a late completion or failure report is a race the engine resolves, not proof that the remote side effect never happened. (durable-workflow.com)
3) Retries, timeouts, and backoff as first-class policy
Retry policy is not a boolean. You need per-tool configuration:
- Timeouts that match the downstream system.
- Backoff that avoids thundering herds.
- A “give up” threshold.
- A compensation path when “retrying” is harmful.
LangGraph makes this explicit with retry and timeout policies and an error handler node that runs when retries are exhausted, carrying the failure context. (langchain.com)
4) Checkpoints, replay, and re-entrancy
If you checkpoint state, your code will be replayed. That is the point. So your orchestrator code must be deterministic (or close enough) and your tool execution must be re-entrant.
AWS’s step semantics highlight the subtlety: if a function replays before a step result is checkpointed, the framework may skip or re-execute depending on the execution guarantee mode, and you have to handle “interrupted” results. (docs.aws.amazon.com)
This is where “agent code” often goes wrong: developers mix planning, tool calls, and external writes in one blob, then are surprised when replay duplicates work.
5) Audit trail you can search at 2am
If you cannot answer “what did the system do” quickly, on-call will disable it.
Durable systems typically provide a UI or at least searchable execution history: inputs, current step, retry counts, and what happened when. Temporal explicitly positions this as part of the durable execution value: you can inspect where a workflow is stuck and what it has done so far. (assets.temporal.io)
For agent systems, the audit trail should include:
- Workflow inputs (sanitised) and version
- Model + prompt/tooling versions
- Tool calls with parameters (sanitised) and idempotency keys
- Human approvals with who/when/what was approved
- Final outputs and where they were sent
This is not bureaucracy; it is how you turn “AI did something weird” into a debuggable incident.
A concrete architecture: agent-as-workflow, tools-as-activities
If you are building an internal automation (triage tickets, reconcile invoices, draft responses, run incident playbooks), the most reliable shape looks like this:
- Trigger creates a workflow instance with a stable ID (e.g. ticket ID).
- Workflow loads current domain state from your database.
- Workflow asks the model to propose a plan, but stores the plan as data.
- For each step, workflow calls a tool/activity that performs one bounded side effect.
- Each tool call uses an idempotency key and writes a receipt (what was done).
- On failure, the workflow retries per policy; on terminal failure, it routes to an error handler that can page a human with full context.
- Human approvals are explicit workflow states (pause, persist, resume), not “wait for a Slack reply and hope the process is still alive”.
Treat the LLM as a planner and classifier, not as your transaction coordinator.
This pattern is not “anti-agent”. It is pro-survivability.
When the right answer is “do not do this”
Not every workflow should be agentic. The durable stack adds operational overhead, and LLM behaviour adds variance.
Avoid a multi-agent system when:
- The task is a simple deterministic integration you can express as code and rules.
- A duplicate side effect is unacceptable and you cannot design idempotency (some financial or irreversible operations).
- You cannot log inputs/outputs for compliance reasons, and you also cannot build a privacy-safe audit trail.
- The environment is hostile to tool execution (untrusted web browsing, arbitrary code execution) without proper sandboxing.
Security is not theoretical here. Microsoft has published agent-related security research showing how a single page can lead to remote code execution on the host running an AI agent in certain setups (in the context of AutoGen Studio). (microsoft.com) If your agent can browse or execute, you need a threat model, sandboxing, and strict egress controls.
Practical checklist for a durable agent pilot
If you want to ship something real in weeks, not quarters, make these non-negotiable:
- Define a workflow ID and dedupe strategy for triggers.
- Choose a persistence store and retention policy for state and logs.
- Implement idempotency keys for every mutating tool; store receipts.
- Make retries and timeouts explicit per tool; include a terminal error handler path.
- Separate “planning” (LLM) from “doing” (activities/steps).
- Add a manual intervention mechanism: pause, approve, resume, and re-run specific steps.
- Version everything: prompts, tool schemas, policies, and workflow code.
- Decide how you will do redaction and access control in the audit trail.
If you cannot commit to these, it is better to keep it as an assisted tool (a UI that suggests actions) rather than a background automation.
Where Codeversols fits (briefly)
At Codeversols we are usually brought in after the first prototype works, when the question becomes “how do we make this safe, observable, and maintainable”. That is engineering across workflow orchestration, cloud infrastructure, product UX (for approvals and review), and AI integration. If you already have a proof of concept, the quickest win is often not a new agent framework, but putting a durable workflow spine underneath the behaviour you want.
Closing
Agentic automations do not fail because the model is “not smart enough”. They fail because production systems are hostile: retries happen, state gets lost, and side effects are irreversible.
Build the durable layer first—resumable workflows, idempotent tools, explicit retry policy, and an audit trail—and your agent logic becomes something you can safely iterate on, instead of something that wakes up your team at 2am.



