Tool Calling

Define tools once with the OpenAI Chat Completions format, send function results back to the model, and account for model-specific tool-choice support.

What is tool calling?#

Tool calling lets a model request a function in its response. Your application—not OpenGateway—runs the function, then sends the result back in a follow-up message. Chat Completions accepts the OpenAI-style tools and tool_choice fields; the provider adapter maps them where supported.

Define a function#

Describe the function and its JSON Schema in the Chat Completions request:

Python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["OPENGATEWAY_API_KEY"],
base_url="https://apis.opengateway.ai/v1",
)
model = "deepseek/deepseek-v4.1-flash-ultrafast"
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
"additionalProperties": False,
},
},
}]
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": "What is the weather in Seoul?"}],
tools=tools,
tool_choice="auto",
)

A tool call appears in the assistant message as tool_calls. The function arguments are JSON encoded in function.arguments:

JSON
{
"tool_calls": [{
"id": "call_example",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Seoul\"}"
}
}]
}

Run the function and return its result#

Parse the arguments, run your own function, then send a role: "tool" message with the matching tool_call_id:

Python
import json
def get_weather(city):
return {"city": city, "temperature_c": 18, "condition": "clear"}
assistant_message = response.choices[0].message
tool_call = assistant_message.tool_calls[0]
arguments = json.loads(tool_call.function.arguments)
result = get_weather(**arguments)
follow_up = client.chat.completions.create(
model=model,
messages=[
{"role": "user", "content": "What is the weather in Seoul?"},
assistant_message.model_dump(exclude_none=True),
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result),
},
],
tools=tools,
)
print(follow_up.choices[0].message.content)

Choose tools#

tool_choice accepts these OpenAI-style choices:

ValueBehavior
"auto"Let the model decide whether to call a tool.
"none"Do not call a tool.
"required"Require a tool call.
{"type":"function","function":{"name":"get_weather"}}Require the named function.

Forced choices such as "required" need at least one tool definition. Some models also restrict forced tool calls while reasoning is enabled; use a supported choice or disable reasoning only when the model allows it.

Stream tool calls#

With stream: true, function-call data arrives in choices[].delta.tool_calls. The arguments may be split across chunks, so accumulate each call’s deltas by index and parse the completed JSON only after the stream finishes. See streaming.

Model-specific support#

Tool features and accepted schemas vary by model. Use a model whose catalog entry includes chat_completions, and check its provider support before relying on forced tool choice or provider-native tool features. The gateway does not execute tools on your behalf.

See also#

Tool Calling — OpenGateway