Tool calling

Call functions in parallel

Multiple tool calls in one response, covering parallel calls to the same tool and to different tools.

Overview

Patterns where the model returns multiple tool calls in a single response, run together. Each call carries its own id; when you send results back, match them with tool_call_id on each tool message.

Parallel tool calling

In parallel tool calling, the same function is called multiple times simultaneously with different parameters. This is more efficient than making sequential calls for similar operations.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.reka.ai/v1",
    api_key=os.environ["REKA_API_KEY"],
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"]
                    }
                },
                "required": ["location"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="deepseek4-flash",
    messages=[
        {
            "role": "system",
            "content": "You are a helpful assistant that can access external functions. The responses from these function calls will be appended to this dialogue. Please provide responses based on the information from these function calls."
        },
        {
            "role": "user",
            "content": "What is the current temperature of New York, San Francisco and Chicago?"
        }
    ],
    tools=tools,
)

print(response.choices[0].message.tool_calls)

In response, the tool_calls key of the model’s response looks like this:

message.tool_calls
[
  {
    "id": "call_aisak3q1px3m2lzb41ay6rwf",
    "type": "function",
    "function": {
      "name": "get_current_weather",
      "arguments": "{\"location\": \"New York, NY\", \"unit\": \"fahrenheit\"}"
    }
  },
  {
    "id": "call_agrjihqjcb0r499vrclwrgdj",
    "type": "function",
    "function": {
      "name": "get_current_weather",
      "arguments": "{\"location\": \"San Francisco, CA\", \"unit\": \"fahrenheit\"}"
    }
  },
  {
    "id": "call_17s148ekr4hk8m5liicpwzkk",
    "type": "function",
    "function": {
      "name": "get_current_weather",
      "arguments": "{\"location\": \"Chicago, IL\", \"unit\": \"fahrenheit\"}"
    }
  }
]

The model returns three function calls. You can execute them programmatically, in parallel, to answer the user’s question.

parallel_tool_calls: false guarantees at most one tool call per response on every model; the gateway enforces it. When streaming, only index: 0 deltas are sent.

Parallel multiple tool calling

This pattern combines parallel and multiple tool calling: multiple different functions are available, and one user prompt triggers multiple different function calls simultaneously. The model chooses which functions to call and calls them in parallel.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.reka.ai/v1",
    api_key=os.environ["REKA_API_KEY"],
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"]
                    }
                },
                "required": ["location"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_current_stock_price",
            "description": "Get the current stock price for a given stock symbol",
            "parameters": {
                "type": "object",
                "properties": {
                    "symbol": {
                        "type": "string",
                        "description": "The stock symbol, e.g. AAPL, GOOGL, TSLA"
                    },
                    "exchange": {
                        "type": "string",
                        "description": "The stock exchange (optional)",
                        "enum": ["NYSE", "NASDAQ", "LSE", "TSX"]
                    }
                },
                "required": ["symbol"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="deepseek4-flash",
    messages=[
        {
            "role": "user",
            "content": "What's the current price of Apple and Google stock? What is the weather in New York, San Francisco and Chicago?"
        }
    ],
    tools=tools,
)

print(response.choices[0].message.tool_calls)

This produces five function calls: two for stock prices (Apple and Google) and three for weather (New York, San Francisco, and Chicago), all executed in parallel.

message.tool_calls
[
  {
    "id": "call_8b31727cf80f41099582a259",
    "type": "function",
    "function": { "name": "get_current_stock_price", "arguments": "{\"symbol\": \"AAPL\"}" }
  },
  {
    "id": "call_b54bcaadceec423d82f28611",
    "type": "function",
    "function": { "name": "get_current_stock_price", "arguments": "{\"symbol\": \"GOOGL\"}" }
  },
  {
    "id": "call_f1118a9601c644e1b78a4a8c",
    "type": "function",
    "function": { "name": "get_current_weather", "arguments": "{\"location\": \"New York, NY\"}" }
  },
  {
    "id": "call_95dc5028837e4d1e9b247388",
    "type": "function",
    "function": { "name": "get_current_weather", "arguments": "{\"location\": \"San Francisco, CA\"}" }
  },
  {
    "id": "call_1b8b58809d374f15a5a990d9",
    "type": "function",
    "function": { "name": "get_current_weather", "arguments": "{\"location\": \"Chicago, IL\"}" }
  }
]

The order of calls and whether optional arguments such as unit are filled in varies by model. Don’t rely on position; dispatch on function.name and parse function.arguments for each call.

Next: Agentic tool calling patterns.

Next steps