Tool Calling (Function Calling)
Enable your AI models to call external functions and APIs using OpenAI-compatible tool calling.
Overview
Tool calling allows models to generate structured JSON arguments for functions you define. Instead of answering from their training data, models can request that your application executes a function and returns the result - enabling real-time data access, calculations, and external API integrations.
Oxlo's tool calling is fully compatible with the OpenAI tools API format, so you can switch providers without changing your code.
Supported Models
The following models support tool calling with both single and parallel tool invocation:
| Model | Single Tool | Parallel Tools | Notes |
|---|---|---|---|
| deepseek-v3-0324 | |||
| deepseek-v3.2 | |||
| deepseek-v4-flash | 1M context | ||
| deepseek-r1-0528 | Reasoning model - intermittent multi-tool | ||
| llama-4-maverick-17b | |||
| llama-3.3-70b | Azure limits to 1 tool definition | ||
| qwen-3-32b | |||
| qwen-3-coder-30b | |||
| gpt-oss-120b | |||
| gpt-oss-20b | |||
| kimi-k2.5 | |||
| kimi-k2.6 | Also supports reasoning | ||
| kimi-k2-thinking | |||
| oxlo-claw | GPT-4o class | ||
| mistral-7b | |||
| glm-5 | |||
| minimax-m2.5 |
Basic Usage
Define your tools in the tools array and set tool_choice to "auto". The model will decide when to call a tool based on the user's message.
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_API_KEY"
)
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather in a city",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location"]
}
}
}]
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=tools,
tool_choice="auto"
)
# Check if the model wants to call a tool
choice = response.choices[0]
if choice.finish_reason == "tool_calls":
for tool_call in choice.message.tool_calls:
print(f"Function: {tool_call.function.name}")
print(f"Arguments: {tool_call.function.arguments}")
Multi-Step Tool Calling
After executing a tool, send the result back to the model to continue the conversation. This enables multi-step workflows where the model reasons about tool results.
import json
# Step 1: Model requests a tool call
response = client.chat.completions.create(
model="kimi-k2.6",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=tools,
tool_choice="auto"
)
tool_call = response.choices[0].message.tool_calls[0]
# Step 2: Execute the function (your code)
weather_result = {"temperature": 22, "condition": "Sunny", "unit": "celsius"}
# Step 3: Send result back to the model
messages = [
{"role": "user", "content": "What's the weather in Tokyo?"},
response.choices[0].message, # assistant message with tool_calls
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(weather_result)
}
]
# Model generates final answer using the tool result
final = client.chat.completions.create(
model="kimi-k2.6",
messages=messages,
tools=tools
)
print(final.choices[0].message.content)
# "The weather in Tokyo is 22°C and sunny!"
Limitations
Llama 3.3 70B: Only supports 1 tool definition per request. If you send multiple tools, Oxlo automatically truncates to the first tool and retries.
DeepSeek R1 models: Reasoning models (R1-70B, R1-8B) do not support tool calling. If tools are sent, Oxlo gracefully falls back to a text response.
Gemma 3 models: Gemma 3 (27B, 4B) outputs tool calls as code blocks rather than structured JSON. Structured tool_calls support is planned.