An agent that picks the right function is not the hard part anymore. Every major model does that reliably. The part that decides whether your agent survives contact with production is everything wrapped around the call: how the function is described, what happens between the model asking and the result coming back, who is allowed to approve it, and what the model sees when it fails.
Here is where the failures actually cluster.
The Schema Is The Prompt
Function definitions are not configuration. They are instructions the model reads on every single turn, and they compete for attention with the rest of the context.
Vague parameter names and missing enums produce wrong arguments far more often than a weak model does. date is a coin flip. start_date_iso8601 is not. A status string that accepts anything will get creative values invented for it, while an enum of four allowed values will not.
Write each parameter description the way you would write docs for someone joining the team tomorrow, mark only what is truly required, and use enums wherever the set is closed. Most "the model keeps calling the tool wrong" bugs are schema bugs wearing a costume.
The Execution Lifecycle Is Yours, Not The Model's
The model returns a structured request. It does not run anything. Your code decides whether to execute, with which credentials, under what timeout, and what to hand back.
That gap is the most valuable place in the whole system, and it is where validation, rate limiting, idempotency keys, and logging belong. Skipping it is how you end up with an agent that charges a card twice because a retry looked like a fresh request.
Treat every tool call as a transaction with a beginning, a middle you control, and an end you record.
Write Errors For The Model To Read
A raw stack trace tells the model nothing it can act on, so it does the only thing left and guesses.
Compare "TypeError: cannot read property of undefined" with "invalid date format, expected YYYY-MM-DD, received 03/14/26". The second one produces a correct retry on the next turn. So does "rate limited, retry after 30 seconds" instead of a bare 429.
Agents that recover well are almost always agents whose error strings were written on purpose. This is the cheapest reliability work available and it is the piece teams skip most often.
Permissions Decide How Far You Can Let It Go
Read-only tools can run unattended all day. Anything that spends money, sends mail, or deletes data needs a scope boundary and usually a human confirmation step.
A useful pattern: split read and write into separate tools instead of one tool with a mode parameter. A mode flag is a value the model chooses. Two tools is a grant you either issued or you did not.
Deciding this per tool, up front, is what lets you widen autonomy later without rewriting the whole system.
The Takeaway
Tool calling is the capability that turns a conversational model into a functional agent. But the capability is not the product. The schemas, the execution lifecycle, the permission model, and the error strings are the product, and they are all things you write rather than things the model provides.
If you want the longer version, this complete guide to AI tool calling covers function definitions and schemas, the execution lifecycle, calling patterns, security and permissions, error handling, and cost and performance in one place.
Top comments (0)