工具调用
OpenAI 兼容的 tools / tool_choice 参数、函数 schema 定义、tool_calls 响应与多轮回填、并行工具调用注意事项与完整 JSON 示例
平台数据平面采用 OpenAI 规范兼容的接口形态,原生支持工具调用(function calling):您把可供模型调用的函数以 tools 参数声明给模型,模型在需要时返回一个或多个工具调用意图,您在本地执行后把结果回填,模型据此继续作答。本页说明 tools / tool_choice 参数、函数 schema 的写法、tool_calls 响应的读取与多轮回填流程,以及并行工具调用的注意事项。
平台只透传工具调用协议。 平台不代为执行任何工具——工具的实际执行(如查询订单、调用内部接口、检索资料等)发生在您的应用侧。平台负责把您声明的
tools透传给模型、把模型返回的tool_calls透传给您,并对每次请求 / 响应施加安全护栏处置。
1. 工具调用的整体流程
一次完整的工具调用通常经历多轮对话,在同一个 /v1/chat/completions 入口上完成:
| 轮次 | 谁做 | 做什么 |
|---|---|---|
| 第 1 轮请求 | 您 | 在请求中带上 messages 与 tools(可声明若干可调用函数) |
| 第 1 轮响应 | 平台 / 模型 | 模型判断需要调用工具,返回 finish_reason: "tool_calls" 与 tool_calls 数组 |
| 本地执行 | 您 | 按 tool_calls 在本地执行对应函数,得到结果 |
| 第 2 轮请求 | 您 | 把上一轮的 assistant 消息与每个工具结果(role: "tool")一并回填,再次请求 |
| 第 2 轮响应 | 平台 / 模型 | 模型据工具结果给出最终自然语言回答(finish_reason: "stop") |
2. 声明工具:tools 参数
tools 是一个数组,每个元素描述一个可被模型调用的函数。函数以 type: "function" 声明,function 对象内给出函数名、用途说明与参数 schema(标准 JSON Schema):
{
"tools": [
{
"type": "function",
"function": {
"name": "query_order_status",
"description": "按订单号查询订单的当前状态与预计送达时间",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "订单号,形如 SO-20260615-0001"
},
"include_logistics": {
"type": "boolean",
"description": "是否一并返回物流轨迹,默认 false"
}
},
"required": ["order_id"]
}
}
}
]
}| 字段 | 含义 |
|---|---|
type | 固定为 "function"(标识这是一个函数工具) |
function.name | 函数名,模型按此名发起调用;建议用小写下划线命名、在同一请求内唯一 |
function.description | 函数用途说明;写得清晰准确有助于模型判断"何时该调用、传什么参数" |
function.parameters | 参数定义,标准 JSON Schema;properties 描述各参数,required 列出必填项 |
schema 写得越清楚,调用越准。 模型依据
description与参数 schema 决定是否调用以及如何填参。为每个参数写明含义、格式与取值约束(如枚举、范围),能显著降低参数缺失或取值错误的概率。
3. 约束调用行为:tool_choice 参数
tool_choice 控制模型在本轮是否、以及如何使用工具:
| 取值 | 含义 |
|---|---|
"auto"(默认) | 由模型自行判断本轮是否调用工具、调用哪个 |
"none" | 本轮不调用任何工具,直接以自然语言作答 |
"required" | 本轮必须至少调用一个工具 |
{ "type": "function", "function": { "name": "<函数名>" } } | 强制本轮调用指定的某个函数 |
{
"model": "<模型名>",
"messages": [ /* ... */ ],
"tools": [ /* ... */ ],
"tool_choice": "auto"
}工具能力以模型清单标注为准。 并非所有模型都支持工具调用。某个模型是否支持
tools/tool_choice、是否支持并行工具调用,以 模型列表接口 返回的能力标注为准;对不支持工具调用的模型传入tools,平台会按该模型的能力据实处理。
4. 读取 tool_calls 响应
当模型决定调用工具时,响应的 finish_reason 为 "tool_calls",message 中携带 tool_calls 数组(此时 content 通常为空):
{
"object": "chat.completion",
"model": "<本次实际路由的模型名>",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_a1b2c3",
"type": "function",
"function": {
"name": "query_order_status",
"arguments": "{\"order_id\":\"SO-20260615-0001\",\"include_logistics\":true}"
}
}
]
},
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0,
"cached_input_tokens": 0,
"price_tier": "<本次适用单价档>",
"thinking": false
}
}| 字段 | 含义 |
|---|---|
tool_calls[].id | 本次工具调用的唯一标识;回填结果时须原样带回(见下一节 tool_call_id) |
tool_calls[].type | 固定为 "function" |
tool_calls[].function.name | 模型要调用的函数名 |
tool_calls[].function.arguments | 模型生成的入参,为 JSON 字符串(需在本地 JSON.parse 后使用) |
arguments 是字符串、需自行解析。
arguments字段是 JSON 文本而非已解析对象;请在本地解析后再执行函数,并对取值做必要校验(模型偶有幻觉参数)。工具调用产生的输入 / 输出统一计价词元,仍按常规 6 档口径 计量,逐条记录可复核。
5. 多轮回填工具结果
执行完函数后,把上一轮的 assistant 消息与每个工具结果追加到 messages 后再次请求。工具结果用 role: "tool" 消息表达,并以 tool_call_id 对应到具体的某次调用:
curl https://<平台入口地址>/v1/chat/completions \
-H "Authorization: Bearer <您的 API 密钥>" \
-H "Content-Type: application/json" \
-d '{
"model": "<模型名>",
"messages": [
{ "role": "user", "content": "帮我查一下订单 SO-20260615-0001 的状态和物流。" },
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_a1b2c3",
"type": "function",
"function": {
"name": "query_order_status",
"arguments": "{\"order_id\":\"SO-20260615-0001\",\"include_logistics\":true}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_a1b2c3",
"content": "{\"status\":\"已发货\",\"eta\":\"2026-06-18\",\"logistics\":[\"已揽收\",\"运输中\"]}"
}
],
"tools": [ /* 同首轮的 tools 声明 */ ]
}'| 回填要点 | 说明 |
|---|---|
| 保留 assistant 消息 | 回填时必须把模型上一轮返回的、含 tool_calls 的 assistant 消息原样放回 messages,模型才能把结果对应到自己的调用意图 |
| 每个调用对应一条 tool 消息 | 模型一轮可能发起多个 tool_calls;每个 id 都要有一条 role: "tool"、tool_call_id 与之匹配的结果消息 |
| content 为结果文本 | 工具结果放在 tool 消息的 content(建议为紧凑 JSON 字符串),模型据此生成最终回答 |
| 再带回 tools | 多轮中通常继续带上 tools,以便模型在需要时发起后续调用 |
| 收敛与续轮 | 回填后模型通常返回 finish_reason: "stop" 的自然语言最终回答;若仍需更多信息,模型可能再次返回 tool_calls,重复"执行 → 回填"直至作答完成 |
6. 并行工具调用注意事项
部分模型支持在一轮内同时发起多个工具调用(tool_calls 数组含多个元素)以并行获取多项信息。使用时请注意:
- 逐个回填、id 一一对应。 一轮的多个调用需各自执行,并为每个
tool_calls[].id回填一条tool_call_id匹配的tool消息;遗漏任何一条都会导致模型无法完整收敛。 - 并行能力以模型清单标注为准。 是否支持并行工具调用因模型而异,以 模型列表接口 返回的能力标注为准;对不支持并行的模型,模型一轮通常只返回单个调用,分多轮完成。
- 执行顺序由您把控。 平台只透传调用意图,多个工具的本地执行顺序、并发与超时由您的应用控制;建议对外部依赖设置超时与降级,避免单个工具阻塞整轮。
- 计量按实计入。 工具调用各轮的输入 / 输出统一计价词元各自按 6 档口径 计入;多轮工具对话会产生多条逐条调用记录,可在用量明细中按调用复核。
- 避免无限循环。 在应用侧为"工具调用—回填"的轮数设上限;对模型反复请求同一工具的情形做兜底(如达上限后改用
tool_choice: "none"强制其直接作答),防止异常下的多轮空转。
7. 安全护栏与工具调用
工具调用的每一轮请求与响应同样经过平台 安全护栏 处置:注入防护会识别试图通过工具参数或工具结果越过指令边界的构造内容;敏感信息脱敏在输入与输出侧同样生效,工具结果中如含可识别个人信息会按规则脱敏;命中应拒答类内容时本轮返回结构化拒答。护栏处置结果随逐条记录标注,可在 用量明细 中按请求复核。