Vault / wiki/201/tool-design-principles.md
updated 2026-05-28Tool Design Principles
The single biggest predictor of agent quality is tool design, not model choice. The cert tests this hard.
1. Make tools obvious
- One tool, one job. If a tool's description has "or" in it, split it.
- Name the tool by verb + object:
search_tickets, nottickets. - Description = a teacher's note: "Use this when... Don't use this when..."
2. Constrain inputs
- Use enums for fixed vocabularies.
- Require only the fields that must be present. Optional > required.
- Default values reduce hallucination.
- Validate at the boundary — return clear errors if input is invalid.
3. Return structured, focused output
- Prefer JSON or short structured text over walls of prose.
- Include only what Claude needs to make the next decision.
- Long blobs → return a
resourceURI Claude can fetch if needed. - Include provenance (IDs, timestamps) so Claude can refer back.
4. Idempotency & safety
- Mark destructive tools with
destructiveHint: true. - Mark idempotent tools with
idempotentHint: true— Claude can retry without fear. - For non-idempotent writes (sending a message, charging a card), require a
confirm: trueargument and a user confirmation in the host.
5. Errors are first-class
- Return
is_error: truewith a useful message — Claude reads errors and adapts. - Distinguish:
- User error (bad input) → "ValidationError: customer_id must be UUID"
- Transient (network, rate limit) → "TransientError: retry after 5s"
- Permanent (resource gone) → "NotFoundError: ticket 1234 deleted"
- Never raise an unstructured exception that bubbles up as a stack trace — the model can't reason about that.
6. Composability
Design tools so Claude can chain them:
find_customer→ returnscustomer_idget_customer_orders→ takescustomer_idrefund_order→ takesorder_id, requiresconfirm
This is more flexible than one mega-tool find_and_refund(query).
7. Limit blast radius
- Read tools should be safe defaults.
- Write tools should be narrow (
create_ticketnotmodify_anything). - Sensitive ops (delete, transfer, refund) should require explicit confirmation flow.
8. Test descriptions like prompts
Description quality drives tool-selection accuracy. Iterate:
- Run 20 sample queries through Claude with your tool list.
- Track which queries triggered the right tool.
- Edit descriptions where it picked wrong; re-run.
CCA-F cheatsheet
| Bad | Good |
|---|---|
do_stuff | update_ticket_status |
| "Handles tickets" | "Update a ticket's status field. Use when the user confirms moving a ticket to a new state." |
args: {...freeform} | Typed schema with enums and required fields |
| Raises Python exception | Returns {is_error: true, code: "...", message: "..."} |
| Returns 20KB JSON dump | Returns top fields + a resource URI for details |