## Definition
**Function calling** is the API mechanism that turns a language model into something that can use tools. The developer declares an inventory of callable functions; the model, when it decides one is needed, emits a structured request naming the function and supplying JSON arguments. It is the wire-level protocol underneath every implementation of [[Tool Use]].
## The contract
A function-calling request carries two things beyond the prompt:
1. A **tool inventory** — for each tool, a `name`, a natural-language `description`, and a JSON-schema for its `parameters`. The description and schema are the only things the model "knows" about the tool; they are prompt engineering, and vague ones produce vague calls.
2. A **tool_choice** directive controlling whether the model may, must, or must not call a tool on this turn.
| tool_choice | Meaning |
|-------------|---------|
| `auto` | Model decides whether to call a tool or answer directly |
| `any` / `required` | Model must call some tool (no plain-text answer) |
| `none` | Tools are visible but calling is forbidden this turn |
| `{name: "X"}` | Force a specific tool |
`any` is the lever you pull when you want guaranteed structured action; `none` lets you show the schema while suppressing a call, useful for a final summarisation turn.
## The model proposes, the host executes
The single most important property to internalise: **the model never runs the function.** It only produces the *intent* to call — a name and a JSON argument blob. Your application (the host) parses that, executes the real code, and feeds the result back into the conversation as a tool-result message. The model then continues with the result in context.
```text
model -> {"name": "get_weather", "args": {"city": "Girona"}}
host -> executes get_weather("Girona") -> "18C, clear"
host -> appends tool_result to messages
model -> "It's 18C and clear in Girona."
```
This separation is what makes tool use safe to reason about: the boundary between proposal and execution is exactly where you put validation, authorization, and logging. Chip Huyen frames the model's job as planning the call and the system's job as performing it in *[[AI Engineering - Chip Huyen]]*; Micheal Lanham walks through the same round-trip mechanically in *[[AI Agents in Action - Micheal Lanham]]*.
## Arguments can be wrong — validate
The model emits arguments that *look* like they satisfy the schema, but conformance is not guaranteed. Common failures:
- A required field is missing or named slightly wrong.
- A value is the right type but semantically nonsense (a date in the past, a negative quantity).
- The model invents an enum value that isn't in your schema.
- Numbers arrive as strings, or nested objects are flattened.
Treat every incoming call as untrusted input: validate against the schema, range-check values, and on failure feed a structured error message *back to the model* rather than crashing. A good error string ("amount must be positive, got -5") lets the model self-correct on the next turn — this is precisely the observe-step of the [[Agentic Loop]].
## Relationship to the loop and to outputs
Function calling is the substrate of the [[ReAct Pattern]]: the *act* is a function call and the *observation* is its result. Repeat that proposal-execution-observation cycle and you have the [[Agentic Loop]]. The available functions are organised by what they do — see [[Tool Taxonomy]] — and the JSON-schema discipline that makes calls parseable is the same machinery behind [[Structured Outputs]] generally; forcing a tool call is one of the most reliable ways to get a model to emit valid JSON.
## Related
- [[Tool Use]]
- [[ReAct Pattern]]
- [[Agentic Loop]]
- [[Tool Taxonomy]]
- [[Structured Outputs]]
- [[AI Engineering - Chip Huyen]]
- [[AI Agents in Action - Micheal Lanham]]