说说 OpenAI 最新发布的Function calling 是什么

 这两天看的比较多的一个新闻就是 OpenAI 又更新了自己的 API。 除了各种大减价,增加 Token 数量之外,还新推出了一个叫做 Function calling 的能力。那么 Function calling 到底是什么东西,可能很多新闻类型的内容也没讲太明白,我和大家聊一下。

其实这个能力和我之前跟大家聊的 ChatGPT 插件功能有些类似。 如果没看过的朋友,我也简单和大家描述一下, ChatGPT 插件是这样一个流程,你的服务端给它提供一个描述文件,就是告诉 ChatGPT 怎么调用你的接口,以及这些接口都能做什么。 那么当用户在使用 ChatGPT 的时候,如果 ChatGPT 认为用户提的某些问题,你的插件能够更好的解决,那么 ChatGPT 就会直接去调用你插件的接口。

当然,如果我这个描述你还是不能很好的理解,可以看看我之前的文章:说说 ChatGPT Plugin, 看看你能否先知先觉

Function calling 其实就是把这个过程 API 化了。 这个东西出现的还真是快,其实我在前些天用 ChatGPT 插件的时候就一只在想这个问题,插件最强大的地方在于任何类型的应用,无论它本身是否有 AI 能力,都能用通过插件这个方式把大语言模型的能力用到自己的产品上面。

但是插件也有一个局限性,就是用户的使用场景受限,必须在 ChatGPT 界面中才行。我那会儿就在想要是这个能力能脱离 ChatGPT 本身的界面,那就更强大了。结果 OpenAI 还是厉害,我想到的这些问题,人家早就想明白了,而且很快的把它变成现实了。

 

https://platform.openai.com/docs/guides/gpt/function-calling

 Function calling:

const { google } = require('googleapis')

const chatUseOpenAi = async (req, res) => {
  let {
    model = 'gpt-3.5-turbo-16k-0613',
    messages = [
      {
        role: 'user',
        content: '你好',
      },
    ],
    apiKey = 'sk-xxx',
    params = {},
  } = req.body
  if (apiKey === 'xxx') {
    let baseURL = 'http://xxx'

    const searchGoogleGptFunction = {
      name: 'search_google_when_gpt_cannot_answer',
      description:
        '当 gpt 遇到无法回答的或者需要搜索引擎协助回答时从 google 搜索',
      parameters: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: '搜索句,支持中文或者英文',
          },
        },
      },
    }

    let getCurrentWeather = {
      name: 'get_current_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'],
      },
    }

    let isUseGoogleSearch = true

    params = {
      ...params,
      functions: [searchGoogleGptFunction],
      function_call: isUseGoogleSearch ? 'auto' : 'none', //fun?.function_call, none
    }

    let result = await axios.post(`${baseURL}/api/light/chat/openAi`, {
      model,
      messages,
      apiKey,
      params,
    })

    const { errorData, completion } = result.data.data

    let tempSearchResult = ''
    if (
      completion &&
      Array.isArray(completion.choices) &&
      completion.choices.length > 0
    ) {
      if (
        completion.choices[0].finish_reason === 'function_call' &&
        completion.choices[0]?.message?.function_call?.name ===
          'search_google_when_gpt_cannot_answer'
      ) {
        try {
          let arguments =
            completion.choices[0]?.message?.function_call?.arguments
          console.log('arguments', arguments)
          arguments = arguments ? JSON.parse(arguments) : {}
          let baseURL = 'http://xxx'
          let pageNum = 1
          searchCount = searchCount + 1
          let message = arguments.query
          console.log('google搜索次数', searchCount)
          console.log('google搜索关键词', message, Date())

          let timer = setTimeout(() => {
            customSendEmail({
              subject: 'google搜索超时',
              html: `google搜索超时,${message},${pageNum}`,
            })
          }, 1000 * 60)

          try {
            let result = await axios.post(
              `${baseURL}/api/light/chat/googleSearchOnAzure`,
              {
                message,
                pageNum: 1,
                apiKey: 'xxx',
              }
            )
            clearTimeout(timer)

            const { searchResult } = result.data.data

            delete searchResult.queries

            tempSearchResult = searchResult

            if (searchResult && Array.isArray(searchResult.items)) {
              let googleResultList = searchResult.items.map((item) => {
                return {
                  title: item.title,
                  snippet: item.snippet,
                }
              })
              const googleResultForGPT = `这是我的提问:${message}\n这是我在google搜索“${message}”的结果:\n${JSON.stringify(
                googleResultList
              )}\n请结合搜索结果回答`
              let messagesTemp = [
                ...messages,
                {
                  role: 'function',
                  name: completion.choices[0]?.message?.function_call?.name,
                  content: googleResultForGPT,
                },
              ]

              let resultForGPT = await axios.post(
                `${baseURL}/api/light/chat/openAi`,
                {
                  model,
                  messages: messagesTemp,
                  apiKey,
                  params,
                }
              )

              const { errorData, completion: completionForGTP } =
                resultForGPT.data.data

              res.send({
                code: 200,
                data: {
                  errorData,
                  completionForGTP,
                  params,
                  tempSearchResult,
                },
                message: '成功',
              })
              return
            }
          } catch (err) {
            console.log('错误1', err.stack)
            customSendEmail({
              subject: 'google搜索失败',
              html: `chatgpt自动调用<br/>${err.stack}`,
            })
          }
        } catch (error) {
          console.log('arguments, 解析错误')

          customSendEmail({
            subject: 'arguments, 解析错误',
            html: `arguments, 解析错误<br/>${err.stack}`,
          })
        }
      }
    }
    res.send({
      code: 200,
      data: {
        errorData,
        completion,
        params,
        tempSearchResult,
      },
      message: '成功',
    })
  } else {
    res.send({
      code: 400,
      message: '失败:参数apiKey',
    })
  }
}

 google搜索:

const chatGoogleSearchOnAzure = async (req, res) => {
  let { message = '', pageNum = 1, apiKey = 'sk-xxx' } = req.body

  if (apiKey === 'xxx') {
    let start = (pageNum - 1) * 10

    const customSearch = google.customsearch('v1')
    const customSearchRes = await customSearch.cse.list({
      cx: 'xxx',
      key: 'xxx,
      q: message,
      start,
      num: 10,
      hl: 'zh-CN',
      safe: 'off',
      imgColorType: 'color',
    })

    const searchResult = customSearchRes.data

    res.send({
      code: 200,
      data: {
        searchResult: searchResult,
      },
      message: '成功',
    })
  } else {
    res.send({
      code: 400,
      message: '失败:参数apiKey',
    })
  }
}

 

 

 

参考链接:

https://juejin.cn/post/7249909247039143997

http://swiftcafe.io/post/openai-api

http://chat.xutongbao.top 

猜你喜欢

转载自blog.csdn.net/xutongbao/article/details/131568991
今日推荐