Idempotency for AI Agents

- Published on

Idempotency for AI Agents
An agent calls a tool to issue a refund. The request times out.
The transcript contains no success response, so the agent tries again. The second call succeeds. Later, the system discovers that the first call succeeded too.
The model did something reasonable. The architecture did something expensive.
This failure is not unique to AI. Distributed systems have dealt with retries, lost acknowledgements, duplicated messages, and partial failure for decades. Agent systems make the problem easier to trigger because retries are often chosen through natural-language reasoning inside long-running loops. The agent sees uncertainty and tries to help. Without a strong operation contract, “try again” can become “do it twice.”
Idempotency is one of the unglamorous ideas agent engineering needs to relearn quickly.
An idempotent operation can be attempted more than once without changing the final effect beyond the first successful application. Reading a file is naturally idempotent. Setting a preference to a specific value can be designed that way. Sending an email or charging a card usually is not unless the system adds a stable identity and deduplication behavior around the action.
Long-running agents are only as dependable as their behavior at this boundary.
Retry Is a Systems Decision
Models are good at interpreting an error and proposing a next step. They should not have to invent retry semantics from an error string.
“Request timed out” does not mean “nothing happened.” It means the caller did not receive a complete response before its waiting period ended. The remote system may have rejected the action, completed it, or still be processing it.
Those states demand different behavior.
If nothing happened, retry may be correct. If the action completed, retry may duplicate it. If the outcome is still pending, retry may race the first request. The correct next step is often reconciliation: query the system of record using the identity of the original operation.
The tool layer should expose this distinction. A generic error leaves the agent to guess. A structured result such as not_started, completed, pending, rejected, or outcome_unknown gives orchestration something dependable to act on.
Retries should be governed by the operation's contract, not by the model's optimism.
Give Every Consequential Intent an Identity
Idempotency begins before the tool call.
The system needs a stable identifier for the intended business operation: refund this order by this amount, create this ticket for this incident, publish this version to this environment. That identity must survive process restarts, model changes, and retries.
An idempotency key should represent the intent, not the attempt. If each retry generates a new key, the receiver sees several independent operations and correctly performs all of them.
The key can be created by the harness when the consequential step enters the workflow. It is stored with the task state and supplied on every attempt. The receiving service records the first accepted result and returns that same result when the key appears again.
The exact implementation varies, but the invariant is simple:
One authorized intent has one durable operation identity, no matter how many times the transport is attempted.
That identity also improves observability. A team can trace the proposal, approval, attempts, remote effect, and final verification as one operation instead of reconstructing them from loosely related tool calls.
Idempotency Is More Than Deduplication
Dropping duplicate requests is useful and incomplete.
The system also needs to ensure that repeated calls describe the same operation. Suppose an agent retries a refund key but changes the amount after reading new context. The receiver should not return the old success as if the new request were equivalent. A key should be bound to canonical parameters, and conflicting reuse should fail loudly.
There is also a timing question. How long does the receiver retain the result associated with the key? If the record expires while the workflow can still retry, duplication becomes possible again. Retention needs to match the life of the business risk, not only the normal request timeout.
Finally, idempotency does not make every sequence atomic. An agent may update a database, send a message, and publish an event. Making each step individually idempotent does not guarantee that all three occur together. The workflow still needs state, recovery, and possibly compensating actions.
Idempotency narrows uncertainty. It does not abolish distributed systems.
Classify Tools by Retry Safety
The agent harness should know which tools are safe to repeat.
I find four practical classes useful.
Read operations can usually be repeated, though freshness and rate limits still matter.
Set operations move a resource toward a declared state, such as setting a feature flag to off. They are often naturally idempotent when the target state is explicit.
Create or effect operations produce a new event, record, payment, message, or external consequence. They require an operation identity or a reconciliation strategy.
Unknown operations come from tools whose semantics are incomplete or whose provider cannot confirm the result. These should receive the most conservative retry policy.
Expose the classification in the tool contract. The orchestrator can automatically retry a read with bounded backoff, reconcile an effect operation, and stop for human review when an unknown action may have created a consequence.
This is safer than relying on the model to infer from names like submit, apply, or run.
Long-Running Loops Increase Duplicate Pressure
A short interactive session has one process and a human nearby. A long-running agent workflow can cross many failure boundaries.
The worker can restart. Context can compact. A task can move to another machine. An approval can arrive hours later. A monitoring loop can decide that no progress occurred and start replacement work. Two agents can receive the same assignment after a queue visibility timeout.
Each transition creates pressure to repeat an action whose outcome is not visible in the current context.
Durable task state should record more than “step started.” It should record the operation identity, intended parameters, authorization, attempt history, last known remote state, and evidence required to close the step. A replacement worker begins by reconciling that record. It does not translate an absent success message into permission to start over.
This is why external state matters in long-running AI work. The loop can persist safely only when it remembers effects outside itself.
Completion Requires Reading the Resulting State
A successful HTTP response is evidence about a request. It is not always evidence about the desired outcome.
After a consequential action, verification should read the resulting state from an authoritative source. Did the payment ledger record one refund for the approved amount? Is the deployed artifact actually serving? Does the ticket exist with the expected ownership? Was the message accepted by the delivery system?
This closes the gap between transport success and business success.
It also allows recovery from ambiguous responses. If the action timed out but the resulting state exists, the workflow can mark the operation complete without retrying. If the receiver acknowledged the request but the expected state never appears, the system can escalate or compensate.
Agent completion should be based on observed effects, not the emotional tone of a tool response.
Approval Should Be Consumed Carefully
Idempotency and human approval meet at the operation identity.
A person approves a particular action with particular parameters. That grant should be bound to the same identity used for execution. Retries of the same operation remain inside the grant. A changed amount, target, or artifact creates a different intent and requires a new decision.
For one-time operations, the approval can be marked consumed when the receiver accepts the identity. If the outcome is unknown, the workflow reconciles before deciding whether another attempt is permitted. It does not spend the same human decision on several logically different effects.
This makes “approved once” precise. The human authorized one operation, not an unlimited retry loop.
Design Tools for Boring Recovery
The most reliable agent tool is not the one with the most natural description. It is the one whose failure behavior is difficult to misunderstand.
A consequential tool should ideally support:
- a caller-supplied operation identity
- canonical request parameters
- a way to query operation status
- explicit terminal and nonterminal outcomes
- a documented retention period
- safe handling of conflicting key reuse
- a durable receipt suitable for verification
If an external API does not provide these features, the agent platform can place a wrapper around it. The wrapper stores the operation before the external call, serializes attempts, checks for known results, and exposes reconciliation as a first-class action.
This is more engineering than passing an API schema to a model. It is also what lets the model operate without being responsible for the laws of distributed execution.
Test the Lost Acknowledgement
Happy-path tests rarely reveal duplicate effects.
Evaluations should deliberately interrupt the workflow at uncomfortable moments: after the remote service commits but before the response returns, after the tool returns but before task state is saved, while two workers believe they own the step, and after the idempotency record expires.
The expected behavior is not merely “the agent eventually finishes.” It is “the intended effect occurs exactly once, or the workflow stops with an explicit unresolved state.”
That second outcome is important. When the architecture cannot determine whether a consequence occurred, honesty is safer than another guess.
Autonomy Depends on Repeatable Effects
The more persistent an agent becomes, the more often it will encounter failure without a human watching the exact moment. Retries are inevitable. Duplicate consequences are not.
Give consequential intent a durable identity. Bind that identity to parameters and approval. Classify tool retry safety. Reconcile ambiguous outcomes. Verify resulting state. Test the moments where acknowledgements disappear.
These practices are ordinary distributed-systems discipline. In agent engineering, ordinary discipline is what makes extraordinary capability safe to keep running.