chatgpt api + function calling + AutoNavi weather API + google custom search [Link Google, Link Google]

 

OpenAI releases several major updates

1. Open the GPT-3.5-Turbo model (gpt-3.5-turbo-16k) with 16k context, which is 4 times the current 2. The new
GPT-4 and 3.5 Turbo model
3. The new function call function in the Chat Completions API (It becomes possible to obtain network data in real time)
4. The cost of the embeddings model is reduced by 75%
5. The input token cost of gpt-3.5-turbo is reduced by 25% (good news for developers)

The most exciting function should be the function call function. We all know that the training data of ChatGPT is based on before 2021. If you ask some real-time related questions, there is no way to answer you, and the function call allows real-time access Network data becomes possible, such as querying weather forecasts, checking stocks, recommending recent movies, and the like.

Which models support function calls?

gpt-3.5-turbo-0613and gpt-4-0613Both models support function calls.

What is the flow of function calls?

1. When a user asks a question, call the completions interface with a function description once, and gpt will judge whether it supports calling the function, and if so, extract the parameters required by the function from the user's question information.
2. After getting the parameters extracted by gpt, the developer calls the function by itself and returns the result.
3. Sends the return result of the function to GPT again for summary and induction into natural language

Things to pay attention to:

  1. The whole process of gpt will be executed twice, the first call extracts the function parameters from the question, and the second call summarizes the results returned by the function
  2. The function call is not called by gpt, but by the developer

give a real example

Here I take the real-time weather forecast as an example to demonstrate the function call process. The third-party AutoNavi API I use for the weather forecast interface is free and has a quota of thousands of calls per day. The application registration process is omitted here, research by yourself.

This function is used to query the weather conditions. The parameter city_nameis the name of the city. Because the Gaode API only supports checking the weather through the city code, so I made a query to find the corresponding code based on the city name.

The results returned by the interface include field information such as temperature, windpower, wind direction, humidity, and weather.

After the weather function is ready, the user starts to ask: "What's the weather in Shenzhen?", and the 'ChatCompletion' interface is called for the first time.

Here we specify a functionsparameter, which describes the name of the function and the parameter type. For example, if we define city_namethe parameters here, gpt will extract city_name from the user question. 

There is a field in the message returned by gpt to us function_call, and the value of the city_name field is extracted from the arguments.

Step 2: Call the function after extracting the parameters from the returned result. This process is not handed over to gpt, but the developer calls the function by himself. What gpt does is to extract the parameters required by the function.

Note that here we need to do some json conversion on the result returned by the function call

Step 3: Summarize the returned results to gpt

Note that the role in the last message in the messages list is function, and the content in rolethe final result is:second_response

 

 

 

 

 

 

const functionCalling = async ({
  isUseGoogleSearch,
  params,
  messages,
  historyMessage,
  model,
}) => {

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

  const getCurrentWeather = {
    name: 'get_current_weather',
    description: '获取指定地区的当前天气情况',
    parameters: {
      type: 'object',
      properties: {
        city: {
          type: 'string',
          description: '城市,例如:深圳',
        },
      },
      required: ['city'],
    },
  }

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

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

  const { completion } = completionRes.data.data

  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 myArguments = completion.choices[0]?.message?.function_call?.arguments
        console.log('myArguments', myArguments)
        myArguments = myArguments ? JSON.parse(myArguments) : {}
        let pageNum = 1
        searchCount = searchCount + 1
        let message = myArguments.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,
            }
          )
          clearTimeout(timer)

          const { searchResult } = result.data.data

          delete searchResult.queries

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

            completionRes = await axios.post(
              `${baseURL}/api/light/chat/openAi`,
              {
                model,
                messages: messagesTemp,
                apiKey,
                params,
              }
            )
            return completionRes
          }
        } catch (err) {
          console.log('错误1', err)

          if (global.isLocal === false) {
            customSendEmail({
              subject: 'chatgpt错误【2】',
              html: `chatgpt错误【2】<br/>${err.stack}`,
            })
          }
        }
      } catch (err) {
        console.log('chatgpt错误【1】', err)

        if (global.isLocal === false) {
          customSendEmail({
            subject: 'chatgpt错误【1】',
            html: `chatgpt错误【1】<br/>${err.stack}`,
          })
        }
      }
    } else if (
      completion.choices[0].finish_reason === 'function_call' &&
      completion.choices[0]?.message?.function_call?.name ===
        'get_current_weather'
    ) {
      try {
        let myArguments = completion.choices[0]?.message?.function_call?.arguments
        console.log('myArguments,get_current_weather', myArguments)
        myArguments = myArguments ? JSON.parse(myArguments) : {}
        let city = myArguments.city

        let resultCity = cityList.find(item => item.name.includes(city))
        let cityCode = '110000'
        if (resultCity && resultCity.adcode) {
          cityCode = resultCity.adcode
        }
        console.log('城市', city, cityCode)


        let result = await axios.get(
          `https://restapi.amap.com/v3/weather/weatherInfo?key=${weatherApiKey}&city=${cityCode}`
        )
        const searchResult = result.data

        if (searchResult && Array.isArray(searchResult.lives)) {
          const searchResultForGPT = `这是我的提问:${historyMessage}\n这是我查询到的结果:\n${JSON.stringify(
            searchResult.lives
          )}\n请结合搜索结果回答`
          console.log(searchResultForGPT)
          let messagesTemp = [
            ...messages,
            {
              role: 'function',
              name: completion.choices[0]?.message?.function_call?.name,
              content: searchResultForGPT,
            },
          ]

          completionRes = await axios.post(`${baseURL}/api/light/chat/openAi`, {
            model,
            messages: messagesTemp,
            apiKey,
            params,
          })
          return completionRes
        }
      } catch (err) {
        console.log('chatgpt错误【3】', err)

        if (global.isLocal === false) {
          customSendEmail({
            subject: 'chatgpt错误【3】',
            html: `chatgpt错误【3】<br/>${err.stack}`,
          })
        }
      }
    }
  }
}
const { google } = require('googleapis')


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: googleCx,
      key: googleKey,
      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',
    })
  }
}

Reference link:

https://wejson.cn/excel2json/

https://lbs.amap.com/api/webservice/guide/api/weatherinfo/ 

 https://m.moji.com/weather/china/beijing/beijing

https://zhuanlan.zhihu.com/p/637425118 

http://chat.xutongbao.top/ 

Guess you like

Origin blog.csdn.net/xutongbao/article/details/131599916