Function calling lets LLMs interact with the real world — calling APIs, querying databases, running code. It's the foundation of AI agents.
Function calling (also called tool use) lets an LLM decide when to call an external function and what arguments to pass. The model doesn't execute the function — it tells your application to do it.
User: "What's the weather in Mumbai?"
Without tools: "I don't have access to real-time weather data."
With tools: Model calls get_weather(city="Mumbai")
→ Your app fetches from weather API
→ Model uses result to answer: "It's 32°C and sunny in Mumbai"
The LLM never directly calls anything — it returns a structured instruction, your code executes it, and you send the result back.
from openai import OpenAI
import json
client = OpenAI()
# Define your tools
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name e.g. Mumbai, Delhi"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit"
}
},
"required": ["city"]
}
}
}
]
# Send message with tools
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "What's the weather in Mumbai?"}],
tools=tools,
tool_choice="auto" # model decides when to use tools
)message = response.choices[0].message
if message.tool_calls:
for tool_call in message.tool_calls:
# Parse the arguments
args = json.loads(tool_call.function.arguments)
# {"city": "Mumbai", "unit": "celsius"}
# Execute your actual function
if tool_call.function.name == "get_weather":
result = get_weather(args["city"], args.get("unit", "celsius"))
# Send result back to model
messages.append(message) # add assistant's tool call
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
})
# Get final response with tool results
final_response = client.chat.completions.create(
LLMs can choose from multiple tools and even call several in parallel:
tools = [
get_weather_tool,
search_flights_tool,
book_hotel_tool,
get_exchange_rate_tool,
]
# User: "Plan a trip to Tokyo next week"
# Model might call: get_weather + search_flights + get_exchange_rate
# All in parallel, then synthesize resultstool_choice="auto" # model decides when to use tools (default)
tool_choice="none" # never use tools
tool_choice="required" # must use at least one tool
tool_choice={"type": "function", "function": {"name": "get_weather"}}
# force a specific tool| Tool | What it does | Example |
|---|---|---|
| Web search | Fetch real-time information | Current news, prices |
| Code execution | Run Python/SQL | Data analysis, calculations |
| Database query | Fetch structured data | User records, inventory |
| API calls | External services | Weather, maps, payments |
| File operations | Read/write files | Document processing |
| Email/calendar | Send messages, schedule | Booking, notifications |
They're the same thing — "tool calling" is the newer, more general term. OpenAI originally called it "function calling". The API still uses tools and function in the schema.
tool_choice="auto" for most cases — the model decides when tools are needed