TL;DR A tool is a function you describe to the model: its name, what it does, and the arguments it takes. The model cannot execute anything. It can only emit a structured request to call one, which your code runs before handing the result back. Once you see that, an agent stops being magic and becomes a plain function-call loop.

A language model on its own can only do one thing: produce text. It cannot check today's weather, look a customer up in your database, or add two numbers reliably. Tool calling, sometimes called function calling, is how you close that gap. And the mechanism is much simpler than the demos make it look. The model does not gain the ability to run code. It gains the ability to ask you to.

What a tool call actually is

You give the model a menu. Each item on the menu is a tool description: a name like get_weather, a sentence saying what it does, and a schema listing the arguments it expects, for example a city string. Crucially, you are handing over the description of the function, never the function itself. The real code stays on your side.

When the model decides a tool would help, it does not run it. It writes out a structured request: the tool's name, and the arguments filled in as proper data, for example get_weather(city: "Singapore"). That request is the model's entire contribution. Everything after it is ordinary software you control.

A two-lane diagram split between 'the model' on the left and 'your code' on the right. Step one, the model emits a structured request get_weather with city Singapore. Step two, your code runs the real function against a weather API. Step three, the result, temperature 31 and sky rain, is passed back into the model. Step four, the model writes the final answer: it is 31 degrees and raining in Singapore.
The model names a function and its arguments; your code runs the real thing and returns the result; the model turns that result into an answer. Nothing on the left ever executes.

The cycle

Put in order, every tool call is the same four beats. The model reads the conversation and emits a call. Your code validates the arguments and runs the real function, an API request, a database query, a calculation. You append the result to the conversation. The model reads that result and either answers or calls another tool. That is it. An “agent” is mostly this cycle run in a loop, which is exactly the loop I described in the loops-and-graphs piece: the tools are the actions the loop gets to take.

Two things follow immediately. First, the model can chain tools: look up a user, then use their ID to fetch their orders, because each result feeds the next turn. Second, nothing runs without passing through your code, so the safety boundary is yours. The model can ask to delete a record; whether that actually happens is a decision your code makes, not the model.

Good tool design is good API design

Here is the part that surprises people: making tools work well is mostly not a prompting problem, it is an interface problem. The model picks a tool the same way a new engineer would, by reading the name, the description, and the argument names. Vague names and fuzzy descriptions produce wrong calls for the same reason a confusing API produces bugs.

So the craft is familiar. Give each tool one clear job. Name it for what it does. Make the arguments specific and typed, so unit: "celsius" | "fahrenheit" beats a free-form string. Return errors as data the model can read and recover from, not as a crash. If you have ever designed an API another team has to use without asking you questions, you already know how to design tools. The model is that other team.

Why any of this matters

Tool calling is the seam where a language model meets the rest of your system, and it is far less mysterious than it sounds. The model contributes one thing, a well-formed request for a named function. Your code does the acting, keeps the control, and owns the safety. When a tool misbehaves, the fix is almost never a cleverer prompt; it is a clearer tool, the same way you would fix a confusing function.

That framing is the one I keep coming back to when an agent starts doing something odd. I do not ask what the model was thinking. I look at the menu I handed it, and usually the bad call was the honest reply to a badly written description.