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

# Function calling

> Let a model choose tools, return structured arguments, and continue after your application executes the tool.

Function calling, also called tool calling, lets a model decide when to call an external function and what arguments to pass. The model does not execute the function. Your application executes it, sends the result back, and asks the model to produce the final answer.

Use function calling to build assistants that can query databases, check order status, fetch weather, search internal systems, or trigger controlled actions.

## Workflow

1. Send the user message and a list of available tools.
2. The model returns one or more tool calls with JSON arguments.
3. Your application validates and executes the tool calls.
4. Send the tool results back as `tool` messages.
5. The model uses the results to generate the final response.

## Define tools

Declare available tools in the `tools` array. Each function uses JSON Schema for its arguments.

```json theme={null}
{
  "model": "gpt-5.4-mini",
  "messages": [
    {"role": "user", "content": "What is the weather in Beijing today?"}
  ],
  "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, such as Beijing or Shanghai"
            }
          },
          "required": ["city"]
        }
      }
    }
  ],
  "tool_choice": "auto"
}
```

`tool_choice` controls tool selection:

* `auto`: the model decides whether to call a tool.
* `none`: tool calling is disabled for this request.
* `{"type":"function","function":{"name":"get_weather"}}`: force a specific function.

## Read the tool call

When the model wants to call a tool, it returns `tool_calls`:

```json theme={null}
{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\": \"Beijing\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}
```

Parse `function.arguments` as JSON and keep the `id`. You need that ID when returning the tool result.

## Return tool results

After your application runs `get_weather`, append a `tool` message using the matching `tool_call_id`:

```json theme={null}
{
  "role": "tool",
  "tool_call_id": "call_abc123",
  "content": "{\"temp\": \"25 C\", \"condition\": \"sunny\"}"
}
```

Then send the full conversation back to the model so it can produce the final answer.

## Complete Python example

Replace `sk-your-key` in `API_KEY` with your actual key. The example bypasses system proxy environment variables and connects directly to Moxus AI.

```python theme={null}
import json
import httpx
from openai import OpenAI

API_KEY = "sk-your-key"

client = OpenAI(
    api_key=API_KEY,
    base_url="https://moxus.cloud/v1",
    # Connect directly to Moxus AI without reading system or terminal proxy variables.
    http_client=httpx.Client(trust_env=False, timeout=60.0),
)

def get_weather(city: str) -> dict:
    return {"temp": "25 C", "condition": "sunny"}

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 is the weather in Beijing today?"}]

response = client.chat.completions.create(
    model="gpt-5.4-mini",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

message = response.choices[0].message

if message.tool_calls:
    messages.append(message)
    for call in message.tool_calls:
        args = json.loads(call.function.arguments)
        result = get_weather(**args)
        messages.append(
            {
                "role": "tool",
                "tool_call_id": call.id,
                "content": json.dumps(result),
            }
        )

    final = client.chat.completions.create(
        model="gpt-5.4-mini",
        messages=messages,
        tools=tools,
    )
    print(final.choices[0].message.content)
else:
    print(message.content)
```

## Complete Node.js example

Replace `sk-your-key` in `API_KEY` with your actual key. This example executes only the declared `get_weather` function. Do not execute arbitrary function names or arguments returned by a model.

```javascript theme={null}
import OpenAI from "openai";

const API_KEY = "sk-your-key";

const client = new OpenAI({
  apiKey: API_KEY,
  baseURL: "https://moxus.cloud/v1",
});

function getWeather(city) {
  // Call a real weather API here in production.
  return { temp: "25 C", condition: "sunny", city };
}

const 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" },
        },
        required: ["city"],
      },
    },
  },
];

const messages = [{ role: "user", content: "What is the weather in Beijing today?" }];

const response = await client.chat.completions.create({
  model: "gpt-5.4-mini",
  messages,
  tools,
  tool_choice: "auto",
});

const message = response.choices[0].message;

if (message.tool_calls?.length) {
  messages.push(message);

  for (const call of message.tool_calls) {
    if (call.function.name !== "get_weather") {
      throw new Error(`Tool is not allowed: ${call.function.name}`);
    }

    const args = JSON.parse(call.function.arguments);
    const result = getWeather(args.city);
    messages.push({
      role: "tool",
      tool_call_id: call.id,
      content: JSON.stringify(result),
    });
  }

  const final = await client.chat.completions.create({
    model: "gpt-5.4-mini",
    messages,
    tools,
  });
  console.log(final.choices[0].message.content);
} else {
  console.log(message.content);
}
```

## Notes

* Validate arguments before executing a function.
* Return tool results as strings, usually serialized JSON.
* A model may request multiple tool calls in one response.
* Tool calling support depends on the selected model.
* Every additional round consumes tokens, so keep tool outputs concise.

## Next steps

* [Structured output](/en/guide/structured-output)
* [Reasoning models](/en/guide/reasoning)
