Mathew K Analytics

Lesson 12 · OpenAI

OpenAI Function Calling Explained with Error Handling in Python

Welcome to your hands-on beginner lesson. You will learn how to use the OpenAI API for advanced function calling. We will type code step by step and explain…

⬇ Download notebookOpen in Colab ↗

📓 Full notebook

Download .ipynb

Learn OpenAI API Function Calling in Python#

  • Welcome to your hands-on beginner lesson.
  • You will learn how to use the OpenAI API for advanced function calling.
  • We will type code step by step and explain key ideas as we go.
  • No experience needed! Everything is explained simply.

What is the OpenAI Function Calling API?#

  • Function calling lets you describe real Python functions to an AI.
  • The model can decide when to run them and pass arguments for you.
  • This makes AI much smarter in apps, chatbots, and automations.

How the Lesson Works#

  • We will set up your environment for OpenAI Python.
  • We will learn how to register real Python functions for the model.
  • You will see how to let an AI call your function using chat input.
  • At the end, try exercises and projects to build real AI helpers.
import warnings; warnings.filterwarnings("ignore")
import numpy as np
np.random.seed(42)
# Suppress warnings so output stays clean for beginners.
import os
from openai import OpenAI

API_key = os.environ["OPENAI_API_KEY"]
client = OpenAI()

# We import the API key from your environment.
# Then we create an OpenAI client instance.

Why Use Function Calling with AI?#

  • Normally, chat models answer with text only.
  • With function calling, the AI can trigger your own code.
  • This is good for apps, tools, math, data, or automating anything.
  • The function is defined by you and described with a schema.
  • The schema tells the model what arguments are needed.
def add(a, b):
    """Add two numbers and return the sum."""
    return a + b

# This simple function adds two numbers.
# We will let the AI call it for us!
function_schema = {
    "name": "add",
    "description": "Add two numbers.",
    "parameters": {
        "type": "object",
        "properties": {
            "a": {"type": "number"},
            "b": {"type": "number"}
        },
        "required": ["a", "b"]
    }
}

# This schema tells the model about the function and its arguments.
messages = [
    {"role": "user", "content": "What is three plus five?"}
]

# The user message is a simple math question.
# The model will decide if it wants to call our add function.

How Does Function Calling Work?#

  • The chat model sees user messages and your function schema.
  • If it decides, it returns arguments to call your function.
  • You run the Python function, get a result, then give this result back to the model.
  • Then the AI responds to the user with an answer in natural language.
response = client.chat.completions.create(
    model="gpt-4.1",
    messages=messages,
    functions=[function_schema],
    function_call="auto"
)

# The model gets your message and your function schema.
# It can decide to output a function call if it thinks your code helps.
choice = response.choices[0]
if hasattr(choice, 'message') and hasattr(choice.message, 'function_call') and choice.message.function_call:
    fn_args = choice.message.function_call.arguments
    import json
    args = json.loads(fn_args)
    result = add(**args)
    print(f"Function called! Result: {result}")
else:
    print("No function call detected.")

# This block runs the function using arguments from the models output.
# It checks if function_call appears, parses arguments, runs your code, and shows the result.
Function called! Result: 8

Practical Example: Summing User Input#

  • Now let us try getting numbers from a real user.
  • We will use input() to collect two numbers to add.
  • Then, wrap them in a user chat message for the AI to process.
num1 = input("Enter a number: ")
num2 = input("Enter another number: ")
prompt = f"Please add {num1} and {num2}."
user_msg = [{"role": "user", "content": prompt}]

# We collect numbers as strings from the user.
# Then, build a message for the AI to interpret and call the function.
response2 = client.chat.completions.create(
    model="gpt-4.1",
    messages=user_msg,
    functions=[function_schema],
    function_call="auto"
)

choice2 = response2.choices[0]
if hasattr(choice2, 'message') and hasattr(choice2.message, 'function_call') and choice2.message.function_call:
    fn_args2 = choice2.message.function_call.arguments
    import json
    args2 = json.loads(fn_args2)
    res2 = add(**args2)
    print(f"The answer is: {res2}")
else:
    print("No function call performed by the model.")

# We send your new message to the model.
# If it suggests a function call, we run it and show the answer.
The answer is: 49

Handling Problems and Missing Function Calls#

  • Sometimes the model does not call your function.
  • Check your schema and types. Be clear in your user messages.
  • Be sure the arguments match your function definition and schema.
  • If you need, set function_call to {"name": "add"} to force a call.
forced_response = client.chat.completions.create(
    model="gpt-4.1",
    messages=messages,
    functions=[function_schema],
    function_call={"name": "add"}
)

# This forces the model to call the add function, even if it was unsure.

Best Practices for Function Calling#

  • Use clear, simple function names and descriptions.
  • Define correct argument types in your schema.
  • Always check that the model provided all needed arguments.
  • Use print() or logs to debug what the AI sends and receives.
  • Keep your functions small and focused on one job.
def greet(name):
    """Return a greeting for the given name."""
    return f"Hello, {name}!"

greet_schema = {
    "name": "greet",
    "description": "Create a personalized greeting.",
    "parameters": {
        "type": "object",
        "properties": {
            "name": {"type": "string"}
        },
        "required": ["name"]
    }
}

# This shows a new function and schema for greetings.
# You can let the model handle more than just math.
greet_msg = [
    {"role": "user", "content": "Say hello to Jamie."}
]

greet_resp = client.chat.completions.create(
    model="gpt-4.1",
    messages=greet_msg,
    functions=[greet_schema],
    function_call="auto"
)

g_choice = greet_resp.choices[0]
if hasattr(g_choice, 'message') and hasattr(g_choice.message, 'function_call') and g_choice.message.function_call:
    g_args = json.loads(g_choice.message.function_call.arguments)
    print(greet(**g_args))
else:
    print("No greeting function called.")

# The AI will now use the greet function if the prompt requests it.
# You will see a personal greeting rendered by your code and the AI working together!
Hello, Jamie!

Mini Project: Chatbot with Multiple Functions#

  • Let us combine add and greet into a simple chatbot application.
  • The AI will decide whether to call add or greet based on your prompt.
  • Try entering a math question or ask for a greeting below.
  • You will see which function the AI calls each time!
chat_input = input("Ask anything for the chatbot: ")
chat_msg = [{"role": "user", "content": chat_input}]

combo_resp = client.chat.completions.create(
    model="gpt-4.1",
    messages=chat_msg,
    functions=[function_schema, greet_schema],
    function_call="auto"
)

combo_choice = combo_resp.choices[0]
if hasattr(combo_choice, 'message') and hasattr(combo_choice.message, 'function_call') and combo_choice.message.function_call:
    import json
    c_args = json.loads(combo_choice.message.function_call.arguments)
    fn_name = combo_choice.message.function_call.name
    if fn_name == "add":
        res = add(**c_args)
        print(f"Chatbot math result: {res}")
    elif fn_name == "greet":
        res = greet(**c_args)
        print(f"Chatbot greeting: {res}")
    else:
        print(f"Function {fn_name} not recognized.")
else:
    print("Model did not call a custom function.")

# Type a math question like 'What is 10 plus 22?' or ask for a greeting.
# The model will decide which of your functions to call and you see the output.
Chatbot math result: 10

Troubleshooting Tips#

  • If you get errors, check your API key, network, and package version.
  • Make sure your function schema matches your code exactly.
  • Read error messages. They will often tell you what is missing or wrong.
  • Print the model output to see what the AI sent back.
  • Try small changes and run again if you get stuck.

Challenge 1: Build Your Own Math Function#

  • Make a new Python function called multiply that multiplies two numbers.
  • Write the schema for your multiply function.
  • Give the schema and user messages to the model using completions.create.
  • Test with input like Multiply 6 and 7.

Challenge 2: Add Help to Your Chatbot#

  • Update the chatbot to respond with a help message when the user asks for help.
  • Try using code to check if "help" is in the chat input.
  • When help is requested, print a list of available functions and how to use them.

Recap: What You Learned#

  • You used Python to talk to the OpenAI API.
  • You learned to define real functions and describe them for the model.
  • The AI can call your code using your own schemas and tasks.
  • You made a chatbot that understands math and can greet people on request.
  • You saw basic troubleshooting for errors and missing outputs.

Keep Going and Subscribe for More Tutorials!#

  • Practice with the challenges above and try new functions.
  • Subscribe to our YouTube channel for more Python and AI tutorials.
  • Leave a comment if you have questions or want to see new topics.

Found this useful?

All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.