An agent's ability to act comes down to one mechanism, and it is simpler than it sounds. The model outputs a structured description of an action it wants taken. A program reads that description and takes the action. That is function calling, and everything an agent does in the world runs through it.
How a tool is described
Before the conversation starts, the surrounding program tells the model what actions exist. Each one gets a name, a plain description of what it does, and a list of inputs with their types. Something like: a tool named search_web, described as searching the public internet, taking one input called query which is text.
The model is not shown any code. It is shown a menu, in words, and it has been trained on enough examples to produce a request in the right shape when a menu item fits the situation.
What actually crosses the wire
When the model decides to search, it does not search. It emits text along the lines of: call search_web with query set to "current entry requirements for the country I am visiting". That output is intercepted by the harness before it ever reaches you.
The harness then does the real work. It calls the actual search API, gets results, and inserts them back into the conversation as a new message. The model's next turn sees those results as ordinary context and continues.
Three consequences follow, and they explain most agent behavior:
The model cannot exceed its menu. If no email tool was provided, no wording will make it send an email. This is the foundation of agent security.
The harness is the real authority. It decides whether to run the requested call, with what credentials, and against which account. A model requesting a file deletion is only a suggestion until the harness obliges.
Tool results become context, and context can lie. Whatever comes back is treated as information. If a web page it fetched contains text designed to manipulate the model, that text is now in the conversation. This is prompt injection, covered in where agents fail.
Why tool descriptions matter more than people expect
The model chooses tools by matching your situation against those written descriptions. Vague descriptions produce wrong choices, in the same way a vague prompt produces a vague answer.
A tool described only as "gets data" will be reached for constantly and used badly. The same tool described as "reads the current row count of a named table in the sales database, read-only" gets used when it fits and ignored when it does not.
If you ever configure an agent, the descriptions are not documentation. They are instructions the model reads at decision time, and they deserve as much care as your prompt.
Where this breaks
Wrong tool, confidently chosen. When two tools sound similar, the model picks the one whose description is closer in wording, not the one that is correct.
Malformed inputs. It may produce a value in the wrong shape or invent an identifier that looks plausible. Good harnesses validate and hand back errors so the model can retry, but the retry can be wrong too.
Silent partial success. A tool that succeeds while doing less than expected returns success. The model believes it and moves on.
No sense of consequence. Deleting a file and reading a file are structurally identical to the model: a name and some inputs. Only the harness knows one is irreversible. That is why permissions live outside the model, never inside a polite request to be careful.
Key takeaway: an agent acts by producing structured text that a program agrees to execute. Everything it can and cannot do is decided by that program, not by the model.