llm-tool-schema-design
verified612a3683-463d-4281-8afe-270a98a962aa
Design tool/function schemas LLMs actually call correctly — naming, descriptions, JSON-Schema params, enums, and error surfaces.
Metadata
Skill file
# LLM Tool Schema Design
Use when you're building the tools an agent/LLM can call and you keep seeing
wrong parameter extraction, confusing similar tools, or invalid calls. The schema
is the *interface contract* the model reads — every word of each description is
input to the model's decision, not just docs for humans.
## The loop, in short
1. Register tool definitions: `name`, `description`, and a JSON-Schema object of
parameters (properties, types, required, enums).
2. Send the user question + the tool list to the LLM.
3. The LLM either answers or emits `{tool_name, arguments}`.
4. Your code validates & executes the tool, returns the result to the LLM.
5. Repeat until the LLM produces a final answer.
## Name and scope well
- **One clear purpose per tool**: not so broad it's ambiguous, not so narrow you
litter the space. Prefer `get_calendar_events(date_or_range)` over
`get_calendar_events_today` / `_tomorrow` / `_next_week`.
- **Semantically differentiate overlapping tools**: if two tools look alike, the
model confuses them. Explicitly annotate boundary conditions — e.g. in
`search_products`'s description: *"Use only for product search; for order
status call get_order_status."* Research shows tool-selection accuracy drops as
the tool count grows, so keep the set lean.
## Descriptions are the primary signal
- Write *what* the tool does and *when* to use it (so the model picks it
correctly) — include a concrete example value in descriptions if helpful
(e.g. `"Search keywords, such as 'wireless Bluetooth headphones'"`).
- **Consistent naming across the toolkit**: if one tool uses `user_id`, another
`userId`, and a third `uid`, the model struggles to map them to the same
concept. Standardize parameter names.
- Include **units and formats** for numeric/date params so the model emits
parseable values rather than guesses.
## Parameters: constrain so the model can't fail
- **Use `enum` for discrete values**: explicitly enumerate valid options. This
prevents invalid values AND shrinks the model's decision space, improving
selection accuracy.
- **Keep `required` minimal**: every required field is a place the model can fail
if it can't extract or infer the value. Make optional what you can defer or
default.
- Define types precisely (`string` vs `integer` vs `array` of `string`) and add
`description` per property, not just per tool.
- Consider **output/error structure too**: a tool that returns `{status, data,
error, stable IDs}` lets the model act on the result and recover from failures
instead of flailing.
## Error & retry behavior
Give tools a structured error surface so the model can react: a stable `status`
field, a machine-usable `error` code, and where possible a "next step" hint. A
tool that returns a bare exception string often makes the model retry blindly or
hallucinate the cause. Return the failure in a shape the model can reason about.
## Pitfalls
- Omitting per-parameter descriptions → the model guesses field meanings.
- Two tools whose descriptions are so similar the model can't tell them apart.
- `required` fields the model can't reliably infer, causing spurious failures.
- No enums on finite-value params, letting the model emit free-text garbage.
- No structured output/error → the model can't adapt when a call fails.
- Letting the tool count balloon; the selection error rate climbs with it.
## Verify
- On a representative set of user requests, measure the tool-selection accuracy
and parameter-extraction correctness (how often args are valid & well-formed).
- Confirm a crafted wrong-param or failure case is handled gracefully (model
recovers via the error surface).
- Show enums/format constraints eliminate invalid-value calls.