工具调用
模型可以请你的代码执行一个函数,比如查订单、查数据库,然后根据结果回答。模型自己从不执行任何东西:它返回函数名和参数,由你的代码执行,再在下一个请求里把结果发回去。
请选用模型页面 Capabilities 一行列有 tool calling 的模型。不支持的模型会忽略 tools,直接用文字回答,不会报错。
下面的示例是一个真实的文件,发布前我们都会实际运行一遍:
# pip install openai
# Tool calling: the model asks for a function, your code runs it and sends the
# result back, and the model answers with it. Any chat model whose page lists
# tool calling works the same way.
import json
import os
from openai import OpenAI
client = OpenAI(
base_url=os.getenv("OCEANTOKEN_BASE_URL", "https://api.oceantoken.ai/v1"),
api_key=os.environ["OCEANTOKEN_API_KEY"],
)
def get_weather(city):
# Your own code runs here: a database, an internal API, anything.
return {"city": city, "temperature_c": 18, "sky": "cloudy"}
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "The current weather in a city.",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string", "description": "City name, for example Lisbon"}},
"required": ["city"],
},
},
}
]
messages = [{"role": "user", "content": "What is the weather in Lisbon right now?"}]
message = client.chat.completions.create(model="openai/gpt-5-mini", messages=messages, tools=tools).choices[0].message
called = False
# While the model asks for tools, run each one and send the results back.
while message.tool_calls:
called = True
messages.append({
"role": "assistant",
"content": message.content,
"tool_calls": [call.model_dump() for call in message.tool_calls],
})
for call in message.tool_calls:
result = get_weather(**json.loads(call.function.arguments))
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
message = client.chat.completions.create(model="openai/gpt-5-mini", messages=messages, tools=tools).choices[0].message
# A model that ignores `tools` answers without calling them, and that is not an error.
if not called:
raise SystemExit("the model answered without calling the tool")
print(message.content)
调用流程
- 描述你的函数,放在
tools里:name;description,模型据此判断何时调用;parameters,用 JSON Schema 描述参数。 - 模型请求调用。 回答的
finish_reason是tool_calls,choices[0].message.tool_calls列出每个调用的id、函数name和 JSON 字符串形式的arguments。 - 执行并把结果发回去。 先把模型带
tool_calls的那条消息加进对话,再为每个调用加一条tool消息,带上该调用的tool_call_id,结果以字符串形式放在内容里。 - 带着同样的
tools再请求一次。 模型给出回答,或者请求更多调用;重复,直到tool_calls为空。
参数是模型生成的,执行前请像对待用户输入一样校验。
控制模型何时调用
用 tool_choice 控制:
| 取值 | 效果 |
|---|---|
"auto"(默认) | 由模型决定。 |
"required" | 模型必须至少调用一个工具。 |
"none" | 模型必须用文字回答。 |
{"type": "function", "function": {"name": "get_weather"}} | 模型必须调用这个函数。 |
一次多个调用
页面上列有 parallel tool calls 的模型,可以在一条消息里请求多个调用,比如同时查两个城市的天气。逐个执行,并为每个 tool_call_id 发一条 tool 消息,顺序不限;上面的循环已经这样处理了。发送 "parallel_tool_calls": false 可以让模型一次只调用一个。
流式输出
设置 stream=True 时,一个调用会分成多块出现在 choices[0].delta.tool_calls 里:每个调用的第一块带有 index、id 和 name,后面的块逐段补充 arguments。按 index 把各块拼起来,等流以 finish_reason 为 tool_calls 结束后再执行。Vercel AI SDK 等 SDK 的辅助函数会替你完成这一步(调用工具)。
使用 Anthropic Messages API
在 /v1/messages 上,工具使用 Anthropic 的格式,所有对话模型都适用:tools 里每个工具有 name、description 和 input_schema;模型以 tool_use 块回答,stop_reason 为 tool_use;你在一条 user 消息里用 tool_result 块把结果发回去。Anthropic SDK 填基础地址 https://api.oceantoken.ai 即可原样使用。
费用
工具定义是提示的一部分,每个带着它的请求都按输入 token 计费,每一轮往返都是一个单独的请求。很长又不变的工具列表适合用提示缓存。