Tool Use & Function Calling
Tool use lets LLMs request function execution instead of guessing answers. Define tools with schemas, validate arguments, execute safely, and return results to the model.
Search across all documentation pages
Tool use lets LLMs request function execution instead of guessing answers. Define tools with schemas, validate arguments, execute safely, and return results to the model.
tools = [{"type": "function", "function": {
"name": "get_order",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}}, "required": ["order_id"]},
}}]
response = client.chat.completions.create(model="gpt-4o-mini", messages=messages, tools=tools)"""tool_use.py - safe tool execution loop."""
from __future__ import annotations
import json
from pydantic import BaseModel, ValidationError
from openai import OpenAI
client = OpenAI()
class GetOrderArgs(BaseModel):
order_id: str
def get_order(order_id: str) -> dict:
orders = {"ORD-123": {"status": "shipped", "total": 49.99}}
return orders.get(order_id, {"error": "not found"})
TOOL_REGISTRY = {"get_order": (GetOrderArgs, get_order)}
tools = [{"type": "function", "function": {
"name": "get_order",
"description": "Look up order by ID",
"parameters": GetOrderArgs.model_json_schema(),
}}]
messages = [{"role": "user", "content": "What is the status of order ORD-123?"}]
for _ in range(5):
resp = client.chat.completions.create(model="gpt-4o-mini", messages=messages, tools=tools)
msg = resp.choices[0].message
if not msg.tool_calls:
print(msg.content)
break
messages.append(msg)
for call in msg.tool_calls:
name = call.function.name
schema_cls, fn = TOOL_REGISTRY[name]
try:
args = schema_cls.model_validate_json(call.function.arguments)
result = fn(**args.model_dump())
except ValidationError as e:
result = {"error": str(e)}
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})| Alternative | Use When | Don't Use When |
|---|---|---|
| OpenAI tool calling | GPT models | Claude (use Anthropic tool format) |
| LangChain @tool | LangGraph agents | Raw SDK preference |
| MCP | Standardized tool servers | Simple single-app tools |
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 19, 2026