白话理解 ChatGPT API 的函式呼叫功能 (function calling)

2025年1月6日

ChatGPT 教學專書
不僅教你 ChatGPT 指令,更帶你實作出創新應用!前往了解

所谓函式呼叫,就是让你把外部函式的形状写入 OpenAI API,这样 OpenAI API 就能输出对的格式来呼叫你的函式。

以下我们会用「取得天气资料」的例子来了解如何使用这个函式呼叫(function calling) 功能。

传统方式的限制

当你使用 ChatGPT 或 OpenAI 的 API 询问类似 「台北目前天气如何」的问题时,若 API 无法即时连网,假设不是即时连网回答模式,API 这时可能会回你

  • 乱回答的内容
  • 或是回答「训练资料只到 20XX 年」这类无法即时回应的资讯

若想要解决这个问题,开发者需搭配外部 API,例如天气 API。但过去的方法可能出现以下问题:

  1. 格式不一致:即使在 prompt 中要求输出 JSON,ChatGPT 仍可能加入「好的,以下是 JSON 字串的输出」这类多余的文字
  2. 格式错误导致整合失败:不符合 API 格式的输出会让整个流程中断

函式呼叫功能正是为了解决这些问题而设计,透过明确定义格式,让 OpenAI API 与外部 API 互动。

在开始程式码范例之前,我们先看以下为函式呼叫(function calling)的流程示意图:

函式呼叫(function calling)的流程示意图
函式呼叫(function calling)的流程示意图

函式呼叫的解决方案

使用函式呼叫功能时,OpenAI API 会依据定义好的格式,直接输出符合需求的内容,避免多余文字或格式错误。

假设有一个天气 API,其需要输入格式要有两个参数:

  1. 地点(location):字串
  2. 单位(unit):需要是摄氏(celsius)或华氏(fahrenheit)

范例函式:

function getWeatherAPI({ location, unit }) {
  // API 处理逻辑
}

建立函式定义

首先,建立函式定义来描述外部函式的结构与参数。

import { OpenAI } from "openai";
const openai = new OpenAI();

// 定义工具
const tools = [
  {
    // type 为 functions
    type: "function",
    function: {
      name: "get_weather",
      // 定义要回传的格式
      parameters: {
        type: "object",
        properties: {
          location: { type: "string" },
          unit: {
            type: "string",
            enum: ["celsius", "fahrenheit"],
          },
        },
      },
    },
  },
];

呼叫 OpenAI 的 API

利用上述工具定义,呼叫 OpenAI API 并传入相关参数。

const response = await openai.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "现在在台北的天气如何?" }],
  tools,
});

console.log(response.choices[0].message.tool_calls);

OpenAI API 的回应可能如下:

[
  {
    id: "call_12345xyz",
    type: "function",
    function: {
      name: "get_weather",
      arguments: '{"location":"Taipei", "unit": "celsius"}',
    },
  },
];

呼叫天气 API

这时就可以直接使用 OpenAI 的 API 回应的 arguments,

{
 "location": "Taipei",
 "unit": "celsius"
}

接着呼叫外部的天气 API 、外部的天气 API 并返回结果,获取最新的天气资讯。例如回覆:

{
  "temperature": 22,
  "unit": "celsius",
  "description": "Sunny"
}

回传给 OpenAI API

最后再将结果回传给 OpenAI API,让 OpenAI API 最后生成自然语言回覆。

curl https://api.openai.com/v1/chat/completions -u :$OPENAI_API_KEY -H 'Content-Type: application/json' -d '{
  "model": "gpt-4o",
  "messages": [
    {"role": "user", "content": "现在在台北的天气如何?"},
    {"role": "assistant", "content": null, "function_call": {"name": "get_current_weather", "arguments": "{ \"location\": \"Taipei\"}"}},
    {"role": "function", "name": "get_current_weather", "content": "{\"temperature\": 22, \"unit\": \"celsius\", \"description\": \"Sunny\"}"}
  ],
  "functions": [
    {
      "name": "get_weather",
      "description": "Get the current weather in a given location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "The city and state, e.g. San Francisco, CA"
          },
          "unit": {
            "type": "string",
            "enum": ["celsius", "fahrenheit"]
          }
        },
        "required": ["location"]
      }
    }
  ]
}'

此时,OpenAI API 的回应可能是:

{
  "id": "chatcmpl-123",
  ...
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "台北目前的天气为 22 度",
    },
    "finish_reason": "stop"
  }]
}

结语

在了解完函式呼叫功能后,大概可以更理解 OpenAI 的未来策略,如同执行长 Sam Altman 先前提到的,不会是再去做 ChatGPT 这种应用;而是会以平台的角度出发。

函式呼叫能让外部工具更好与 OpenAI API 整合,这会让 OpenAI 变得更有价值。身为企业或开发者,假如今天 Anthropic Claude 或 Google 的 Gimini 的成果追上 OpenAI 了,企业与开发者还可以选择能有更好整合性的。

参考文件

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們