Tools: when models need the outside world
The tool-call lifecycle
A reliable tool interaction is a loop of request, proposed call, application execution, tool result, and grounded response—not a single magical model action.
Before you start
Why this matters
A user asks, “Do I have time for a walk before my 3 p.m. meeting?” The assistant needs calendar data and perhaps weather data. If it instantly answers “Yes, you have forty minutes and it is sunny,” what evidence supports either claim?
To answer reliably, the system must cross boundaries in a controlled order. Each step has a different owner. Seeing the lifecycle makes it easier to find bugs, enforce policy, and tell the truth when something fails.
1Learn the idea
Read
Step 1: the application sends context
The application starts with the user’s message, relevant conversation context, and definitions of the tools available for this request. Availability should reflect the authenticated user, product mode, and policy. A guest should not even be offered an account-deletion tool. A read-only screen should expose read operations, not writes.
Conceptually, the request may include:
{
"messages": [
{
"role": "user",
"content": "What is the weather in Nairobi tomorrow?"
}
],
"tools": [
{
"name": "get_weather_forecast",
"description": "Returns a forecast up to five days ahead.",
"parameters": {
"type": "object",
"required": ["city", "date"],
"properties": {
"city": { "type": "string" },
"date": { "type": "string", "format": "date" }
}
}
}
]
}
The model receives a description, not the underlying API credential or implementation. Secrets stay in the execution environment.
Read
Step 2: the model proposes a call
The model may answer directly, ask a clarifying question, or emit a structured call. For the weather request, it might produce:
{
"type": "tool_call",
"id": "call_weather_01",
"name": "get_weather_forecast",
"arguments": {
"city": "Nairobi",
"date": "2026-07-19"
}
}
This output expresses intent. It does not cross a network boundary by itself. Even when an API or framework labels the event “tool use,” the host application remains responsible for deciding whether and how to run it.
The call ID is important. It lets the application associate a later result with the exact proposal, especially when several calls occur. Do not rely only on tool name because two weather calls could be in flight for different cities.
Read
Step 3: the application gates execution
Before invoking implementation code, the application parses and validates the call. It checks that the tool exists in the allowlist for this request, arguments match the schema, dates and ranges make sense, the user is authorized, and any required confirmation exists.
This is also where trusted context is attached. The application may add a tenant ID from the session, fetch a provider token from a secret store, apply a timeout, and generate an idempotency key. Those values should not be accepted from model output.
A simplified execution envelope could look like:
{
"trace_id": "trace_91af",
"tool_call_id": "call_weather_01",
"actor_user_id": "usr_204",
"validated_arguments": {
"city": "Nairobi",
"date": "2026-07-19"
},
"timeout_ms": 3000
}
If validation fails, the application does not “try its best” by executing malformed input. It returns a bounded error that enables clarification or correction.
Read
Step 4: the tool returns an observation
The implementation calls the weather provider, database, calculator, or other system. The application normalizes the provider-specific response into a small result contract.
{
"tool_call_id": "call_weather_01",
"ok": true,
"data": {
"city": "Nairobi",
"date": "2026-07-19",
"condition": "light rain",
"high_c": 22,
"source_updated_at": "2026-07-18T08:35:00Z"
}
}
Call this result an observation because it is new evidence available to the model. It may be successful, empty, partial, stale, or failed. The result should preserve those distinctions. An empty calendar search means “no matching events were returned,” not necessarily “the user has no events anywhere.”
For a write, the observation should identify whether the side effect was accepted, completed, pending, or rejected. An HTTP response alone may not prove completion if the provider processes jobs asynchronously.
Read
Step 5: the model responds from evidence
The application sends the tool result back into the conversation, associated with its call ID. The model can now compose a user-facing answer: “Nairobi’s forecast for tomorrow shows light rain with a high near 22°C.”
The final response must not exceed the evidence. It should mention uncertainty or freshness when relevant. If the provider returns no data, the assistant should say it could not retrieve the forecast, not substitute a likely climate pattern. If a calendar event is pending, it should not say the event is confirmed.
Some requests need another call after the first observation. The model might discover that it needs a location ID, or use a calendar result to choose the time range for weather. The same gate-and-observe process repeats, subject to call, cost, and time limits.
Read
Lifecycle states prevent confusion
In production, represent states explicitly: proposed, validated, approval_required, executing, succeeded, failed, and perhaps unknown. The unknown state matters when a timeout occurs after a provider may have received a write. Retrying blindly could duplicate the side effect.
Store a trace that links the original user request, advertised tool set, model proposal, validation outcome, execution attempt, normalized result, and final message. Redact secrets and apply retention controls, but preserve enough evidence to answer “What happened?”
The lifecycle also reveals where controls belong. Schema checks happen before execution. Provider errors happen during execution. Grounding checks compare the final answer with returned evidence. Combining these into one “tool accuracy” score hides actionable failures.
Continue learning · glossary & guides
- Can you name all five stages and the owner of each?
- Why must tool-call IDs link proposals to results?
- What is the truthful state after a write times out and completion cannot be verified?
- Glossary: function calling · Snippet: function-call handler · Snippet: trace request ID