Function calling lets an LLM request the execution of external functions — APIs, databases, calculations — by outputting structured JSON matching a schema you define. The model decides when to call a function, which function, and with what arguments.
Parallel function calling: models can request multiple tool calls in one response. Structured output / JSON mode: forces the model to output valid JSON matching a schema — useful even without external tools for data extraction, classification, etc.
Python — OpenAI function calling#
Four tool calls checked against a schema. The first passes. The second is missing the required unit and sends days as a string. The third is not valid JSON (a missing brace). The fourth uses “K”, which is not an allowed unit. Every one of these reaches your code unless you validate — the model proposes a call, your program decides whether to run it.
- Constrained decoding (JSON mode) guarantees valid syntax, not correct arguments.
- Tool descriptions are part of the prompt; vague descriptions cause wrong tool choice.
- Tool outputs can carry instructions (prompt injection); treat them as data, never as commands.
import json
schema = {'required': ['city', 'unit'], 'types': {'city': str, 'unit': str, 'days': int},
'enum': {'unit': ['celsius', 'fahrenheit']}}
def check(raw):
try: args = json.loads(raw)
except json.JSONDecodeError as e: return [f'not JSON: {e.msg}']
errs = [f'missing {k}' for k in schema['required'] if k not in args]
errs += [f'{k} should be {t.__name__}' for k, t in schema['types'].items() if k in args and not isinstance(args[k], t)]
errs += [f'{k} not in {v}' for k, v in schema['enum'].items() if k in args and args[k] not in v]
return errs
calls = ['{"city": "Aarhus", "unit": "celsius"}', '{"city": "Aarhus", "days": "3"}', '{"city": "Aarhus", "unit": "kelvin"', '{"city": "Aarhus", "unit": "K"}']
results = [check(c) for c in calls]Assumes import numpy as np. Configurations named after real models use their published shapes; other numbers are made up or simulated, as the comments say.
The same idea with a library
from openai import OpenAI
import json
client = OpenAI()
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location"]
}
}
}]
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Weather in Oslo?"}],
tools=tools
)
# Parse tool call → execute → send result back
call = response.choices[0].message.tool_calls[0]
args = json.loads(call.function.arguments)- T. Schick et al., “Toolformer: Language Models Can Teach Themselves to Use Tools”, NeurIPS, 2023
- S. G. Patil, T. Zhang, X. Wang & J. E. Gonzalez, “Gorilla: Large Language Model Connected with Massive APIs”, arXiv:2305.15334, 2023
- JSON Schema specification, json-schema.org
Last reviewed October 2026 · How this site checks its content · Report a mistake