Same topic, related formats. Practice these next.
Same topic, related formats. Practice these next.
Explain why idempotency matters for safe retries in an agent. Give one concrete example of a non-idempotent tool and the failure that occurs when the agent retries it after a transient error.
A timeout is ambiguous, so a blind retry can repeat a side effect. Idempotency makes the repeat harmless; idempotency keys are the standard fix for payments and sends.
Imagine you text a friend to pay back ten dollars, but your phone says 'failed to send' even though it actually went through. If you resend it, your friend gets paid twice. The trouble is you cannot tell whether the first one really worked. An agent calling a tool over the network has the same problem. When it gets a timeout, it does not know if the action happened or not. If it just tries again, it might charge a card twice or send the same email twice. The clean fix is to attach a unique sticker to each request. The server remembers the sticker, so when it sees the same one again it says 'I already did this' instead of doing it a second time. That makes trying again safe even when you cannot tell what happened.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
Define idempotency, explain why a timeout is ambiguous about commit, walk the double-charge failure end to end, then present idempotency keys scoped per action, the transient versus definite error split with backoff, and the at most once fallback for tools that cannot be keyed.
import uuid, time, random
def call_tool_with_retry(tool, args, max_attempts=4):
# One key per LOGICAL action, reused across all retries.
key = str(uuid.uuid4())
for attempt in range(max_attempts):
try:
return tool(args, idempotency_key=key)
except TransientError: # timeout, 503, connection reset
if attempt == max_attempts - 1:
raise
time.sleep(2 ** attempt + random.random()) # backoff + jitter
except ClientError: # definite 4xx: never retry
raise| Aspect | Idempotent tool | Non-idempotent tool |
|---|---|---|
| Examples | Read, GET, upsert by id | Charge card, send email, append row |
| Effect of a blind retry | Harmless, state unchanged | Duplicate side effect |
| Retry policy | Retry freely with backoff | Retry only with an idempotency key |
| Fallback when key is impossible | Not needed | Human approval or compensating action |
Real products, models, and research that use this idea.
What an interviewer would ask next. Try answering before peeking at the approach.
Red flags and common mistakes that signal junior thinking. Click to expand.
Retrying every failed tool call the same way. A timeout on a payment or send is ambiguous, so a blind retry can duplicate the side effect even though the first attempt already succeeded.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.