Skip to content
On this page

如何使用OpenAI的函数调用

OpenAI 引入了一个新功能叫函数调用(Function Calling)。 通过这个功能,开发者能进一步拓展GPT的能力,比如联网获取实时信息,与第三方应用互动等。 个人认为这次函数调用的上线是API发布以来最为重要的一次更新。 这篇文章通过实现一个简单的文章总结功能来说明如何使用函数调用。

GPT 自身无法对网络文章进行总结

我们都知道GPT最擅长瞎编,由于GPT并未联网,当你给它一个网页让总结内容的时候,通常会得到一个完全不相关的结果。比如我们要总结下面这篇文章

高温下电网面临考验:水电大省出力受挫,迎峰度夏或存缺口

https://www.thepaper.cn/newsDetail_forward_23564777

ChatGPT给出的回复是“很抱歉...”

ChatGPT

看得出来官方就人工智能瞎编这个毛病做了一些功课的。 再找一个接入了OpenAI的第三方应用试一下。

第三方应用

这个就纯粹是瞎编了。

利用函数调用实现网络文章的要点总结

总结文章最重要的一步是通过URL地址获取到文章的标题和正文,并将其作为上下文提交给OpenAI。

演示采用Node.js编写,这里有已经写好的库可以实现文章解析——article-extractor

JavaScript
const { extract } = require('@extractus/article-extractor')
async function extractArticle(url){
    try{
        return await extract(url)
    }catch(err){
        return null
    }
}

接下来需要在API中一个定义函数(参考文档),告诉接口当用户的要求是总结文章,并提供了url地址,就请调用 summarize 方法。

JavaScript
async function getCompletion(messages){
    return await openai.createChatCompletion({
        model: "gpt-3.5-turbo-0613-16k", // 建议采用16K避免文章过长
        messages,
        functions: [{ // 这里可以定义多个函数
            name: 'summarize',
            description: 'Write a summary in 150 to 300 words of any web article from its URL.',
            parameters:{
                type: 'object',
                properties:{
                  "url":{
                    "type":"string",
                    "description": "The URL of the article"
                  }
                },
                "required": ["url"]
            }
        }]
    })
}

GPT会根据用户的Prompt决定是否需要调用某一个函数,因此这里建议采用具有说明性的函数名称和描述。

接下来当我们输入下面的提示词

请总结文章:https://www.thepaper.cn/newsDetail_forward_23564777

API 判断需要用到 summarize 函数,返回结果中的 finish_reason 会从以前的 stop 变成 function_call, 同时,在 choices 中会返回函数的名称和参数。

JSON
{
  "id":"chatcmpl-7VKutU9VYnZ7kCrCYm73KfREzxqf8",
  "object":"chat.completion.chunk",
  "created":1687702927,
  "model":"gpt-3.5-turbo-0613-16k",
  "choices":[{
    "index":0,
    "message":{
      "text": null,
      "function_call":{
        "name": "summarize",
        "arguments":{
          "url": "https://www.thepaper.cn/newsDetail_forward_23564777"
        }
      }
    },
    "finish_reason":"function_call"
  }]
}

接下来就是在程序中根据接口返回的函数信息,调用前面定义的 summarize 函数并将返回的文章标题和正文作为message再次提交给OpenAI接口。

JavaScript
const {function_call} = resp.data.choices[0].message
const article = extractArtcile(function_call.arguments.url)
const messages = [
  {
    role: 'system', content: `请将文章总结为1到10条左右的要点,返回的格式如下:
      标题:<文章标题>\n
      要点:\n
      1. <要点1>\n
      2. <要点2>\n
      ...
      `
    },{
      role: 'function',
      name: 'summarize',
      content: `待总结的文章内容如下:\n标题:${article.title}\n${article.content}`
      }
    ]
return await getCompletion(messages)

看看效果