Skip to main content

The model retries

The tool loop runs up to six steps per turn. A malformed reply, a network hiccup or the model simply repeating itself can all produce the same call twice. If that call places an order, twice is a real order too many.

Idempotency you inherit

The platform routes side-effecting calls through an execution ledger keyed on (company, conversation, tool_call_id). A repeat returns the stored result without reaching your server.

How the platform decides

By name. A tool counts as side-effecting when its name starts with, or contains, one of:
This is a heuristic, and it is your job to work with it. Name a mutating tool finalise_basket and it will not be treated as one — the ledger will not protect it, and a retry will run it twice.Name anything that changes state with one of the verbs above. If that is impossible, make the operation idempotent on your side.

Be idempotent anyway

The ledger protects one conversation. It does not protect against a customer saying “yes” twice in two conversations, or a retry after a network failure where you committed and the response never arrived.
1

Derive a key from the request

Buyer plus cart contents, or an explicit token you issued earlier.
2

Return the existing result

A repeat should return the original order, not a conflict.
3

Commit before you reply

A tool that answers before committing turns a 10-second timeout into a silent data-loss bug.

Confirmation is the assistant’s job, not yours

The assistant is instructed to take an action that changes something only after the customer has clearly confirmed it. Your server should still refuse what it should not do — an instruction is not an authorisation.