白話理解 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 上追蹤我們