When you give a model a tool, what you're actually doing is showing it a function signature in JSON: a name, a description, and the arguments it accepts. The model can then return — instead of prose — a request to call that function with specific arguments. Your code runs the function, and you pass the result back to the model as a new message. That's the entire mechanism.
Most tool-call failures are interface failures
When a tool call doesn't behave the way you wanted, the temptation is to blame the model. In practice, 80% of the time the model is calling the tool correctly given what you told it the tool does. The fix is in the tool definition, not in the model.
- Description too vague — "search" vs. "search the help center for an article matching the user's question; returns up to 3 titles + URLs."
- Argument names that don't say what they want — `id` vs. `support_ticket_id`
- Missing examples — add a one-line "example call: search_kb('how to reset password')"
- Tool does too many things at once — split into two narrower tools the model can compose
- Tool fails silently — return a structured error message ("not found: no article matched") instead of an empty result
Tool design heuristics
- Each tool should do one thing. If you find yourself writing "if mode == 'X' do Y, else do Z" inside a tool, split it.
- Inputs and outputs should be JSON-shaped, not free-text. Free-text is a request for the model to guess.
- When a tool can fail, make the failure a clear message the model can react to. Half-failures (returns empty without saying why) are the worst kind.
- Read-only tools first. Get the agent reading reliably before letting it write anywhere.
- 01
- 02
Knowledge check
0/1 answered1. Your agent calls search_kb() with the wrong query and gets no result. The simplest first improvement is to:
Discussion
0 commentsBe the first to start the conversation.