OpenAI Function Calling: Complete Guide with Python Examples
Introduction
Function calling allows GPT models to interact with external systems — APIs, databases, file systems — by generating structured JSON arguments that your code executes. This turns a text generator into an AI agent capable of taking actions in the real world.
How Function Calling Works
User: "What's the weather in Tokyo?"
↓
GPT detects: needs weather function
↓
GPT outputs: {name: "get_weather", arguments: {location: "Tokyo"}}
↓
Your code: calls weather API with "Tokyo"
↓
GPT: "The weather in Tokyo is 22°C, partly cloudy."
Setup
import openai
import json
client = openai.OpenAI(
api_key="your-api-key",
base_url="https://api.apiyihe.org/v1"
)
Defining Functions
functions = [
{
"name": "get_stock_price",
"description": "Get the current stock price for a given symbol",
"parameters": {
"type": "object",
"properties": {
"symbol": {
"type": "string",
"description": "Stock ticker symbol, e.g. AAPL, GOOGL"
}
},
"required": ["symbol"]
}
},
{
"name": "calculate_mortgage",
"description": "Calculate monthly mortgage payment",
"parameters": {
"type": "object",
"properties": {
"principal": {"type": "number", "description": "Loan amount in USD"},
"rate": {"type": "number", "description": "Annual interest rate (%)"},
"years": {"type": "integer", "description": "Loan term in years"}
},
"required": ["principal", "rate", "years"]
}
}
]
Complete Agent Example
import openai
import json
import math
client = openai.OpenAI(
api_key="your-api-key",
base_url="https://api.apiyihe.org/v1"
)
def get_stock_price(symbol: str) -> dict:
prices = {"AAPL": 185.50, "GOOGL": 142.30, "MSFT": 420.10}
return {"symbol": symbol, "price": prices.get(symbol, "Unknown")}
def calculate_mortgage(principal, rate, years):
r = rate / 100 / 12
n = years * 12
payment = principal * (r * (1 + r)**n) / ((1 + r)**n - 1)
return {"monthly_payment": round(payment, 2), "total": round(payment * n, 2)}
available_functions = {
"get_stock_price": get_stock_price,
"calculate_mortgage": calculate_mortgage,
}
def run_agent(user_prompt):
messages = [{"role": "user", "content": user_prompt}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
functions=functions,
function_call="auto"
)
msg = response.choices[0].message
if msg.function_call:
func_name = msg.function_call.name
func_args = json.loads(msg.function_call.arguments)
func = available_functions[func_name]
result = func(**func_args)
messages.append(msg)
messages.append({
"role": "function",
"name": func_name,
"content": json.dumps(result)
})
final = client.chat.completions.create(
model="gpt-4o",
messages=messages
)
return final.choices[0].message.content
return msg.content
print(run_agent("What's AAPL stock price?"))
print(run_agent("Calculate monthly payment for $400,000 at 6.5% for 30 years"))
Multi-Function Calls
functions = [
{"name": "search_docs", ...},
{"name": "send_email", ...},
{"name": "create_task", ...},
]
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Find docs about authentication and email them to [email protected]"}],
functions=functions,
function_call="auto"
)
msg = response.choices[0].message
if msg.function_call:
# GPT might call one function at a time; handle iteratively
while msg.function_call:
func = available_functions[msg.function_call.name]
result = func(**json.loads(msg.function_call.arguments))
messages.append(msg)
messages.append({"role": "function", "name": msg.function_call.name, "content": json.dumps(result)})
response = client.chat.completions.create(model="gpt-4o", messages=messages, functions=functions)
msg = response.choices[0].message
Node.js Example
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "your-api-key",
baseURL: "https://api.apiyihe.org/v1",
});
const tools = [{
type: "function",
function: {
name: "search_flights",
description: "Search for available flights",
parameters: {
type: "object",
properties: {
from: { type: "string" },
to: { type: "string" },
date: { type: "string" }
},
required: ["from", "to"]
}
}
}];
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Find flights from SFO to NYC tomorrow" }],
tools,
tool_choice: "auto",
});
Common Errors and Fixes
| Error | Cause | Solution | |---|---|---| | "Invalid function call arguments" | Malformed JSON | Validate JSON.parse() with error handling | | "Function not found" | Function name mismatch | Match exactly; case-sensitive | | "Missing required parameter" | GPT omitted a required field | Add clear descriptions to parameters | | "Maximum function call depth" | Infinite loop | Limit iterations in while loop | | "Hallucinated function arguments" | GPT made up values | Validate results; retry with error feedback |
Pricing
Function calls consume tokens like any other API call. The function definitions in the request count as input tokens. Function call responses count as output tokens. A typical function call sequence uses 500-2000 tokens total.
FAQ
Q: What's the difference between functions and tools? A: Tools is the newer API (GPT-4o+). Functions is the legacy API. Both work; tools is recommended for new projects.
Q: Can function calling work with DeepSeek via AI API Hub? A: Yes. DeepSeek V3 supports function calling through the OpenAI-compatible API.
Q: How many functions can I define? A: Up to 128 in a single request. Practical limit is 10-20 for reliable selection.
Q: Can GPT call multiple functions at once?
A: Only with tool_choice: "required" and parallel tool calls. Otherwise iterate.
Alternatives
- LangChain Agents: Higher-level abstraction for tool use
- Assistant API: Managed conversation state with built-in tools
- Custom routing: Route queries to specific functions based on keyword matching