Most teams discover the problem the same way: an agent that worked fine in testing starts returning null where a number should be, or invents an argument name that does not exist in the schema.
A prompt that works perfectly in testing starts failing after a model update. The JSON parser breaks on unexpected field types. The LLM decided to rename "status" to "current_state" without warning.
That is not a prompting problem - it is a misunderstanding of what function calling actually does at the inference layer.
Here is how it works, and why the details matter.
What the model actually does when it calls a function
Function calling - also called tool calling - provides a way for models to interface with external systems and access data outside their training data. But calling is a slightly misleading word. The model does not run any code. It produces a structured text object that your application receives and then executes.
Here is what happens under the hood: the user sends a query. The LLM analyzes it and recognizes it needs external data or an action. If the user asks about CRM leads, the model identifies the need to fetch live data. If they want inventory details, it triggers a database lookup. Then the LLM decides to execute a function call - this could be an API call to pull real-time data from Salesforce or a custom function accessing an internal database. The function fetches the required data, sends it back to the LLM, and the model processes it into a response.
The model's output in that middle step looks something like this: