Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.opper.ai/llms.txt

Use this file to discover all available pages before exploring further.

Tools turn a chat from “the model writes you a sentence” into “the model can do things.” You hand it a list of functions it’s allowed to call. It decides if and when to call them, you run the actual code, and you feed the result back into the conversation. Opper’s tool calling uses the standard OpenAI-compatible tools array, so anything you’ve written against OpenAI, Anthropic, or other compat SDKs works unchanged. It’s available across all 300+ models.

The round trip

A tool call always follows the same shape:
  1. You send a chat completion request with a tools list.
  2. The model responds with a tool_use (it wants to call one).
  3. You run the tool in your code.
  4. You send the result back to the model as a tool_result message.
  5. The model uses the result to write its final response.

A working example

A weather assistant.
import os, json
from openai import OpenAI

client = OpenAI(
    base_url="https://api.opper.ai/v3/compat",
    api_key=os.environ["OPPER_API_KEY"],
)

# 1. Declare the tool
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "City name, e.g. 'Stockholm'"}
            },
            "required": ["city"],
        },
    },
}]

# 2. Your local implementation
def get_weather(city: str) -> str:
    return f"Sunny, 22°C in {city}"

# 3. First call. Model decides to use the tool.
messages = [{"role": "user", "content": "What's the weather in Stockholm?"}]
r = client.chat.completions.create(
    model="openai/gpt-5-mini",
    messages=messages,
    tools=tools,
)
msg = r.choices[0].message
messages.append(msg)

# 4. Run the tool, append the result
for call in (msg.tool_calls or []):
    args = json.loads(call.function.arguments)
    result = get_weather(**args)
    messages.append({
        "role": "tool",
        "tool_call_id": call.id,
        "content": result,
    })

# 5. Second call. Model uses the result to answer.
r = client.chat.completions.create(
    model="openai/gpt-5-mini",
    messages=messages,
    tools=tools,
)
print(r.choices[0].message.content)

Control when tools fire

The tool_choice parameter tells the model how aggressively to use tools.
ValueBehavior
"auto" (default)The model decides. Calls a tool when it makes sense, otherwise answers in text.
"none"Tools are ignored. The model has to answer from what it knows.
"required"The model must call one of the tools. Use when the answer can only come from a tool.
{"type": "function", "function": {"name": "X"}}Force a specific tool.

Parallel calls

The model can ask for several tool calls in one turn. The tool_calls array on the response can have more than one entry. Run them all (in parallel if they’re independent), then send back one tool message per call, each with its tool_call_id.

Streaming tool arguments

When you stream a tool call with stream: true, the arguments arrive as JSON fragments in delta.tool_calls[].function.arguments. Concatenate them as they come in, then parse once the call is complete. Useful for showing “I’m calling search…” UI as the call assembles. See Streaming.

Tools vs structured output

Tools and structured output look similar but do different things.
ToolsStructured output
GoalHave the model trigger an actionGet a single typed JSON object back
Round-tripsAt least two (call, result, follow-up)One
Multiple results per turnYes, parallel calls allowedNo, one object
Best forAgents, search, data lookups, side effectsExtraction, classification, parsing
If you have a clear input → output and don’t need the model to drive control flow, reach for the JSON API or structured output, not tools.

What’s next

Conversations

Multi-turn chat with message history.

Streaming

Stream tokens and tool arguments as they arrive.

Structured output

Get JSON back without the tool round-trip.

JSON API

For one-shot tasks, this is usually simpler than tools.