Tools & reasoning
Function calling, structured output, and controlling reasoning (thinking) for GPT, Claude and Gemini.
Tool calling (OpenAI format)
Declare functions in tools and let the model decide whether to call them; after you run a function, send the result back with role: "tool":
Python
import json
from openai import OpenAI
client = OpenAI(api_key="sk-xxx", base_url="https://api.onefast.ai/v1")
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
messages = [{"role": "user", "content": "What's the weather in Shanghai right now?"}]
resp = client.chat.completions.create(model="gpt-5.5", messages=messages, tools=tools)
msg = resp.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = {"city": args["city"], "temp_c": 22, "sky": "cloudy"} # replace with your real function
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result, ensure_ascii=False)})
final = client.chat.completions.create(model="gpt-5.5", messages=messages, tools=tools)
print(final.choices[0].message.content)
The same code works with model set to claude-sonnet-4-6 or gemini-2.5-flash; the gateway converts it to each provider's tool format. Parallel tool calls (several tool_calls in one response) are supported too.
Tool calling (Claude native)
Python
import anthropic
client = anthropic.Anthropic(api_key="sk-xxx", base_url="https://api.onefast.ai")
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=[{
"name": "get_weather",
"description": "Get the current weather for a city",
"input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
}],
messages=[{"role": "user", "content": "What's the weather in Shanghai right now?"}],
)
for block in resp.content:
if block.type == "tool_use":
print(block.name, block.input)
Structured output
Ask the model to output JSON only:
{
"model": "gpt-5.5",
"response_format": {"type": "json_object"},
"messages": [
{"role": "system", "content": "Respond in JSON with the fields name and age"},
{"role": "user", "content": "John is 30 years old this year"}
]
}
To enforce a specific schema, use {"type": "json_schema", "json_schema": {...}} (if the model supports it).
Reasoning (thinking) control
Parameters differ by provider; pick the one for the protocol you use:
| Model | Protocol | Parameter |
|---|---|---|
| GPT reasoning models | Chat Completions | "reasoning_effort": "low" | "medium" | "high" |
| GPT reasoning models | Responses | "reasoning": {"effort": "high", "summary": "auto"} |
| Claude | Messages | "thinking": {"type": "enabled", "budget_tokens": 8000} (max_tokens must be greater than budget_tokens) |
| Gemini 2.5+ | Gemini native | "generationConfig": {"thinkingConfig": {"thinkingBudget": 1024}} |
All reasoning / thinking tokens are billed as output. A larger thinking budget means higher cost and latency per request; for simple tasks, use low effort or turn thinking off.