Name, description, parameters
Last lesson you learned to spot the gap — to see that "weather in Tokyo right now" reaches past what the model knows. Now you hand the model a way to cover that gap. But the model can't see your code; it can only see a description of what's available. So a tool is, before anything else, a small contract written for the model to read.
A tool has three parts. The name is the identifier the model emits when it decides to
call (get_weather). The parameters schema lists the arguments it must supply and
their types ({ city: "string" }) — this is what the model fills in. And the
description is the load-bearing part: it is not documentation, it is the prompt the
model reads to decide when this tool applies. The model never runs your function to
find out what it does; it routes entirely off these words.
Watch how much the wording carries. "Gets weather" is nearly useless — the model has
to guess whether that means a forecast, a historical lookup, or current conditions, and
when to prefer it. "Get the current weather for a city. Use when the user asks about current conditions or temperature." tells the model both the what and the trigger.
Same function, completely different call behavior.
This is where most tool bugs actually live. A vague description means the model never calls a tool it should — or fires it at the wrong moment, burning a call and confusing the user. You'll tune descriptions far more than you'll tune code.
Define a real tool with all three parts filled in — a get_weather tool is the obvious
one. Done is a printed object where name, description, and parameters are all
non-empty, with a description that states what it does and when to use it.
A vague description means the model never calls the tool — or calls it at the wrong moment. The description is where most of the work is.