函数调用与工具
函数调用允许把模型接入你的业务系统中,例如查询数据、修改状态或调用外部 API。 你只需要声明可用工具,模型会根据用户问题判断是否调用工具,以及应该传入哪些参数。
build
模型不会直接执行你的代码。
它只会以 JSON 参数对象的形式生成结构化意图。
真正的函数执行由你的应用完成,执行结果再作为
tool 消息回传给模型。
工具调用流程
一次完整的工具调用往返包含四步:
-
声明工具
每个工具都用一份 JSON Schema 描述,包含名称、用途和参数说明。
-
发起请求
在对话补全调用中带上
tools数组。也可以通过tool_choice强制调用、禁止调用或者指定某个函数。 -
执行并回传
当
finish_reason为tool_calls时,按顺序执行模型请求的工具调用,并将结果以role: "tool"的消息追加到对话中。 -
让模型收尾
带上更新后的对话历史再次调用 API,模型会结合工具结果生成最终自然语言类型的回复。
声明工具
一个工具定义包含三部分:name、description 和 JSON Schema 形式的 parameters。
tips_and_updates
建议清晰地描述工具用途和参数含义,这会影响模型是否能正确选择和填写参数。
[
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取某个城市的当前气温。",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "IANA 城市名称,例如 '上海'。"},
"unit": {"type": "string", "enum": ["c", "f"]}
},
"required": ["city"]
}
}
}
]
工具调用控制
tool_choice | 行为 |
|---|---|
"auto" (默认) | 由模型自行决定调用工具或者直接回答。 |
"none" | 本次请求忽略工具。 |
"required" | 模型必须调用至少一个工具。 |
{"type":"function","function":{"name":"get_weather"}} | 强制调用指定工具。 |
端到端示例
一轮完整流程包含:声明工具、模型请求工具调用、应用侧执行工具、回传结果,获取最终回答。
下面示例展示了一个完整的工具调用流程,使用 Python 或 Node.js SDK 调用接口。
import json, os
from openai import OpenAI
client = OpenAI(base_url="https://api.wylon.cn/v1", api_key=os.environ["WYLON_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": 22}
messages = [{"role": "user", "content": "上海现在天气如何?"}]
# 1. 模型决定调用工具
first = client.chat.completions.create(
model="moonshotai/kimi-k2.5", messages=messages, tools=tools,
)
messages.append(first.choices[0].message)
# 2. 执行每次工具调用并追加结果
for call in first.choices[0].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),
})
# 3. 让模型生成最终答案
final = client.chat.completions.create(
model="moonshotai/kimi-k2.5", messages=messages, tools=tools,
)
print(final.choices[0].message.content)
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.wylon.cn/v1", apiKey: process.env.WYLON_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: 22 });
const messages = [{ role: "user", content: "上海现在天气如何?" }];
const first = await client.chat.completions.create({ model: "moonshotai/kimi-k2.5", messages, tools });
messages.push(first.choices[0].message);
for (const call of first.choices[0].message.tool_calls ?? []) {
const args = JSON.parse(call.function.arguments);
messages.push({ role: "tool", tool_call_id: call.id, content: JSON.stringify(getWeather(args.city)) });
}
const final = await client.chat.completions.create({ model: "moonshotai/kimi-k2.5", messages, tools });
console.log(final.choices[0].message.content);
并行工具调用
部分模型可以在一轮回复中发起多次工具调用。
- 遍历
message.tool_calls; - 为每次调用追加一条以
tool_call_id为键的role: "tool"消息; - 下一次调用模型时,它会综合这些工具结果继续生成回复。
最佳实践
- 工具名以动词命名。建议使用
get_weather、create_ticket,不要只写weather或ticket。 - 描述每个参数。包含单位、格式、枚举值范围等信息。
- 控制工具数量。单次请求放入 10–20 个工具较为稳妥;工具过多时,建议先通过检索筛选出候选工具。
- 校验输入。使用 Schema 校验可在真正执行代码前拦截异常参数。
- 返回结构化 JSON。相比自然语言描述,结构化结果更容易被模型理解和继续使用。