Function Calling

How It Works

  1. You send a request with a tools array defining available functions.
  2. The model decides whether to call a function and responds with a tool_calls array.
  3. Your code executes the function and collects the result.
  4. You send the result back as a message with role: "tool".
  5. The model incorporates the result and generates a final response.

Defining Tools

Each tool has a type (always "function"), a name, a description, and a JSON Schema for parameters:

config.json
json
{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get the current weather for a given city. Returns temperature in Celsius and conditions.",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string",
              "description": "City name, e.g. 'San Francisco'"
            },
            "unit": {
              "type": "string",
              "enum": ["celsius", "fahrenheit"],
              "description": "Temperature unit"
            }
          },
          "required": ["city"]
        }
      }
    }
  ]
}

Write clear, specific descriptions. The model uses these to decide when to call each function.

Supported Models

Function calling is supported by most chat models:

  • OpenAI: GPT-4.1, GPT-4.1-mini, GPT-4.1-nano, GPT-4o, GPT-5, o3, o4-mini
  • Anthropic: Claude Opus 4, Claude Sonnet 4, Claude Haiku 3.5
  • Google: Gemini 2.5 Pro, Gemini 2.5 Flash
  • DeepSeek: DeepSeek V3, DeepSeek R1
  • Qwen: Qwen3, Qwen-Plus, Qwen-Max

Complete Example: Weather Query

This example shows a full multi-turn conversation with function calling.

example.py
python
from openai import OpenAI
import json

client = OpenAI(
    base_url="https://api.chuizi.ai/v1",
    api_key="ck-your-key-here",
)

# Define the tool
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather for a city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "City name"},
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "Temperature unit",
                    },
                },
                "required": ["city"],
            },
        },
    }
]

# Step 1: Send the initial request with tools
messages = [{"role": "user", "content": "What's the weather in Tokyo and London?"}]

response = client.chat.completions.create(
    model="openai/gpt-4.1",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

assistant_message = response.choices[0].message

# Step 2: The model returns tool_calls
if assistant_message.tool_calls:
    # Add the assistant's message (with tool_calls) to the conversation
    messages.append(assistant_message)

    # Step 3: Execute each function and add results
    for tool_call in assistant_message.tool_calls:
        args = json.loads(tool_call.function.arguments)

        # Your actual function implementation
        if tool_call.function.name == "get_weather":
            # In production, this would call a real weather API
            result = {
                "city": args["city"],
                "temperature": 22,
                "unit": args.get("unit", "celsius"),
                "conditions": "partly cloudy",
            }

        # Add the tool result to the conversation
        messages.append(
            {
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result),
            }
        )

    # Step 4: Send results back to get the final response
    final_response = client.chat.completions.create(
        model="openai/gpt-4.1",
        messages=messages,
        tools=tools,
    )
    print(final_response.choices[0].message.content)

Tips

  • Write detailed descriptions. The model relies on description fields to decide which function to call and how to fill parameters. Vague descriptions lead to wrong calls.
  • Validate arguments. The model may produce invalid JSON or missing fields. Always validate before executing.
  • Limit the number of tools. Providing too many tools (>20) can degrade model performance. Group related functionality into fewer, broader tools.
  • Use tool_choice: "required" when you know the user's intent requires a function call. This prevents the model from generating a text response instead.

Next Steps