Idempotency for AI agents: preventing one instruction from becoming three actions
Retries, duplicated messages and uncertain tool outcomes can multiply an agent’s effects. Idempotency turns a logical action into one controlled business operation.
Architecture & engineering, Evaluation & assurance Agent systems
A user tells an agent to refund one invoice. The agent calls the payment tool, the connection closes before a response, and the model decides to try again. A queue also redelivers the original task after its acknowledgement is lost. The instruction was singular; the system now has three opportunities to move money.
Idempotency is the property that makes those repeated attempts resolve to one intended effect. It is not a prompt instruction such as “do not repeat yourself.” It is an agreement across workflow state, tool contract and target system about the identity of the business action.
Define the logical action before the request
Start by describing what “the same action” means in the workflow. For a refund, it might be:
Refund invoice INV-402’s approved refundable balance under approval AP-91.
That identity should not depend on the model’s wording, a transient tool-call ID or the time of an attempt. Derive or assign a stable idempotency key when the action becomes authorised, then reuse it for every retry of that exact action.
A useful key binds:
- workflow and step identity;
- target business object;
- operation type;
- material parameters such as amount and currency;
- approval or mandate version; and
- a sequence or revision when the business allows multiple distinct actions.
If the amount changes, it is a new action, not a retry. The old approval and key should not authorise it.
Understand what HTTP does—and does not—promise
RFC 9110 defines a method as idempotent when multiple identical requests have the same intended server effect as one. It identifies PUT, DELETE and safe methods as idempotent and explains that this property permits automatic retry after a communication failure.
Two cautions matter for agents. First, POST is not idempotent by definition, though an application can give a particular POST operation idempotent semantics. Second, method semantics cover the requested effect, not every implementation side effect; a server may still log each request separately.
The application must therefore verify the target API’s contract. A PUT /refunds/INV-402 may still be wrong if the target allows several refunds per invoice or forwards calls to a non-deduplicating payment provider. Conversely, a POST endpoint can be safe to retry if it accepts a stable idempotency key and returns the original result for repeats.
Put an effect ledger in the action path
Before sending a consequential operation, write an effect record:
| Field | Example |
|---|---|
| Logical action key | refund:INV-402:AP-91:v1 |
| State | prepared, dispatched, confirmed, ambiguous, compensated |
| Authorised parameters | amount, currency, destination and expiry |
| Attempt history | request ID, time, worker and response |
| External reference | provider transaction or resource ID |
| Verification | authoritative end-state query and timestamp |
| Outcome | one accepted business effect or unresolved exception |
Enforce a uniqueness constraint on the logical key. Competing workers should converge on the same record rather than each creating a new action. When possible, commit task completion and the durable effect outcome in one transaction or use an outbox/inbox pattern so a crash cannot silently separate them.
Workflow research such as ExoFlow shows why durable logging and coordinated checkpoint/recovery are central to exactly-once workflow goals. External services remain outside a local transaction, so “exactly once” is usually a system property built from deduplication and reconciliation, not a magical delivery guarantee.
Make retry policy a tool property
The model should not improvise whether an error is retryable. Put semantics in the tool contract:
- Safe retry: same key and parameters may be sent again.
- Reconcile first: the operation might have happened; query authoritative state before retry.
- Compensate: a partial effect requires a defined reversal or follow-up.
- Do not retry automatically: the action lacks deduplication or has irreversible consequences.
- Escalate: a person or system owner must resolve ambiguity.
Treat timeouts, connection resets, 5xx responses, invalid responses and business rejections differently. A timeout means no response arrived; it does not mean no effect occurred. A validation rejection may be terminal for those parameters. A rate limit may be safely retryable after a server-provided delay if the logical key remains the same.
RFC 9458, in its replay-risk discussion, notes that connection failures are not sufficient evidence that processing did not occur and that even combinations of individually idempotent requests may not be idempotent. That is a useful warning for multi-step agent plans: deduplicating each call does not automatically make the whole business workflow safe.
Reconcile against business state
After an ambiguous result, ask the target system what exists. Prefer lookup by the same idempotency key or external request ID. If that is unavailable, use a business key and compare all material fields. Do not ask the model to infer success from a confirmation-like message.
The reconciliation outcome should be one of:
- the intended effect exists exactly once—record its reference and continue;
- no effect exists—retry if the contract permits;
- a mismatched or duplicate effect exists—stop and escalate or compensate; or
- state cannot be determined—remain ambiguous and prevent further action.
That last state is uncomfortable but honest. It is safer than turning uncertainty into another payment, message or deletion.
Protect approval from replay
An approval should bind to the logical action, not merely to a chat turn. Store the approved parameters and evidence version with the effect record. Expire approval when its time, target or assumptions change. Mark it consumed or linked to the confirmed effect while retaining the audit record.
If a workflow branches, prevent two branches from using the same approval for different actions. If the user repeats the request after completion, show the existing outcome and require a new, distinguishable mandate for another effect.
NIST’s tool-use work highlights that tools differ by write access, reversibility, reliability and statefulness. Use those attributes to decide how strong an idempotency and approval design each tool needs.
Test duplication deliberately
Run the same logical action through failure injection:
- deliver the task twice concurrently;
- drop the tool response after the external effect;
- crash after dispatch but before recording the result;
- crash after recording the result but before acknowledging the queue;
- return a late success after the workflow has retried;
- change a material parameter while retaining the old key;
- expire the approval between attempts; and
- replay a completed request weeks later.
Assert external business state, not only local logs. The pass condition is one intended effect, one reconciled outcome and a complete record of every attempt. Also test the opposite: two genuinely distinct approved actions must not be collapsed because the key was too broad.
Use a release checklist for every write tool
Before giving an agent write authority, confirm:
- the logical action has a stable identity;
- same-action retries reuse that identity;
- changed actions cannot reuse approval or key;
- duplicates are rejected or return the prior result;
- ambiguous effects enter reconciliation, not blind retry;
- external state can be verified independently;
- compensation or escalation exists where deduplication does not;
- late and reordered messages cannot reopen completed work; and
- fault tests prove the behaviour under concurrency and restart.
Idempotency is not glamorous, but it separates a tool demo from an operable system. The model can decide that a retry is desirable; the architecture must ensure that retry does not turn one human instruction into three real-world effects.