Fix LLM not calling function when expected
Quick answer
Ensure you use the
tools parameter (not deprecated functions) when creating chat completions with the OpenAI SDK. Also, check if the response's finish_reason is tool_calls and parse message.tool_calls to trigger the function call properly.PREREQUISITES
Python 3.8+OpenAI API key (free tier works)pip install openai>=1.0
Setup
Install the latest openai Python package and set your API key as an environment variable.
- Install SDK:
pip install openai --upgrade - Set environment variable:
export OPENAI_API_KEY='your_api_key'(Linux/macOS) orsetx OPENAI_API_KEY "your_api_key"(Windows)
pip install openai --upgrade output
Collecting openai Downloading openai-1.x.x-py3-none-any.whl (xx kB) Installing collected packages: openai Successfully installed openai-1.x.x
Step by step
Use the tools parameter to define your function schema and check the response for tool_calls to invoke the function. This example shows a weather function call triggered by the LLM.
import os
import json
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# Define the function schema as a tool
weather_tool = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"}
},
"required": ["location"]
}
}
}]
# User prompt
messages = [{"role": "user", "content": "What's the weather in New York?"}]
# Create chat completion with tools
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=weather_tool
)
print("LLM response:", response.choices[0].message.content)
# Check if LLM wants to call a function
if response.choices[0].finish_reason == "tool_calls":
tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
location = args.get("location")
# Simulate function call
weather_result = f"The weather in {location} is sunny and 75°F."
print("Function call result:", weather_result)
else:
print("No function call requested.") output
LLM response: Function call result: The weather in New York is sunny and 75°F.
Common variations
You can use async calls with the OpenAI SDK by using asyncio and await. Also, you can switch to different models like gpt-4o or gpt-4o-mini. Remember to always use the tools parameter instead of the deprecated functions parameter.
import os
import json
import asyncio
from openai import OpenAI
async def main():
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
weather_tool = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"]
}
}
}]
messages = [{"role": "user", "content": "What's the weather in San Francisco?"}]
response = await client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=weather_tool
)
print("LLM response:", response.choices[0].message.content)
if response.choices[0].finish_reason == "tool_calls":
tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
location = args.get("location")
weather_result = f"The weather in {location} is cloudy and 65°F."
print("Function call result:", weather_result)
else:
print("No function call requested.")
asyncio.run(main()) output
LLM response: Function call result: The weather in San Francisco is cloudy and 65°F.
Troubleshooting
- If the LLM never calls your function, verify you are using the
toolsparameter instead of the deprecatedfunctionsparameter. - Check that your function schema is correctly formatted as a tool with
typeandfunctionkeys. - Ensure you parse
response.choices[0].message.tool_callsand notresponse.choices[0].message.function_call, which is deprecated. - If
finish_reasonis nottool_calls, the model did not request a function call; try rephrasing your prompt or adjusting model temperature.
Key Takeaways
- Always use the
toolsparameter to define functions for the LLM to call. - Check
finish_reason == 'tool_calls'and parsemessage.tool_callsto handle function calls. - Avoid deprecated parameters like
functionsandfunction_callin the OpenAI SDK. - Use async calls for non-blocking function invocation with the OpenAI Python SDK.
- Validate your function schema strictly matches the required JSON schema format.