Designing agent tools the model actually calls correctly
When an agent calls the wrong tool or invents an argument, the instinct is to blame the model. Sometimes that is right. More often the tool was badly designed and the model was doing exactly what the schema told it to.
One tool, one job
A tool that searches, filters, paginates and exports is four tools wearing a trench coat. The model has to decide four things at once and will get at least one wrong. Split them. The schema footprint cost is trivial compared to the correction loop you avoid.
The name is the description
Models match on names far more than on prose. search_files with a target parameter that takes files or content is discoverable. query is not. Name the tool after the thing the user calls it, and let the parameters be the modifiers.
Say when NOT to use the tool
Most schema descriptions explain what the tool does. Very few explain what it is for, and the gap is where misuse happens. A line like "use this only for reading files; use patch for edits" removes an entire category of failure, because the model is choosing between tools, not just filling in arguments.
Do not reference other tools by name
If one tool description names another tool, and that other tool is disabled or unconfigured, the model will still be told it exists and will call it. Any genuine cross-reference has to be injected at runtime from the list of tools that are actually available.
Enumerations beat prose
An enum in the schema is a hard constraint the provider enforces. A sentence in the description is a suggestion. Where you can express the valid values as an enum, do it, and let the prose explain what each one means rather than listing what is allowed.
Return what the next step needs
A tool that returns raw data forces the model to spend a turn interpreting it. Returning a compact, pre-shaped summary — plus a pointer to the full data — means the useful thing arrives in the same turn the tool finished. Fewer turns, fewer places to go wrong, and less to pay for.
Errors are part of the interface
An error string that says what went wrong and what to do next is a correction the model can act on. "500 Internal Server Error" gets retried identically. "File not found at path X; check the path or call search_files with target=files to list what exists" gets fixed. Errors deserve the same care as the happy path.