Native function calling
Modern LLM APIs return a structured tool call instead of free text, so you no longer have to parse a model's words and hope they are machine-readable.
Native function calling
The player loads from youtube-nocookie.com when you press play. Nothing reaches YouTube before that.
What you'll learn
- Native function calling means the model's API returns a structured object — a tool name plus arguments matching your schema — instead of free text you'd have to parse yourself.
- You execute the requested function yourself; the model never runs code, it only ever proposes a call and later reads back whatever result you send it.
- The full round trip has four steps — send tools with the prompt, receive a structured call, execute it and send back the result, let the model continue — and this is the same shape across OpenAI, Anthropic, and Gemini despite differing field names.
- Before native function calling existed, developers asked models to output tool calls as plain text and parsed it with regular expressions, which broke constantly on reasonable but unanticipated phrasing.
The problem before native function calling existed
Before every major provider built structured tool calling into their API, getting a
model to “use a tool” meant asking it, in the prompt, to output something like
CALL: get_weather(city="Lisbon") as plain text, and then writing a regular
expression to pull the function name and arguments back out of the model’s response.
This worked in demos and broke constantly in practice. A model might write
get_weather(city='Lisbon') with single quotes, or add a sentence of explanation
before the call, or format the arguments slightly differently from the exact pattern
your regex expected — any of which silently broke the parser. The underlying problem
was never the model’s reasoning; it was that free text has no guaranteed structure,
and extracting a reliable, machine-readable call from text generated by a language
model is fighting the medium.
What “native” actually means
Native function calling means the structure is guaranteed by the API itself, not
recovered after the fact by your code. When you call OpenAI’s, Anthropic’s, or
Gemini’s chat completion endpoint with a list of tool definitions attached, and the
model decides a tool applies, the API’s response includes a dedicated, typed field —
not a sentence to parse, but an object with a tool name and a set of arguments that
already match the JSON schema you provided. Anthropic calls it a tool_use content
block; OpenAI calls it a tool_call; the field names differ, but the guarantee is the
same: if the model wants to call a tool, the response contains a structured
representation of that call, not prose describing it.
A simplified version of what comes back looks like this:
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "call_8f2a",
"name": "get_weather",
"input": { "city": "Lisbon" }
}
]
}
Your code reads name and input directly — no regex, no hoping the model’s phrasing
matches a pattern. If the model doesn’t think a tool is needed, this field is simply
absent and you get ordinary text back instead.
The four-step round trip
The practical mechanics are the same shape across every provider, once you look past the differing field names.
- Send tool definitions with the prompt. Alongside the user’s message, you pass the list of available tools — the name, description, and schema from the previous lesson — as a separate parameter in the API call, not embedded in the prompt text.
- Receive a structured call. If the model decides a tool is relevant, the
response comes back containing a
tool_useortool_callobject instead of (or alongside) plain text. - Execute it yourself, then send the result back. Your application code looks up
get_weather, runs it with{"city": "Lisbon"}, and sends the return value back to the model in a new message — typically atool_resultortoolrole message referencing the same callid. - The model continues. With the result now in its context, the model generates its next output — which might be the final answer to the user, or another tool call if the task needs more than one step.
That loop can run once or many times in a row before the model produces a final answer — an agent answering a multi-part question might call three different tools in sequence, each one informed by the last.
A worked example end to end
Suppose a user asks an assistant, “What’s the weather like in Lisbon, and should I
bring an umbrella?” The assistant’s first API response contains a tool_use block
requesting get_weather(city="Lisbon"). Your code executes the real function, gets
back {"temp_c": 16, "condition": "rain"}, and sends that back as a tool result. The
model’s second response, now informed by that result, is ordinary text: “It’s 16°C and
rainy in Lisbon, so yes — bring an umbrella.” Nowhere in this exchange did your code
parse a sentence to figure out what the model wanted; the request arrived as a typed
object with exactly the fields your schema specified, which is the entire point of the
feature.
Why this matters beyond convenience
It’s tempting to read structured calling as a nice-to-have ergonomic improvement over text parsing, but it changes what’s actually reliable to build. A system that depends on regex-parsing free text degrades unpredictably as prompts, models, or phrasing shift — the same code might work today and quietly misfire after a model upgrade changes its default phrasing. A system built on native function calling depends on a contract the provider maintains deliberately, which is what makes it realistic to build agents that chain several tool calls together, as the next lesson’s error handling has to assume calls are structured in the first place, not that your code is still trying to regex a sentence apart.
Check yourself
What problem did native function calling solve that earlier approaches to tool use didn't?
Earlier approaches asked the model to describe a desired tool call in free text, which developers then parsed with regular expressions or string matching — fragile because any reasonable rewording of the model's output could break the parser; native function calling instead has the API return a structured, machine-readable object directly.
In the function-calling round trip, who actually executes the requested function, and what does the model do with the result?
Your own application code executes the function — the model has no ability to run code itself — and once you send the function's return value back to the model in a new message, the model reads it as context and continues generating its response, often producing the final answer only after seeing that result.
Go deeper
Notes
Notes are saved to your account.
Everything else on this page works without one — progress and bookmarks keep themselves in this browser and come with you when you sign in. Notes are the one thing worth not trusting to a browser you might clear.
Your notes could not be loaded.