函数调用
函数调用
函数调用让模型决定何时调用你的应用暴露的工具。OpenModels 在支持工具调用的模型上支持兼容 OpenAI 的 tools 格式。
并非每个模型都支持工具。在生产环境使用函数调用前,请验证所选模型和供应商路由的工具支持情况,因为参数支持可能因上游供应商而异。
下面的示例使用 <tool-capable-model> 作为占位符。请将其替换为你已验证支持工具调用的模型和路由。
工作方式
- 使用 JSON schemas 定义一个或多个工具。
- 将用户消息和
tools发送到POST /chat/completions。 - 检查 assistant 是否返回了
tool_calls。 - 在你的应用中执行匹配的 function。
- 将工具结果作为
role: "tool"消息发回。 - 请求模型生成最终回答。
请求
{"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 jsonimport osfrom openai import OpenAIclient = 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].messagemessages.append(assistant_message.model_dump(exclude_none=True))for tool_call in assistant_message.tool_calls or []:if tool_call.function.name != "get_weather":continuearguments = 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、工具调用消息以及会话中包含的工具结果消耗。