在这里插入图片描述

本文以 OpenAI 风格的工具调用举例说明“工具调用(Tool Calling)”的协议约定。

1. 核心概念

  • tools:你提供给模型可调用的工具列表(最常见是 function 类型)。
  • tool_choice:控制模型是否/如何调用工具(auto / none / required / 指定某个工具)。
  • tool_calls:模型决定调用工具时,在响应中返回的调用指令(函数名 + 参数 JSON)。
  • tool 消息:客户端执行工具后,把结果作为 role=tool 回传给模型。

2. 请求格式(你发给模型)

典型请求字段:

  • model: 模型名
  • messages: 对话消息数组(system / user / assistant / tool
  • tools: 工具定义数组
  • tool_choice: 工具策略(默认常用 auto

2.1 tools 定义(function)

{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "查询城市天气",
    "parameters": {
      "type": "object",
      "properties": {
        "city": {
          "type": "string",
          "description": "城市名称,如 Beijing"
        },
        "unit": {
          "type": "string",
          "enum": ["celsius", "fahrenheit"]
        }
      },
      "required": ["city"],
      "additionalProperties": false
    }
  }
}

说明:

  • name 使用稳定、可读、无空格命名。
  • parameters 模型会按它生成参数。
  • additionalProperties: false 可减少模型多传无关字段,默认为true.

2.2 tool_choice 值

  • "auto":模型自行决定“直接回答”或“调用工具”。
  • "none":禁止工具调用。
  • "required":必须调用至少一个工具。
  • 指定工具(强制某个函数):
"tool_choice":{
  "type": "function",
  "function": { "name": "get_weather" }
}

2.3 一次完整请求示例

{
  "model": "gpt-4.1",
  "messages": [
    { "role": "system", "content": "你是一个天气助手" },
    { "role": "user", "content": "北京现在天气怎么样?" }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "查询城市天气",
        "parameters": {
          "type": "object",
          "properties": {
            "city": { "type": "string" },
            "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }
          },
          "required": ["city"],
          "additionalProperties": false
        }
      }
    }
  ],
  "tool_choice": "auto"
}

3. 返回格式(模型回给你)

3.1 不调用工具时

通常是普通 assistant 文本:

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "今天天气晴,约 20°C。"
      },
      "finish_reason": "stop"
    }
  ]
}

3.2 调用工具时

模型不会直接给最终答案,而是给 tool_calls

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\":\"Beijing\",\"unit\":\"celsius\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}

关键点:

  • function.arguments 常见是 JSON 字符串,客户端需要 json.loads 后校验。
  • finish_reason 常见为 tool_calls(表示这轮在请求你执行工具)。

4. 客户端协议循环

标准循环如下:

  1. 发起请求(含 messages + tools + tool_choice)。
  2. 若响应含 tool_calls
    • 逐个解析参数并执行本地工具函数。
    • 把每个工具执行结果作为 role=tool 消息追加到 messages
  3. 再次请求模型,让模型基于工具结果生成最终回答。
  4. 若无 tool_calls,直接把 assistant 文本返回给用户。

4.1 tool 回传消息格式

{
  "role": "tool",
  "tool_call_id": "call_123",
  "content": "{\"temp\":20,\"condition\":\"Sunny\"}"
}

说明:

  • tool_call_id 必须对应模型返回的 tool_calls[i].id
  • content 通常是字符串(可放 JSON 字符串)。

5. 完整多轮示例

第 1 轮(用户提问)

[
  { "role": "system", "content": "你是天气助手" },
  { "role": "user", "content": "北京天气?" }
]

模型返回(要求调用工具)

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

客户端执行工具后追加消息

[
  {
    "role": "assistant",
    "content": null,
    "tool_calls": [
      {
        "id": "call_123",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"city\":\"Beijing\"}"
        }
      }
    ]
  },
  {
    "role": "tool",
    "tool_call_id": "call_123",
    "content": "{\"temp\":20,\"condition\":\"Sunny\"}"
  }
]

第 2 轮(模型产出最终答案)

{
  "role": "assistant",
  "content": "北京当前晴,约 20°C。"
}

6. OpenAI 官方原始资料链接

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐