# 工具调用（Function Calling）

> 通过 BigModel.io 让 GLM、Kimi、DeepSeek 等模型调用你的函数，支持 OpenAI tools 与 Anthropic tool use，附完整的请求循环示例。

网页版: https://bigmodel.io/zh-cn/docs/tool-calling · 更新于 2026-10-18

工具调用让模型请求你的代码执行某个函数，再根据结果作答。BigModel.io 在 Chat Completions 上转发标准的 OpenAI `tools` 格式，在 Messages 上转发 Anthropic `tools` 格式。模型调用工具的效果取决于模型本身。

| 发送内容 | 适用范围 |
|---|---|
| `tools`、`tool_choice`（以及旧版 `functions`、`function_call`） | 所有分组的 `/v1/chat/completions` |
| Anthropic `tools`，配合 `tool_use` / `tool_result` 块 | 支持 Messages 的分组的 `/v1/messages` |

在 GLM、DeepSeek 分组上，请求体原样转发给模型供应方，模型支持的工具参数都能生效。在 Chat Completions 会被转换成其他协议的分组上，`tools`、`tool_choice`、`functions`、`function_call` 会保留，但 `parallel_tool_calls` 等其他字段会被丢弃。

使用前请在[模型目录](https://bigmodel.io/zh-cn/models)的模型页面确认有「工具调用」标签。

## 发起一次工具调用

完整流程分三步：发送工具定义，执行模型请求的函数，再把结果发回。

```python [Python]
import json, os
from openai import OpenAI

client = OpenAI(base_url="https://bigmodel.io/v1", api_key=os.environ["BIGMODEL_API_KEY"])

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

def get_weather(city):
    return {"city": city, "temp_c": 21, "sky": "clear"}  # 换成你的真实查询

messages = [{"role": "user", "content": "杭州现在天气怎么样？"}]
first = client.chat.completions.create(model="glm-5.3", messages=messages, tools=tools)
msg = first.choices[0].message

if msg.tool_calls:
    messages.append(msg)  # 保留带 tool_calls 的 assistant 消息
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(get_weather(**args)),
        })
    final = client.chat.completions.create(model="glm-5.3", messages=messages, tools=tools)
    print(final.choices[0].message.content)
else:
    print(msg.content)
```

```js [Node.js]
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://bigmodel.io/v1", apiKey: process.env.BIGMODEL_API_KEY });

const tools = [{
  type: "function",
  function: {
    name: "get_weather",
    description: "查询某个城市的当前天气",
    parameters: { type: "object", properties: { city: { type: "string" } }, required: ["city"] },
  },
}];
const getWeather = ({ city }) => ({ city, temp_c: 21, sky: "clear" });

const messages = [{ role: "user", content: "杭州现在天气怎么样？" }];
const first = await client.chat.completions.create({ model: "glm-5.3", messages, tools });
const msg = first.choices[0].message;

if (msg.tool_calls?.length) {
  messages.push(msg);
  for (const call of msg.tool_calls) {
    const result = getWeather(JSON.parse(call.function.arguments));
    messages.push({ role: "tool", tool_call_id: call.id, content: JSON.stringify(result) });
  }
  const final = await client.chat.completions.create({ model: "glm-5.3", messages, tools });
  console.log(final.choices[0].message.content);
} else {
  console.log(msg.content);
}
```

```bash [cURL]
curl https://bigmodel.io/v1/chat/completions \
  -H "Authorization: Bearer $BIGMODEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-5.3",
    "messages": [{"role": "user", "content": "杭州现在天气怎么样？"}],
    "tools": [{"type":"function","function":{"name":"get_weather","description":"查询某个城市的当前天气","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}}]
  }'
```

`tool_choice` 控制调用方式：`"auto"`（默认）、`"none"`、`"required"`，或 `{"type":"function","function":{"name":"get_weather"}}` 强制调用某个函数。`"required"` 和强制指定函数的支持程度因模型而异。

## Messages API 的工具调用

在支持 `/v1/messages` 的分组上使用 Anthropic 格式：模型返回 `tool_use` 块，你用带相同 `id` 的 `tool_result` 块回复。

```python [Python]
import os
from anthropic import Anthropic

client = Anthropic(base_url="https://bigmodel.io", api_key=os.environ["BIGMODEL_API_KEY"])
tools = [{
    "name": "get_weather",
    "description": "查询某个城市的当前天气",
    "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
}]
messages = [{"role": "user", "content": "杭州现在天气怎么样？"}]

first = client.messages.create(model="glm-5.3", max_tokens=512, tools=tools, messages=messages)
if first.stop_reason == "tool_use":
    call = next(b for b in first.content if b.type == "tool_use")
    messages += [
        {"role": "assistant", "content": first.content},
        {"role": "user", "content": [{"type": "tool_result", "tool_use_id": call.id, "content": '{"temp_c": 21}'}]},
    ]
    final = client.messages.create(model="glm-5.3", max_tokens=512, tools=tools, messages=messages)
    print(final.content[0].text)
```

## 流式工具调用

流式输出时，工具参数会分段出现在 `choices[0].delta.tool_calls[i].function.arguments` 中。按 `index` 拼接各段，等 `finish_reason` 为 `tool_calls` 后再解析 JSON。见[流式输出](https://bigmodel.io/zh-cn/docs/streaming)。

## 验证配置

运行 cURL 示例。响应应包含 `"finish_reason": "tool_calls"`，以及调用 `get_weather`、参数为 `{"city":"杭州"}` 的 `tool_calls` 数组。如果返回的是普通文本，说明模型选择不调用工具，可以试试 `"tool_choice": "required"` 或换一个模型。

## 常见问题排查

**模型直接用文字回答，从不调用工具。** 模型可能不支持工具，或工具描述太模糊。确认模型页面有「工具调用」标签，写清楚何时使用该工具，并尝试 `tool_choice`。

**`json.loads` 解析参数失败。** 模型偶尔会返回不合法的 JSON 参数。捕获错误并把错误信息作为工具结果发回让模型重试，或用 schema 库校验。

**供应方返回 400，指向工具结果。** 每条 `tool` 消息都需要上一条 assistant 消息中某个调用的 `tool_call_id`，并且那条 assistant 消息必须包含在 `messages` 中。

**`/v1/messages` 返回 409 `malformed_session_state`。** 历史中有 `tool_result` 的 id 对不上 `tool_use`，或思考块被修改。请原样回传 assistant 内容。

**预期调用多个工具，实际只调用一个。** 并行调用取决于模型。在转换协议的分组上 `parallel_tool_calls` 会被丢弃，无法控制。

**503 `api_error`「No available accounts」。** Key 的分组不提供该模型。见[模型 ID](https://bigmodel.io/zh-cn/docs/model-ids)。

## 相关文档

- [结构化输出](https://bigmodel.io/zh-cn/docs/structured-output)：用工具 schema 在任何分组上获得 JSON。
- [流式输出](https://bigmodel.io/zh-cn/docs/streaming)与[推理与思考](https://bigmodel.io/zh-cn/docs/reasoning)。
- [Chat Completions API 参考](https://bigmodel.io/zh-cn/docs/api-chat-completions)。
