Safe repeated intent
AI Agent Idempotency and Retry Safety
Prevent repeated business effects with stable intent identifiers, destination contracts, concurrency checks and explicit treatment of unknown outcomes.
An agent should be able to recover from a lost response without unintentionally repeating a business action. Idempotency is the contract that makes repeated requests for the same intended operation behave as one logical operation within a defined boundary. Retry safety also requires knowing when the original outcome is uncertain, whether the intent changed and which system enforces the contract.
This guide uses a repair-part reservation to explain the boundary. It is for engineers and AgentOps owners whose agents reserve stock, create work items or perform other external writes. It does not promise universal exactly-once execution across independent systems.
A timeout does not answer the business question
In the illustrative workflow, an agent requests a reservation of two replacement filters for repair job PR-62. The inventory service creates reservation RSV-91, but the response is lost. The agent sees a timeout and issues a new request with a new identifier. If the destination treats that as a new intent, it can reserve another two filters.
Both network attempts may be individually valid. The business defect is that one reservation intent created two effects. Logging the requests or asking the model to “avoid duplicates” does not enforce the required relationship at the inventory boundary.
The agent needs a stable identifier for the reservation intent and a destination contract that recognises repeated use of it. It also needs a status lookup or equivalent reconciliation method. A successful model response saying “reserved” is neither the enforcement mechanism nor the evidence of the final stock state.
Define what counts as the same intent
The key should identify the business operation, not a model invocation, network attempt or arbitrary fresh UUID generated on each retry. Persist it before the first execution attempt and propagate it through the relevant action path. Keep a separate attempt identifier for tracing each transmission.
For PR-62, the original intent includes the repair job, part identity, quantity, stock location and applicable reservation revision. Changing from two filters to three is a new business request or an explicitly supported amendment. Reusing the old key with changed parameters should not silently return an unrelated success.
The AWS Builders' Library discussion of idempotent APIs explains caller-provided request identifiers, repeated intent and parameter mismatch handling. The important design decision for an agent is the scope of that intent; an opaque key alone does not make an operation safe.
Avoid placing personal or commercially sensitive values directly in visible keys. An opaque identifier can reference an authorised intent record. Scope it by tenant or caller where required so one customer's request cannot collide with another's. Document the rule instead of relying on a convention known only to one developer.
Write the destination contract before adding retries
| Contract question | Required behaviour | Evidence to test |
|---|---|---|
| Same key, same parameters | Return or resolve the same logical reservation under the documented contract. | Repeated requests link to RSV-91 without extra stock reservation. |
| Same key, changed parameters | Reject the mismatch or use an explicit amendment contract. | Quantity two cannot silently become quantity three. |
| Concurrent requests | Arbitrate the intent consistently at the effect boundary. | Parallel attempts cannot both create independent reservations for the same intent. |
| Unknown outcome | Provide status or a defined reconciliation route. | A timeout can be resolved without assuming no effect. |
| Retention expiry | State how long deduplication evidence remains valid. | A late retry follows the documented expiry rule. |
| Partial completion | Expose the known state of the logical operation. | Stock reservation and notification are not confused. |
Ask the destination owner to confirm the contract and test it in a representative environment. A client library accepting an idempotency field does not prove the downstream service honours it. Check scope, retention, concurrency and failure behaviour, including whether a proxy strips or replaces the identifier.
Close the gap between deduplication and the effect
A local “seen keys” table can reduce duplicate attempts, but it can also create dangerous gaps. If the client records a key as complete before the reservation occurs, a crash can suppress needed work. If it records completion afterwards, a crash between the reservation and local record can permit a duplicate.
Where the destination can atomically associate the intent record with its effect, that boundary can offer a stronger guarantee. Where separate systems cannot do that together, design for ambiguity and reconciliation. Do not describe a local lock as a universal exactly-once guarantee over an independent inventory service.
Concurrent workers need more than a preflight read. Two workers can both observe “not seen” before either writes. Use a destination-supported uniqueness or transaction mechanism where applicable, and test the actual race. A sleep or random delay changes timing; it does not establish the required invariant.
Keep retries within a classified failure policy
Separate failures known to occur before acceptance, failures with an ambiguous effect and final business rejections. A transient transport problem may be retryable under the idempotency contract. An invalid part identifier needs correction. Insufficient stock may require an alternative decision, not repeated identical requests.
Use bounded attempts, elapsed-time limits and backoff appropriate to the service contract. Avoid multiplying retries at every layer: the agent, SDK, gateway and worker may each retry without knowing the others have done so. Record effective attempts across the path and respect destination rate controls.
Cancellation has similar ambiguity. If a reservation request is already accepted, stopping the agent does not establish that stock was released. A release-reservation operation is a separate business action with its own authority and repeated-request behaviour.
The runtime cost-control guide covers shared attempt and resource budgets. Budget enforcement limits repetition, while idempotency governs the business effect. One cannot replace the other: a cheap duplicate can still be operationally harmful.
Treat multistep work as several accountable effects
A repair workflow may reserve stock, create a collection task and notify a technician. Give each operation an explicit identity and relationship to the parent task. Successful reservation does not imply successful notification, and repeating the whole workflow can unnecessarily recreate completed steps.
Persist confirmed step outcomes and resume from a known state. If a later step fails, decide whether to wait, retry that step or perform an authorised compensating action. Releasing stock after notification failure may be inappropriate if the technician has already collected it; inspect the actual business state.
Use incident recovery when the workflow needs reconciliation across systems. A compensating action should be recorded as a new event, not treated as erasing the original. This is especially important when one effect is reversible and another, such as a delivered message, is not reliably reversible.
Revalidate authority without inventing a new intent
A retry may occur after permission, approval or stock conditions have changed. The destination should still enforce the current applicable action policy. A stable intent key is not a capability token and should not bypass revoked access or an expired approval.
Distinguish retrieving the result of an already executed authorised operation from authorising a new effect. The access needed to inspect RSV-91 may differ from the permission to create a reservation. Agent action controls should define both, including the identity on whose behalf the agent acts.
If the approved quantity changes, create an explicit amendment or a new approved intent rather than laundering the changed request through the original key. Preserve the relationship for audit and reconcile any existing reservation before adding or releasing stock.
Test the failure windows that matter
Run tests where the destination succeeds but the response is lost; where two workers submit concurrently; where a late retry arrives after retention expiry; and where the same key carries changed parameters. Also test a crash after each state transition and a callback that arrives after the caller has stopped waiting.
Verify destination stock state and logical reservation count, not just HTTP responses. A test that sees a conflict response on the second call may still need to prove that only the intended quantity is held. Record the precise scope of any guarantee demonstrated by the test.
Use task and attempt tracing to connect the business intent, each attempt and destination reference. The useful investigation question is “which effects belong to this intent?” rather than “how many times did the model call a tool?” Keep identifiers stable across recovery and deployment transitions.
Make key retention discoverable to operators who may replay work days later. The recovery interface should show whether the original deduplication protection is still valid, rather than offering an undifferentiated retry button. If the retention window has passed, require the documented reconciliation decision before a new attempt. Preserve the original intent relationship even when a new authorised operation becomes necessary.
Make retry safety part of handover evidence
Ask the delivery team for the key-creation rule, destination contract, retention rule, concurrency tests, status-lookup path and treatment of ambiguous outcomes. Include the behaviour when the destination does not support idempotency. In that case, a constrained manual confirmation path may be necessary for consequential writes.
Connect the design to versioning and rollback so restoring older internal state cannot silently generate fresh keys for already executed intents. Rehearse replay using the actual stored records. The presence of a retry loop is not evidence that recovery is safe.
Discuss AI agent retry and idempotency design with one masked write operation, its destination API contract and a failure case with an unknown outcome. The practical goal is a documented boundary where repeated intent is handled predictably and uncertainty remains visible.
FAQ
Your questions, answered.
Should an agent generate a new idempotency key for each retry?
No, not when it is retrying the same intended business operation under a destination idempotency contract. Persist the intent key before the first attempt and reuse it with the same relevant parameters. Keep separate attempt identifiers for tracing. A genuinely changed request needs an explicit amendment or a new authorised intent.
Is a local deduplication table enough to prevent duplicate actions?
It can reduce duplicates but does not automatically close the gap between recording intent and executing an external effect. Crashes and concurrent workers can expose that gap. Prefer destination-supported enforcement where available, and design a status and reconciliation path where atomic coordination across systems is unavailable.
What should happen if the same key has a different quantity?
The contract should reject the parameter mismatch or route it through an explicit amendment operation. Do not silently return the old result as if it satisfied the changed request. Preserve the relationship between the original reservation and the revised intent, and revalidate the authority and stock state before creating another effect.
Can a retry remain unsafe after the first operation succeeded?
Yes. The deduplication record may have expired, the key may not cover all downstream steps or the caller may accidentally create a new intent. Verify the actual destination contract and retention period. Retrieve the existing result where possible and reconcile uncertain state rather than assuming every repeated request is protected.
Does idempotency replace approval and access control?
No. It governs repeated intent, not permission to act. A retry must respect the applicable authority and approval conditions, while retrieving a previous result may require a different permission from creating a new effect. A stable key must not become a way to bypass revoked access or changed business scope.
How should an agent retry a multistep workflow?
Track each external effect with its own identity and confirmed state, linked to the parent business task. Resume only the appropriate unresolved step. Do not repeat the whole workflow by default. If compensation is needed, treat it as a separately authorised action and verify current destination state before executing it.