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

所谓函式呼叫,就是让你把外部函式的形状写入 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 了,企业与开发者还可以选择能有更好整合性的。

参考文件

  • OpenAI Function Calling
© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享