> ## 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，亦称工具调用 / Tool Calling）允许模型判断需要调用哪个外部函数，并生成相应的参数。模型本身不执行函数，而是将调用意图与参数返回给调用方，由调用方执行后再将结果回传给模型，以生成最终响应。

函数调用（Function Calling，亦称工具调用 / Tool Calling）允许模型判断需要调用哪个外部函数，并生成相应的参数。模型本身不执行函数，而是将调用意图与参数返回给调用方，由调用方执行后再将结果回传给模型，以生成最终响应。

这是构建「能查询天气、查询数据库、执行操作」的 AI 助手的核心机制。

## 工作流程

函数调用是多轮往返的过程：

1. 用户向模型发送问题，并提供可用工具列表。
2. 模型返回需调用的函数及参数。
3. 调用方在本地执行该函数，获得结果。
4. 调用方将执行结果回传给模型。
5. 模型基于执行结果生成最终响应。

## 步骤一：定义工具并发起请求

在请求中通过 `tools` 字段声明可用函数。每个函数使用 JSON Schema 描述其名称、用途与参数。

```json theme={null}
{
  "model": "gpt-5.4-mini",
  "messages": [
    {"role": "user", "content": "北京今天天气怎么样？"}
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "查询指定城市的当前天气",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string",
              "description": "城市名称，例如 北京、上海"
            }
          },
          "required": ["city"]
        }
      }
    }
  ],
  "tool_choice": "auto"
}
```

* `tools`：可用工具数组。
* `tool_choice`：控制工具选择策略。可选值包括：
  * `"auto"`（默认）：模型自行决定是否调用及调用哪个。
  * `"none"`：禁止调用工具，强制普通响应。
  * `{"type": "function", "function": {"name": "get_weather"}}`：强制调用指定函数。

## 步骤二：模型返回调用意图

模型不会直接回答天气，而是返回 `tool_calls`，说明需调用 `get_weather` 及参数：

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

* `finish_reason` 为 `tool_calls`，表示模型请求调用工具。
* `arguments` 为 JSON 字符串，需解析为对象。
* `id`（`call_abc123`）需在步骤四回传结果时使用。

## 步骤三：执行函数

在本地代码中执行 `get_weather("北京")`，假设得到结果：`{"temp": "25℃", "condition": "晴"}`。

## 步骤四：回传执行结果

将对话历史、模型的 tool\_calls 及执行结果一并发送。执行结果使用 `role: "tool"` 的消息表示，并通过 `tool_call_id` 对应步骤二的 `id`：

```json theme={null}
{
  "model": "gpt-5.4-mini",
  "messages": [
    {"role": "user", "content": "北京今天天气怎么样？"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "get_weather",
            "arguments": "{\"city\": \"北京\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "call_abc123",
      "content": "{\"temp\": \"25℃\", \"condition\": \"晴\"}"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "查询指定城市的当前天气",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {"type": "string", "description": "城市名称"}
          },
          "required": ["city"]
        }
      }
    }
  ]
}
```

## 步骤五：模型生成最终响应

模型基于天气数据返回自然语言响应：

```json theme={null}
{
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "北京今天天气晴朗，气温 25℃，适合外出活动。"
      },
      "finish_reason": "stop"
    }
  ]
}
```

## 完整 Python 示例

将 `API_KEY` 中的 `你的密钥` 替换为实际密钥即可运行。示例会绕过系统代理环境变量，直接请求 Moxus AI。

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

API_KEY = "你的密钥"

client = OpenAI(
    api_key=API_KEY,
    base_url="https://moxus.cloud/v1",
    # 直接连接 Moxus AI，不读取系统或终端代理环境变量。
    http_client=httpx.Client(trust_env=False, timeout=60.0),
)

def get_weather(city: str) -> dict:
    # 实际应调用天气 API
    return {"temp": "25℃", "condition": "晴"}

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "查询指定城市的当前天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"}
                },
                "required": ["city"],
            },
        },
    }
]

messages = [{"role": "user", "content": "北京今天天气怎么样？"}]

# 第一轮：模型判断是否调用工具
resp = client.chat.completions.create(
    model="gpt-5.4-mini", messages=messages, tools=tools, tool_choice="auto"
)
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 = get_weather(**args)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result, ensure_ascii=False),
        })

    # 第二轮：回传结果，获取最终响应
    final = client.chat.completions.create(model="gpt-5.4-mini", messages=messages, tools=tools)
    print(final.choices[0].message.content)
else:
    print(msg.content)
```

## 完整 Node.js 示例

将 `API_KEY` 中的 `你的密钥` 替换为实际密钥。示例只执行已声明的 `get_weather`，不要直接执行模型返回的任意函数名或参数。

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

const API_KEY = "你的密钥";

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

function getWeather(city) {
  // 实际项目中在这里调用天气 API。
  return { temp: "25℃", condition: "晴", city };
}

const tools = [
  {
    type: "function",
    function: {
      name: "get_weather",
      description: "查询指定城市的当前天气",
      parameters: {
        type: "object",
        properties: {
          city: { type: "string", description: "城市名称" },
        },
        required: ["city"],
      },
    },
  },
];

const messages = [{ role: "user", content: "北京今天天气怎么样？" }];

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(`未允许调用工具：${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);
}
```

## 并行调用多个工具

模型可能一次请求调用多个工具（`tool_calls` 数组包含多项）。需全部执行，并为每个 `id` 各回传一条 `role: "tool"` 消息。可通过 `parallel_tool_calls` 参数控制是否允许并行（默认允许）。

## 注意事项

* 并非所有模型均支持函数调用，请在模型广场确认所选模型的能力。
* `arguments` 为 JSON 字符串，需先解析。
* 工具执行结果须转为字符串（通常为 JSON 字符串）再回传。
* 每轮往返均消耗 Token（历史越长消耗越多），应注意成本。
* 模型生成的参数可能不完全符合预期，执行前应进行校验与容错。

## 后续步骤

* 强制返回规范 JSON：参阅 [结构化输出](/zh/guide/structured-output)。
* 深度推理：参阅 [推理模型](/zh/guide/reasoning)。
