Function Calling

Enable AI models to call your functions, access external APIs, and interact with the real world.

Overview

Function calling (also called "tools") allows the model to:

  • Call external APIs (weather, stocks, databases)
  • Perform calculations or data transformations
  • Take actions in your application (send email, create record)
  • Retrieve information the model doesn't have access to

Note: The model doesn't execute functions directly. It tells you which function to call and with what arguments. You execute the function and send the result back.

Defining Functions

Define functions using JSON Schema in the tools parameter:

TypeScript
const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [
    { role: 'user', content: 'What is the weather in Paris and Tokyo?' }
  ],
  tools: [
    {
      type: 'function',
      function: {
        name: 'get_weather',
        description: 'Get the current weather for a location',
        parameters: {
          type: 'object',
          properties: {
            location: {
              type: 'string',
              description: 'City name, e.g., Paris, Tokyo'
            },
            unit: {
              type: 'string',
              enum: ['celsius', 'fahrenheit'],
              description: 'Temperature unit'
            }
          },
          required: ['location']
        }
      }
    }
  ]
});

Function Definition Schema

FieldDescription
nameFunction name (a-z, A-Z, 0-9, underscores)
descriptionWhat the function does (helps the model decide when to call it)
parametersJSON Schema defining the function's arguments
strictEnable strict mode for guaranteed schema adherence

Understanding Tool Calls

When the model decides to call a function, it returns a special response:

json
{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "get_weather",
            "arguments": "{\"location\": \"Paris\", \"unit\": \"celsius\"}"
          }
        },
        {
          "id": "call_def456",
          "type": "function",
          "function": {
            "name": "get_weather",
            "arguments": "{\"location\": \"Tokyo\", \"unit\": \"celsius\"}"
          }
        }
      ]
    },
    "finish_reason": "tool_calls"
  }]
}

Key Fields

  • content is null when making tool calls
  • finish_reason is "tool_calls"
  • • Each tool call has a unique id
  • arguments is a JSON string you need to parse

Complete Flow

Here's the full pattern for handling function calls:

TypeScript
// 1. Send initial request with tools
const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'What is the weather in Paris?' }],
  tools: [weatherTool]
});

const message = response.choices[0].message;

// 2. Check if the model wants to call a function
if (message.tool_calls) {
  // 3. Execute each function call
  const toolResults = await Promise.all(
    message.tool_calls.map(async (toolCall) => {
      const args = JSON.parse(toolCall.function.arguments);
      
      // Call your actual function
      const result = await getWeather(args.location, args.unit);
      
      return {
        tool_call_id: toolCall.id,
        role: 'tool' as const,
        content: JSON.stringify(result)
      };
    })
  );

  // 4. Send results back to the model
  const finalResponse = await client.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      { role: 'user', content: 'What is the weather in Paris?' },
      message,          // Include the assistant's tool_calls message
      ...toolResults    // Include the tool results
    ],
    tools: [weatherTool]
  });

  console.log(finalResponse.choices[0].message.content);
  // "The current weather in Paris is 18°C with partly cloudy skies."
}

Controlling Tool Selection

Use tool_choice to control whether and which functions the model can call:

TypeScript
// Let the model decide (default)
tool_choice: 'auto'

// Force the model to call a specific function
tool_choice: {
  type: 'function',
  function: { name: 'get_weather' }
}

// Force the model to call any function
tool_choice: 'required'

// Prevent function calls entirely
tool_choice: 'none'

Multiple Tools

You can define multiple functions for the model to choose from:

TypeScript
const tools = [
  {
    type: 'function',
    function: {
      name: 'search_web',
      description: 'Search the web for information',
      parameters: {
        type: 'object',
        properties: {
          query: { type: 'string', description: 'Search query' }
        },
        required: ['query']
      }
    }
  },
  {
    type: 'function',
    function: {
      name: 'get_stock_price',
      description: 'Get current stock price',
      parameters: {
        type: 'object',
        properties: {
          symbol: { type: 'string', description: 'Stock symbol, e.g., AAPL' }
        },
        required: ['symbol']
      }
    }
  },
  {
    type: 'function',
    function: {
      name: 'send_email',
      description: 'Send an email',
      parameters: {
        type: 'object',
        properties: {
          to: { type: 'string', description: 'Recipient email' },
          subject: { type: 'string', description: 'Email subject' },
          body: { type: 'string', description: 'Email body' }
        },
        required: ['to', 'subject', 'body']
      }
    }
  }
];

Parallel Tool Calls

Models can call multiple functions in a single response:

TypeScript
// The model can call multiple functions in parallel
const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [
    { role: 'user', content: 'Compare the weather in Paris, Tokyo, and New York' }
  ],
  tools: [weatherTool],
  parallel_tool_calls: true  // Enable parallel calls (default: true)
});

// response.choices[0].message.tool_calls will contain 3 function calls

Strict Mode

Enable strict: true to guarantee the model's output matches your schema exactly:

TypeScript
const tools = [
  {
    type: 'function',
    function: {
      name: 'create_user',
      description: 'Create a new user account',
      strict: true,  // Enable strict mode
      parameters: {
        type: 'object',
        properties: {
          name: { type: 'string' },
          email: { type: 'string', format: 'email' },
          age: { type: 'integer', minimum: 0 }
        },
        required: ['name', 'email'],
        additionalProperties: false  // Required for strict mode
      }
    }
  }
];

// With strict: true, the model will ALWAYS return valid JSON
// matching your schema exactly

Recommendation: Use strict mode in production to avoid JSON parsing errors and invalid arguments.

Best Practices

Write Clear Descriptions

The model uses descriptions to decide when to call functions. Be specific about what each function does and when to use it.

Validate Arguments

Always validate and sanitize function arguments before executing. The model might occasionally produce invalid values.

Handle Errors Gracefully

If a function fails, return a helpful error message as the tool result so the model can adapt or inform the user.

Limit Available Tools

Only include relevant tools for each request. Too many tools can confuse the model and slow down responses.

Supported Models

Function calling is supported on these models:

GPT-4o
GPT-4o-mini
GPT-4 Turbo
Claude 3.5 Sonnet
Claude 3.5 Haiku
Claude 3 Opus
Gemini 2.0 Flash
Gemini 1.5 Pro
Llama 3.3 70B
Mistral Large

Related Guides