tokrouterdocs
使用指南

工具调用

function calling 的完整循环:声明工具、读 tool_calls、回填结果,再让模型给出最终答案。

工具调用是两轮以上的交互:模型不会自己执行函数,它只输出「我想调用哪个函数、参数是什么」, 由你的代码执行后把结果回填,模型再据此回答。

第一轮:声明工具

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

resp = client.chat.completions.create(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "北京现在多少度?"}],
    tools=tools,
)
msg = resp.choices[0].message
print(msg.tool_calls)
# [ChatCompletionMessageToolCall(id='call_...', function=Function(name='get_weather', arguments='{"city":"北京"}'))]

第二轮:回填结果

import json

messages = [{"role": "user", "content": "北京现在多少度?"}, msg]
for call in msg.tool_calls:
    result = get_weather(**json.loads(call.function.arguments))
    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", messages=messages, tools=tools)
print(final.choices[0].message.content)

tool_call_id 必须与模型给出的 id 一一对应 —— 这是多工具并行调用时唯一的配对依据。

常见问题

现象原因
模型不调用工具,直接回答工具 description 写得太笼统;或模型本身不支持 tool use
arguments 不是合法 JSON用 json.loads 包一层 try,失败时把错误回填给模型让它重试
并行调用时结果串了按 tool_call_id 配对,不要按数组下标

结构化输出与工具调用的区别

工具调用是「让模型决定调用什么」,结构化输出是「让模型的回答符合固定 schema」。 后者见结构化输出。