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

# Tool calling

> Letting a model call your functions, on both the OpenAI and the Anthropic shape.

Describe the functions a model may call, and it answers with the call it wants made rather
than with prose. You run it and feed the result back.

## OpenAI shape

```json theme={null}
{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Current conditions for a city.",
        "parameters": {
          "type": "object",
          "properties": { "city": { "type": "string" } },
          "required": ["city"]
        }
      }
    }
  ],
  "tool_choice": "auto"
}
```

`tool_choice` takes `none`, `auto`, `required`, or a named function
(`{"type": "function", "function": {"name": "get_weather"}}`).

## Anthropic shape

On `/v1/messages`, tools are flat and the schema key is `input_schema`:

```json theme={null}
{
  "tools": [
    {
      "name": "get_weather",
      "description": "Current conditions for a city.",
      "input_schema": {
        "type": "object",
        "properties": { "city": { "type": "string" } },
        "required": ["city"]
      }
    }
  ],
  "tool_choice": { "type": "auto" }
}
```

`tool_choice` takes `auto`, `any`, `none`, or `{"type": "tool", "name": "…"}`. Anthropic's
server-side built-in tools are rejected by name — they would need us to run something on
your behalf, which this API does not do.

## Not every model can do this

Tool calling is a property of the model, not of the API. If no provider that can serve
your chosen model supports tools, the call is **rejected**:

```json theme={null}
{
  "error": {
    "message": "Model 'some-model' does not support 'tools'.",
    "type": "invalid_request_error",
    "code": "MODEL_CAPABILITY_UNSUPPORTED",
    "param": "tools"
  }
}
```

<Warning>
  This is deliberate, and it is the opposite of what several APIs do. Answering the prompt
  while silently ignoring your `tools` would return something that looks fine, parses
  fine, and is wrong in a way you would only discover in production — probably from a
  user. An error you cannot miss is the better failure.
</Warning>

The same rule applies to [structured outputs](/structured-outputs). Check
[`GET /v1/models`](/api-reference/list-models) for what an account can call; capability
detail lives in the [console](https://compute.prentis.ai).

## Reading the call back

The model's turn comes back with `finish_reason: "tool_calls"` and the arguments as a JSON
**string**, not an object — parse it, and be ready for it to be malformed, because a model
produced it:

```python theme={null}
call = resp.choices[0].message.tool_calls[0]
try:
    args = json.loads(call.function.arguments)
except json.JSONDecodeError:
    ...  # ask again, or fall back; do not trust it blindly
```

Then append the assistant turn and a `role: "tool"` turn carrying your result, and call
again. The conversation is yours to keep — this API stores nothing between calls.

## Next

<CardGroup cols={2}>
  <Card title="Structured outputs" icon="brackets-curly" href="/structured-outputs">
    When you want JSON back rather than a function call.
  </Card>

  <Card title="Chat completions" icon="code" href="/api-reference/chat-completions">
    Every parameter, including the two above.
  </Card>
</CardGroup>
