The most common cause of an agent "not using tools well" isn't the model -- it's that the tool is poorly described, poorly named, or the tool set is too large for the model to pick precisely.
The model doesn't see your code -- it sees the tool's name, description, and schema. Everything it knows about when and how to use it comes from that text. A generic name like `process` or a one-line description that only says what the function does, without saying *when* to use it, leaves the model guessing.
On recent models, which tend to be more conservative about invoking tools, being explicit about the activation criterion in the description (not just in the general system prompt) gives a measurable improvement in correct invocation rate.
A schema that only says `"type": "string"` for a field that actually only accepts 5 possible values leaves too much room for the model to invent variants. Use `enum` whenever the set of valid values is finite and known.
Marking `required` precisely matters as much as `enum`: if a field is optional but you mark it as required, the model will invent a value when it doesn't have one, instead of correctly omitting it.
For tools where a malformed parameter has real consequences (a transaction, a configuration change), strict mode guarantees the model's `input` validates exactly against your schema -- no extra fields, no wrong types.
Strict mode (`strict: true` in the tool definition, not in `tool_choice`) requires `additionalProperties: false` and an explicit `required` list, but in exchange guarantees you'll never receive a malformed input that your execution code has to defensively re-validate.
A set of 30+ tools available on every call degrades selection accuracy -- the model has to discriminate among too many similar options, and the odds of picking the wrong tool (or none, when it should use one) go up. If your agent needs a large tool catalog, the solution isn't always loading all of them -- it's using a dynamic discovery mechanism that only loads the definitions relevant to the task's current context, deferring the rest until they're actually needed.
As a practical rule: if an agent has more than 15-20 active tools at once and you're seeing selection errors, the first intervention isn't rewriting the descriptions -- it's reducing how many are available at a time.
When a tool's execution fails (a downed API, a timeout, failed validation in your backend), the result must go back to the model explicitly marked as an error, not as if it were a successful result with odd content. This lets the model reasonably decide whether to retry, inform the user, or try an alternate path -- instead of interpreting an error message as valid data.
A pattern that frequently breaks agents: returning the error as plain text with no `is_error: true`. The model then treats the error message as if it were the operation's legitimate result, and may report to the user that the action completed when it actually failed.
When the model requests several tools in a single response (default behavior on most current models), execute all of them and return all the `tool_result` blocks together in one message -- don't split them across multiple user messages. Splitting them implicitly trains the model to stop requesting parallel calls, reintroducing the sequential latency that parallelism was supposed to avoid.
For tools with nested parameters or non-obvious formats (dates in a specific format, complex filter structures), an example of a correct invocation inside the description reduces format errors more than any amount of detail in the raw JSON schema.
Designing the tool set well isn't a secondary detail of an agent system -- it's, along with context engineering, the part of the architecture that most determines whether the agent is reliable in production or ends up generating erratic calls that need patching case by case.
Carlos Montiel is an enterprise AI solutions architect. He implements LLMs, Agents, RAG, and orchestrators for companies across Guatemala and Latin America. Reach out for a consultation.
Contact Carlos Montiel