𝗬𝗼𝘂𝗿 𝗔𝗜 𝗔𝗴𝗲𝗻𝘁 𝗪𝗶𝗹𝗹 𝗗𝗼𝘂𝗯𝗹𝗲-𝗖𝗵𝗮𝗿𝗴𝗲 𝗼𝗻 𝗮 𝗟𝗼𝘀𝘁 𝗥𝗲𝘀𝗽𝗼𝗻𝘀𝗲
If your AI agent calls a tool to charge a card and the network drops the response, your agent fails poorly. It double-charges the customer without knowing it.
The money already moved. The agent never heard "ok." It does what every retry loop does: it tries again. It uses the same prompt and the same arguments. This causes a second charge.
A retry is not a network event. It is a decision about a side effect that may have already happened.
Standard retry tools like backoff and jitter make retries polite. They do nothing to stop double-charges.
You need an idempotency ledger. This uses a unique key to ensure an action happens at most once.
There are two ways a tool call fails:
- The request was lost. The action never happened. Retrying is safe.
- The response was lost. The action already happened. Retrying causes a duplicate.
To an agent, these look identical. Both look like a timeout or a dropped connection.
If a tool has a side effect like a payment, an email, or a refund, you cannot rely on simple retries. You must use an idempotency key.
How to fix this:
- Tag your tools. Identify which tools have irreversible side effects.
- Use deterministic keys. Create a stable key based on the workflow ID, the step, and the arguments. Do this before the LLM can change the arguments.
- Use provider keys. If you use Stripe, pass their idempotency key. The provider must recognize the repeat to stop the charge.
- Build a ledger for your own tools. For side effects you own, use a database table with a unique constraint. This ensures your system records the result before it tries again.
Do not mistake "at-least-once" for "exactly-once." In distributed systems, you get "exactly-once" by combining at-most-once delivery with at-least-once retries and a deduplication ledger.
Stop treating writes like reads. Retrying a read is free. Retrying a write costs money.
Source: https://dev.to/0012303/your-ai-agent-will-double-charge-on-a-lost-response-5eed
Optional learning community: https://t.me/GyaanSetuAi