函数调用

以 Markdown 格式查看

函数调用让模型决定何时调用你的应用暴露的工具。OpenModels 在支持工具调用的模型上支持兼容 OpenAI 的 tools 格式。

并非每个模型都支持工具。在生产环境使用函数调用前,请验证所选模型和供应商路由的工具支持情况,因为参数支持可能因上游供应商而异。

下面的示例使用 <tool-capable-model> 作为占位符。请将其替换为你已验证支持工具调用的模型和路由。

工作方式

  1. 使用 JSON schemas 定义一个或多个工具。
  2. 将用户消息和 tools 发送到 POST /chat/completions
  3. 检查 assistant 是否返回了 tool_calls
  4. 在你的应用中执行匹配的 function。
  5. 将工具结果作为 role: "tool" 消息发回。
  6. 请求模型生成最终回答。

请求

{
"model": "<tool-capable-model>",
"route": { "provider": "<provider-for-this-model>" },
"route_mode": "balanced",
"messages": [
{
"role": "user",
"content": "What is the weather in San Francisco?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, for example San Francisco"
}
},
"required": ["city"],
"additionalProperties": false
}
}
}
],
"tool_choice": "auto"
}

如果模型选择工具,assistant 消息会包含 tool_calls

{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"San Francisco\"}"
}
}
]
}

你的应用执行 get_weather,然后发回结果:

{
"role": "tool",
"tool_call_id": "call_123",
"content": "{\"city\":\"San Francisco\",\"temperature\":\"18C\",\"condition\":\"clear\"}"
}

Python

import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.getopenmodels.com/v1",
api_key=os.environ["OM_API_KEY"],
)
def get_weather(city: str) -> dict:
return {
"city": city,
"temperature": "18C",
"condition": "clear",
}
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, for example San Francisco",
}
},
"required": ["city"],
"additionalProperties": False,
},
},
}
]
messages = [
{
"role": "user",
"content": "What is the weather in San Francisco?",
}
]
response = client.chat.completions.create(
model="<tool-capable-model>",
messages=messages,
tools=tools,
tool_choice="auto",
extra_body={
"route": {"provider": "<provider-for-this-model>"},
"route_mode": "balanced",
},
)
assistant_message = response.choices[0].message
messages.append(assistant_message.model_dump(exclude_none=True))
for tool_call in assistant_message.tool_calls or []:
if tool_call.function.name != "get_weather":
continue
arguments = json.loads(tool_call.function.arguments)
result = get_weather(city=arguments["city"])
messages.append(
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result),
}
)
final_response = client.chat.completions.create(
model="<tool-capable-model>",
messages=messages,
extra_body={
"route": {"provider": "<provider-for-this-model>"},
"route_mode": "balanced",
},
)
print(final_response.choices[0].message.content)

Node.js

import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.getopenmodels.com/v1",
apiKey: process.env.OM_API_KEY,
});
function getWeather({ city }) {
return {
city,
temperature: "18C",
condition: "clear",
};
}
const tools = [
{
type: "function",
function: {
name: "get_weather",
description: "Get current weather for a city",
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "City name, for example San Francisco",
},
},
required: ["city"],
additionalProperties: false,
},
},
},
];
const messages = [
{
role: "user",
content: "What is the weather in San Francisco?",
},
];
const response = await client.chat.completions.create({
model: "<tool-capable-model>",
route: { provider: "<provider-for-this-model>" },
route_mode: "balanced",
messages,
tools,
tool_choice: "auto",
});
const assistantMessage = response.choices[0].message;
messages.push(assistantMessage);
for (const toolCall of assistantMessage.tool_calls ?? []) {
if (toolCall.function.name !== "get_weather") {
continue;
}
const args = JSON.parse(toolCall.function.arguments);
const result = getWeather(args);
messages.push({
role: "tool",
tool_call_id: toolCall.id,
content: JSON.stringify(result),
});
}
const finalResponse = await client.chat.completions.create({
model: "<tool-capable-model>",
route: { provider: "<provider-for-this-model>" },
route_mode: "balanced",
messages,
});
console.log(finalResponse.choices[0].message.content);

工具选择

使用 tool_choice 控制模型是否可以调用工具:

行为
auto模型决定是否调用工具
none模型应在不调用工具的情况下回答
{"type":"function","function":{"name":"get_weather"}}在模型支持时强制调用指定函数

生产指南

  • 只执行应用明确 allowlist 的工具。
  • 在调用任何内部系统前,验证并解析 function.arguments
  • 保持工具 schemas 小巧、类型明确且具体。
  • 将工具输出发回模型时,把它视为不可信输入。
  • 如果模型没有返回 tool_calls,请将 assistant 消息作为普通文本响应处理。
  • 优先先使用非流式函数调用。流式工具调用需要在执行前累积部分 delta.tool_calls 参数。

计费

函数调用使用与普通聊天补全相同的积分计费方式。积分会根据输入 token、生成的输出 token、工具调用消息以及会话中包含的工具结果消耗。