The model never executes anything. It emits a structured request, your code runs it, and the result flows back into the conversation. Step through the loop and see exactly who does what.
Why a language model needs tools
A large language model is a next-token predictor. Three gaps follow from that, and tools close all three.
Frozen knowledge
An LLM's knowledge stops at its training cutoff. It cannot know today's weather, prices, or news. A tool call fetches the current fact and puts it in the context.
Unreliable arithmetic
LLMs predict tokens, they do not compute. Long multiplications and precise sums come out wrong often enough to matter. A calculator tool returns the exact answer every time.
No hands
Text generation cannot send an email, query a database, or book a meeting. Tools are how a model's decision becomes an action your code performs on its behalf.
The contract: name, description, parameters
A tool definition is a small contract between your code and the model. The model never sees your implementation, only this schema. Writing a good description is prompt engineering in miniature.
{
"name": "get_weather",
"description": "Get the current weather for a location. Use when the user asks about present conditions, not forecasts.",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and country, e.g. \"Oslo, Norway\""
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit for the result"
}
},
"required": ["location"]
}
}name
The stable identifier the model emits when it wants this tool. Keep it short, verb-first, and unambiguous.
description
The model's only guide for WHEN to call the tool. This is prompt engineering: write it like documentation for a new teammate, including when not to use it.
input_schema
JSON Schema for the arguments. The model fills it in; your runtime validates against it before executing. Enums like unit constrain the model to legal values.
Trace explorer: watch one tool call happen
Pick a scenario, then advance one message at a time. Each trace is a fixed, hand-authored example (labeled as simulated), showing the four messages every major native function-calling API exchanges.
One round trip through the loop
get_weather(location, unit)
What's the weather in Oslo right now?
What happens hereThe runtime sends this message to the model along with the list of available tool definitions. The model has no live weather data of its own.
Same question, with and without tools
Question: "What's the weather in Oslo right now?" Both answers below are simulated for illustration. The difference is not fluency, it is whether the specific claim can be traced to evidence in the context.
Without tools
Simulated response"Oslo summers are usually mild. Right now it is probably around 20 degrees with clear skies."
Plausible, fluent, and unverifiable. The model's knowledge stops at its training cutoff, so any specific number about "right now" is a guess dressed up as a fact. This is the same failure mode as hallucination: confident text with nothing behind it.
With tools
Simulated response"It is currently 17 degrees Celsius and partly cloudy in Oslo, per the weather service."
The number comes from a tool result sitting in the conversation (the trace above), so the claim is grounded: you can point at the exact message it came from, log it, and audit it. Grounding does not make the model smarter, it makes the answer checkable.
From one call to an agent: the loop
Everything you stepped through above was one iteration. Put it in a while-loop and you have an agent: the model keeps requesting tools until it can answer, and the conversation itself is the agent's state. That is the whole trick behind AI agents.
messages = [user_request]
loop:
response = model(messages, tools)
if response.tool_calls:
results = execute(response.tool_calls) # your code runs here
messages += response.tool_calls + results
else:
return response.text # final answerModern APIs also support parallel tool calls: the model can request several independent calls in a single turn, such as the weather for three cities at once, and the runtime executes them concurrently and returns all results together.