---
title: "Make tools that change things safe to · Agent Wranglers"
url: https://agentwranglers.se/playbook/ai-features/structured-output-and-tools/idempotent-tools
updated: 2026-10-20
licence: "All rights reserved"
---

# Make tools that change things safe to repeat

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Structured output and tools](https://agentwranglers.se/playbook/ai-features/structured-output-and-tools)
- Rule: Give every tool that creates or changes data an idempotency key, so a repeated call has no extra effect.
- How: Models and retry logic both repeat calls. A model that repeats itself sends a new tool call ID, so the ID alone is not enough. Derive the key from the conversation and the thing the call acts on, such as the order line. Store the key with the result and return the stored result on a repeat. The [idempotency keys rule](https://agentwranglers.se/playbook/api-design/reliability/idempotency-keys) shows the server side. Tools that pay, send or delete also need [a person's approval](https://agentwranglers.se/playbook/adversarial-testing/ai-agents-and-models/human-approval).
- Check: A test calls `create_return` twice for the same order line, with two different tool call IDs. One return exists, and both calls get the same result.

Example:

```ts
async function createReturn(args: ReturnArgs, ctx: ToolContext) {
  const key = `${ctx.conversationId}:${args.orderNumber}:${args.lineId}`;
  return idempotent(key, () => returns.create({ ...args, customerId: ctx.user.id }));
}
```

```python
def create_return(args: ReturnArgs, ctx: ToolContext) -> dict:
    key = f"{ctx.conversation_id}:{args.order_number}:{args.line_id}"
    return idempotent(key, lambda: returns.create(**args.model_dump(), customer_id=ctx.user.id))
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers ai features playbook: https://agentwranglers.se/playbook/ai-features/structured-output-and-tools/idempotent-tools`.

- Previous: [Return errors the model can act on](https://agentwranglers.se/playbook/ai-features/structured-output-and-tools/tool-errors-for-models)
- [Structured output and tools](https://agentwranglers.se/playbook/ai-features/structured-output-and-tools)
