> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openp.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Function calling

> A unified guide to OpenAI Tools / Claude Tool Use / Gemini Function Calling

Function calling (also known as **tool use**) lets the model request the execution of an external function while generating a reply —
for actions like querying a database, calling an API, or reading/writing files. OpenPAI fully supports all three protocols, and they interoperate.

## OpenAI protocol

```python theme={null}
from openai import OpenAI
client = OpenAI(api_key="sk-...", base_url="https://openp.ai/v1")

tools = [{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get current weather for a city",
    "parameters": {
      "type": "object",
      "properties": {"city": {"type": "string"}},
      "required": ["city"],
    },
  },
}]

resp = client.chat.completions.create(
    model="gpt-5.5",
    messages=[{"role": "user", "content": "Weather in Shanghai"}],
    tools=tools,
)

call = resp.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)
```

After executing the function, send the result back:

```python theme={null}
messages = [
    {"role": "user", "content": "Weather in Shanghai"},
    resp.choices[0].message,            # assistant message with tool_calls
    {"role": "tool", "tool_call_id": call.id, "content": "Shanghai 26°C clear"},
]
final = client.chat.completions.create(model="gpt-5.5", messages=messages)
print(final.choices[0].message.content)
```

### tool\_choice

| Value                                             | Behavior                     |
| ------------------------------------------------- | ---------------------------- |
| `"auto"` (default)                                | The model decides on its own |
| `"none"`                                          | Force no tool call           |
| `"required"`                                      | Must call some tool          |
| `{"type": "function", "function": {"name": "x"}}` | Call a specific tool         |

### parallel\_tool\_calls

Newer models support calling multiple tools in parallel by default; `tool_calls` in the response is an array — execute each and return them all at once.
To disable parallelism, set `parallel_tool_calls: false`.

## Claude protocol

```python theme={null}
from anthropic import Anthropic
client = Anthropic(api_key="sk-...", base_url="https://openp.ai")

resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=[{
        "name": "get_weather",
        "description": "Get weather",
        "input_schema": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    }],
    messages=[{"role": "user", "content": "Weather in Shanghai"}],
)

# Find the tool_use block
for block in resp.content:
    if block.type == "tool_use":
        result = call_my_weather(block.input["city"])
        followup = client.messages.create(
            model="claude-opus-4-8",
            max_tokens=1024,
            messages=[
                {"role": "user", "content": "Weather in Shanghai"},
                {"role": "assistant", "content": resp.content},
                {"role": "user", "content": [{
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": result,
                }]},
            ],
        )
```

### tool\_choice (Claude)

```json theme={null}
{"type": "auto"}                      // default
{"type": "any"}                       // must call some tool
{"type": "tool", "name": "x"}         // a specific tool
{"type": "none"}                      // disable tools
```

## Gemini protocol

```python theme={null}
from google import genai
from google.genai import types

client = genai.Client(api_key="sk-...", http_options={"base_url": "https://openp.ai"})

weather_tool = types.Tool(function_declarations=[
    types.FunctionDeclaration(
        name="get_weather",
        description="Get weather",
        parameters={
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    )
])

resp = client.models.generate_content(
    model="gemini-3.1-pro-preview",
    contents="Weather in Shanghai",
    config=types.GenerateContentConfig(tools=[weather_tool]),
)

for part in resp.candidates[0].content.parts:
    if part.function_call:
        print(part.function_call.name, part.function_call.args)
```

Return the result:

```python theme={null}
function_response = types.Part(function_response=types.FunctionResponse(
    name="get_weather",
    response={"city": "Shanghai", "temp": 26}
))

followup = client.models.generate_content(
    model="gemini-3.1-pro-preview",
    contents=[
        types.Content(role="user", parts=[types.Part(text="Weather in Shanghai")]),
        resp.candidates[0].content,
        types.Content(role="user", parts=[function_response]),
    ],
)
```

## Protocol interoperability

When you call Claude / Gemini models via OpenPAI's **OpenAI-compatible endpoint**,
OpenPAI automatically converts the Anthropic / Google tool-calling structures to OpenAI's `tools` / `tool_calls`,
and vice versa. You **don't** need to worry about protocol differences — just pick one style.

## Best practices

<CardGroup cols={2}>
  <Card title="Detailed descriptions" icon="pen">
    The more specific a tool's `description`, the better the model decides when to call it and what arguments to pass.
  </Card>

  <Card title="Strict schema" icon="shield">
    Use `required` and `additionalProperties: false` to keep the model from passing stray fields.
  </Card>

  <Card title="Handle errors gracefully" icon="circle-exclamation">
    When a tool fails, return the error as a `tool_result` so the model can retry or change strategy.
  </Card>

  <Card title="Parallel calls" icon="layer-group">
    Execute multiple independent tools in parallel in one call to reduce latency.
  </Card>
</CardGroup>
