When an agent call times out, the natural reaction is to try again. Sometimes that is exactly right. A network packet may have been lost and the provider may never have seen it. Sometimes the provider completed the action and only the response was lost. Retrying blindly is how one customer gets three emails or one payment gets attempted twice.
Classify the failure first
A temporary network error, rate limit, or provider overload may be worth retrying. A permission failure, invalid record, or rejected business rule usually is not. A timeout sits in the uncomfortable middle: you do not know whether the request happened. Treat it as an uncertain outcome and use the provider request ID or an idempotency key to find out before acting again.
Back off instead of banging on the door
Use exponential backoff with jitter and a maximum attempt count. Set a deadline for the whole task, not just each individual call. Keep the retry policy near the tool or workflow that understands the operation; a generic retry wrapper cannot know whether sending a message is safe to repeat.
Give up usefully
When the limit is reached, move the job to a visible failed or needs-review state. Tell the person what is known, what is uncertain, and whether they can safely try again. Preserve the request ID, previous responses, and attempt history so an operator does not recreate the same side effect while investigating.
Recovery is part of the feature. Test a provider that succeeds after your client times out, a worker that crashes after a write, a queue that delivers twice, and a user who clicks retry twice. A good recovery design makes the safe action the easy action.