工具调用(Function Calling)
通过 BigModel.io 让 GLM、Kimi、DeepSeek 等模型调用你的函数,支持 OpenAI tools 与 Anthropic tool use,附完整的请求循环示例。
工具调用让模型请求你的代码执行某个函数,再根据结果作答。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 等其他字段会被丢弃。
使用前请在模型目录的模型页面确认有「工具调用」标签。
#发起一次工具调用
完整流程分三步:发送工具定义,执行模型请求的函数,再把结果发回。
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)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);
}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 块回复。
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。见流式输出。
#验证配置
运行 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。
#相关文档
- 结构化输出:用工具 schema 在任何分组上获得 JSON。
- 流式输出与推理与思考。
- Chat Completions API 参考。
更新于 · 以 Markdown 查看