Treat each tool call as an untrusted action request. Validate schema, identity, permission, business rules and idempotency before execution. Return structured results and cap the loop by turns, time, cost and action risk.
Production loop
Model requests a tool
Claude returns a structured tool-use block containing the tool name and arguments.
Application validates the request
Check the schema, caller identity, permissions, entity state, amount limits and approval requirements.
Executor runs once
Use an idempotency key so retries cannot duplicate a payment, order or message.
Application returns a tool result
Return a typed success or error with safe fields the model can use for the next step.
Loop stops at a defined boundary
Stop on completed outcome, user approval request, terminal error or exhausted budget.
Worked example: approve a supplier invoice
A fictional accounts-payable agent receives “Approve invoice INV-2048 for $12,400.” It can read invoices and request approval. It cannot release payment.
Tool contract
name: request_invoice_approval
required: invoice_id, amount_usd, cost_centre, evidence_ids
server checks: caller role, invoice status, amount match, vendor match, duplicate request
side effect: create approval task only
| Stage | Input or state | Control | Outcome |
|---|---|---|---|
| 1. Read | INV-2048 shows $12,400 and vendor V-77 | Read-only invoice tool | Evidence IDs E1 and E2 returned |
| 2. Request | Claude asks for approval with matching values | Strict schema accepts shape | Request moves to business validation |
| 3. Validate | Invoice is open; amount and vendor match | Policy requires finance approval above $10,000 | Human approval task created |
| 4. Resume | Finance approver accepts task A-901 | Signed approval token linked to invoice | Agent reports approved for downstream payment |
| 5. Stop | Payment tool is absent from the agent allowlist | Least privilege | No payment can be released by this loop |
Error path
If Claude requests $12,450, the application returns a typed AMOUNT_MISMATCH error with the recorded amount of $12,400. Claude may repair the request once. A second mismatch stops the loop and routes the case to a person.
Controls at each boundary
| Boundary | Required control | What it prevents |
|---|---|---|
| Tool definition | Specific name, description, strict schema and narrow purpose | Ambiguous selection and malformed arguments |
| Authorisation | Caller identity, role and task-scoped allowlist | Capability escalation |
| Business validation | Live entity, state, limits and policy checks | Valid JSON that requests an invalid action |
| Execution | Idempotency key, timeout and transaction boundary | Duplicate or partial side effects |
| Error handling | Typed recoverable and terminal errors | Blind retries and invented fixes |
| Loop budget | Maximum turns, tool calls, elapsed time and cost | Runaway loops |
| Trace | Model version, inputs, calls, results and approvals | Unexplained production actions |
Stop conditions belong in code
- Return success when the defined business outcome is complete.
- Pause when a required human approval is missing.
- Stop immediately on permission failure, policy denial or unsafe content.
- Allow a small fixed number of retries for transient or repairable errors.
- Stop when the time, token, cost or tool-call budget is exhausted.
Public sources
- Anthropic: tool use overview
- Anthropic: implement tool use
- Anthropic: strict tool use
- Anthropic engineering: advanced tool use
Related Timo Labs guides
Prepare for Developer Foundations
CCDV-F is the certification track for engineers building Claude applications and agents.
View CCDV-F