跳到主要内容

工具调用

模型可以请你的代码执行一个函数,比如查订单、查数据库,然后根据结果回答。模型自己从不执行任何东西:它返回函数名和参数,由你的代码执行,再在下一个请求里把结果发回去。

请选用模型页面 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)

调用流程​

  1. 描述你的函数,放在 tools 里:name;description,模型据此判断何时调用;parameters,用 JSON Schema 描述参数。
  2. 模型请求调用。 回答的 finish_reason 是 tool_calls,choices[0].message.tool_calls 列出每个调用的 id、函数 name 和 JSON 字符串形式的 arguments。
  3. 执行并把结果发回去。 先把模型带 tool_calls 的那条消息加进对话,再为每个调用加一条 tool 消息,带上该调用的 tool_call_id,结果以字符串形式放在内容里。
  4. 带着同样的 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 计费,每一轮往返都是一个单独的请求。很长又不变的工具列表适合用提示缓存。

下一步​

  • 只需要 JSON、不需要调用函数时,用结构化输出。
  • 编程智能体:每一轮都要调用工具的智能体,以及和它们一起测试过的模型。