HOW-TO · RAG
How to Use OpenAI Function Calling with Tools
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES
OpenAI API key or local model with tool support, Python 3.10+
What this does
Function calling lets the LLM request execution of external tools by outputting structured JSON. The application executes the tool and feeds the result back to the model for a final answer.
Steps
- Define tool schemas. Each tool requires a JSON Schema description of its parameters.
import json
from openai import OpenAI
client = OpenAI(api_key="sk-...", base_url="http://localhost:11434/v1") # Ollama also works
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city name"
}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "Evaluate a math expression",
"parameters": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "Math expression like '2+2'"
}
},
"required": ["expression"]
}
}
}
]
- Send a request with tools. The model may return a
tool_callsresponse.
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "What's 15*7 and the weather in Paris?"}],
tools=tools,
tool_choice="auto"
)
message = response.choices[0].message
print(message.tool_calls)
- Execute tool calls and return results. Map function names to local implementations.
def get_weather(city: str) -> str:
return f"Weather in {city}: 22°C, sunny"
def calculate(expression: str) -> str:
return str(eval(expression))
if message.tool_calls:
messages = [{"role": "user", "content": "What's 15*7 and the weather in Paris?"}]
messages.append(message)
for tc in message.tool_calls:
func = globals()[tc.function.name]
args = json.loads(tc.function.arguments)
result = func(**args)
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": result
})
# Send back to model for final answer
final = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
print(final.choices[0].message.content)
- Force a specific tool with
tool_choice. Use{"type": "function", "function": {"name": "calculate"}}to force.
Verification
python -c "
from openai import OpenAI
c = OpenAI(api_key='sk-test', base_url='http://localhost:11434/v1')
r = c.chat.completions.create(model='llama3.2', messages=[{'role':'user','content':'say hi'}], tools=[{'type':'function','function':{'name':'test','parameters':{'type':'object','properties':{'x':{'type':'string'}},'required':['x']}}}])
print(r.choices[0].finish_reason)
# Expected: stop or tool_calls
"
Common failures
- Tool choice ignored by local models. Some models don't respect
tool_choice: "required". Fall back to parsing function calls from text. - JSON schema too complex. Deeply nested
$reforallOfschemas cause parsing failures. Use flatpropertieswithtypeanddescription. - Missing
tool_call_id. The tool response must include the exactidfrom the model's request. A mismatch causes the model to ignore the response. - Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
- Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.
Related guides
- How to Define JSON Schema for Tool Calling
- How to Handle Function Call Errors and Retries