函数调用与工具使用

将工具定义传入 AI 工作流,并接收结构化函数调用。支持多供应商下的 OpenAI 兼容 tools 格式。

ModelRiver 通过 toolstool_choice 支持 OpenAI 兼容的函数调用。工具定义会透传给底层供应商(如 OpenAI、xAI、Mistral),工具调用结果则以标准 OpenAI 格式返回。

函数调用的工作方式

  1. 定义工具:描述你的应用可以执行哪些函数
  2. 发送请求:在消息中附带工具定义
  3. 接收 tool_calls:模型返回结构化函数调用,而不是纯文本
  4. 执行函数:由你的应用实际运行这些函数
  5. 回传结果:把函数结果再发回模型,继续对话

基础示例

Python

PYTHON
1from openai import OpenAI
2 
3client = OpenAI(
4 base_url="https://api.modelriver.com/v1",
5 api_key="mr_live_YOUR_API_KEY"
6)
7 
8response = client.chat.completions.create(
9 model="my_workflow",
10 messages=[{"role": "user", "content": "What's the weather in Paris?"}],
11 tools=[{
12 "type": "function",
13 "function": {
14 "name": "get_weather",
15 "description": "Get the current weather for a location",
16 "parameters": {
17 "type": "object",
18 "properties": {
19 "location": {
20 "type": "string",
21 "description": "City name"
22 },
23 "unit": {
24 "type": "string",
25 "enum": ["celsius", "fahrenheit"],
26 "description": "Temperature unit"
27 }
28 },
29 "required": ["location"]
30 }
31 }
32 }],
33 tool_choice="auto"
34)
35 
36message = response.choices[0].message
37if message.tool_calls:
38 for tool_call in message.tool_calls:
39 print(f"Function: {tool_call.function.name}")
40 print(f"Arguments: {tool_call.function.arguments}")
41else:
42 print(message.content)

Node.js

JAVASCRIPT
1import OpenAI from "openai";
2 
3const client = new OpenAI({
4 baseURL: "https://api.modelriver.com/v1",
5 apiKey: "mr_live_YOUR_API_KEY",
6});
7 
8const response = await client.chat.completions.create({
9 model: "my_workflow",
10 messages: [{ role: "user", content: "What's the weather in Paris?" }],
11 tools: [{
12 type: "function",
13 function: {
14 name: "get_weather",
15 description: "Get the current weather for a location",
16 parameters: {
17 type: "object",
18 properties: {
19 location: { type: "string", description: "City name" },
20 unit: { type: "string", enum: ["celsius", "fahrenheit"] },
21 },
22 required: ["location"],
23 },
24 },
25 }],
26 tool_choice: "auto",
27});
28 
29const message = response.choices[0].message;
30if (message.tool_calls) {
31 for (const toolCall of message.tool_calls) {
32 console.log(`Function: ${toolCall.function.name}`);
33 console.log(`Arguments: ${toolCall.function.arguments}`);
34 }
35} else {
36 console.log(message.content);
37}

带有 tool_calls 的响应

当模型决定调用函数时,响应中会包含 tool_calls 数组:

JSON
1{
2 "choices": [{
3 "index": 0,
4 "message": {
5 "role": "assistant",
6 "content": null,
7 "tool_calls": [{
8 "id": "call_abc123",
9 "type": "function",
10 "function": {
11 "name": "get_weather",
12 "arguments": "{\"location\": \"Paris\", \"unit\": \"celsius\"}"
13 }
14 }]
15 },
16 "finish_reason": "tool_calls"
17 }]
18}

响应字段说明

字段说明
tool_calls[].id本次工具调用的唯一标识
tool_calls[].type恒为 "function"
tool_calls[].function.name需要执行的函数名称
tool_calls[].function.arguments函数参数的 JSON 字符串
finish_reason当模型要调用函数时,值为 "tool_calls"
contenttool_calls 时通常为 null

多轮工具对话

在执行完模型请求的函数后,把结果回传给模型,就可以继续对话。

常见模式:

  1. 用户发起请求
  2. 模型返回工具调用
  3. 后端执行函数
  4. 把函数结果作为新的消息追加
  5. 再次请求模型生成最终回答

这种模式非常适合:天气查询、数据库读取、订单查询、搜索增强回答以及 Agent 工具编排。

最佳实践

  • 为工具提供清晰、稳定的 name
  • description 要精确,让模型知道何时应调用它
  • 参数 schema 应尽量严格,减少歧义
  • 始终在服务端验证工具参数,不要完全信任模型输出
  • 为工具执行设置超时与重试策略

下一步

  • 请求类型:为不同 AI 任务选择正确的载荷格式
  • 流式传输:流式处理工具调用结果
  • 工作流:在工作流中组织多步 AI 与工具执行逻辑