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

news2024/11/25 4:24:29

 这两天看的比较多的一个新闻就是 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 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/725054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SpringBoot+vue的教师人事档案管理系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

【力扣周赛】第 352 场周赛

文章目录 Q1&#xff1a;2760. 最长奇偶子数组解法1——纯纯暴力解法2——枚举左端点&#xff0c;尝试右端点继续优化 Q2&#xff1a;2761. 和等于目标值的质数对一个小优化 Q3&#xff1a;2762. 不间断子数组解法1——滑动窗口维护哈希表普通HashMap使用TreeMap补充&#xff1…

利用Python批量压缩图片大小(不改变图片尺寸,不改变图片格式)

我们经常需要在某些文件中如&#xff1a;Word,Excel&#xff0c;PPT等中&#xff0c;插入大量的图片&#xff0c;但是图片每一张的内存都不小&#xff0c;累计多了&#xff0c;就是导致文件的内存过大&#xff0c;导致客户打不开文件&#xff0c;那么我们可以将图片的内存压缩一…

指针的指针理解与用法

指针实际上就是一个变量&#xff0c;当他不是空指针的时候他的值就是某一个地址&#xff0c;同时他自己也是有地址的&#xff0c;因为它是一个变量。 指针的指针的值其实就是某一个指针的地址。 int main() {int a 5;int *p &a;int **pp &p;printf("%p\n&quo…

GitHub Pages + Hexo搭建个人博客网站

步骤 参考如下步骤&#xff1a;https://blog.csdn.net/yaorongke/article/details/119089190 出现的问题 1 Fluid主题 其更换Fluid主题时&#xff1a; 下载最新 release 版本 解压到 themes 目录&#xff0c;并将解压出的文件夹重命名为 fluid 按照上面执行后&#xff0c;后…

新增数据列--Pandas

1. 直接赋值 order pd.read_excel(C:\\Users\\changyanhua\\Desktop\\order.xlsx) print(order.head()) # 1.直接赋值新增列&#xff1a; order[平均价]order[销售额]/order[数量] print(order.head())2.apply()方法 2.1 函数功能 沿着DataFrame的某个轴应用一个函数。返回…

AIGC - Stable Diffusion 的 Prompts 提示词工程框架 (1)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131544508 当前 Stable Diffusion 模型使用基础的 stable-diffusion-v1-5&#xff0c;即 v1-5-pruned-emaonly.safetensors。 Stable Diffusion …

【RT】统一的基于文本的行人检索:大规模多属性和语言检索基准

Towards Unified Text-based Person Retrieval: A Large-scale Multi-Attribute and Language Search Benchmark 西安交通大学 针对 基于文本的行人检索的预训练 展开探索 Motivation Data Scarcity Contributions MALS(Multi-Attribute and Language Search dataset for pe…

关于亚马逊测评,为何绝大多数卖家都倾向于自养号测评

亚马逊测评在当前的电商环境中对于卖家的重要性不言而喻。现在越来越多的卖家选择自养账号测评&#xff0c;相对于找国外买手或测评服务商&#xff0c;主要是出于以下考虑&#xff1a; 1.避免买家账号资源的重复使用&#xff1a;使用国外买手或测评服务商时&#xff0c;买家账…

Python+selenium自动化测试

批量执行完用例后&#xff0c;生成的测试报告是文本形式的&#xff0c;不够直观&#xff0c;为了更好的展示测试报告&#xff0c;最好是生成HTML格式的。 unittest里面是不能生成html格式报告的&#xff0c;需要导入一个第三方的模块&#xff1a;HTMLTestRunner 一、导入HTML…

VSCode如何通过Ctrl+P快速打开node_modules中的文件

背景 咱们新建一个NodeJS项目&#xff0c;必然会安装许多依赖包&#xff0c;因此经常需要查阅某些依赖包的源码文件。但是&#xff0c;由于node_modules目录包含的文件太多&#xff0c;出于性能考虑&#xff0c;在VSCode中默认情况下是禁止搜索node_modules目录的。在这种情况…

Spring Boot 中的 XSS 攻击是什么,原理,如何预防

Spring Boot 中的 XSS 攻击是什么&#xff0c;原理&#xff0c;如何预防 XSS&#xff08;Cross-Site Scripting&#xff0c;跨站脚本攻击&#xff09;是 Web 应用程序开发中常见的一种安全问题。在 Spring Boot 中&#xff0c;XSS 攻击可能会导致应用程序被攻击者利用&#xf…

阿里云直播配置

一、开通阿里云直播 首先进入阿里云直播产品主页&#xff1a;https://www.aliyun.com/product/live 。 点击下方的“立即开通”。 如果是还未注册的用户请按照页面提示进行完成注册并实名认证。 2、首次进入会提示开通服务&#xff0c;点击“开通服务”&#xff0c;然后选择计…

操作系统与内核、系统编程与应用编程

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

Ubuntu18.04系统如何安装和使用telnet工具

在ubuntu18.04中如何安装和使用telnet工具呢?本文给出详细说明。 1.更新软件列表 sudo apt update 2.安装telnet服务 sudo apt install openbsd-inetd telnetd 3.查看telnet运行状态 netstat -a | grep telnet 4.登录测试 telnet 127.0.0.1

【NLP】PNR指标

PNR&#xff08;Positive Negative Rate&#xff09; 正逆序比 正序数 / 逆序数&#xff1b; 当正序数量越多、逆序数量越少时&#xff0c;表明模型对序关系的刻画越准确&#xff0c;模型效果越好。 参考&#xff1a;https://www.jianshu.com/p/e9813ac25cb6

如何使用不同的工具运行交互式的python

最近在极客时间学习陈旸老师《数据分析实战45讲》专栏&#xff0c;需要用到python&#xff0c;自19年后基本没用过python&#xff0c;现在又重头抓起&#xff0c;针对遇到的问题进行总结积累。代码片段均取自专栏内容。 示例代码&#xff1a; name raw_input("Whats your…

了解抖音本地生活服务商:连接你与便捷生活的桥梁

抖音本地生活服务商是抖音平台为用户提供的一项服务&#xff0c;旨在连接用户与本地商家&#xff0c;为用户提供更便捷的本地生活服务。下面是四川不若与众对抖音本地生活服务商的介绍。 1. 提供多样化的服务&#xff1a;抖音本地生活服务商为用户提供了多样化的服务&#xff0…

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)

目录 MongoDB索引Index 聚合操作 通过聚合操作可以处理多个文档&#xff0c;并返回计算后的结果。 对多个文档进行分组对分组的文档执行操作并返回单个结果分析数据变化 聚合管道 分别由多个阶段来处理文档&#xff0c;每个阶段的输出是下个阶段的输入&#xff0c; 返回的是…

C / C++的wprintf打印速度太慢,改WriteConsoleW输出提速200+倍

在 C / C 处理将UTF-8字符串内容输出到终端控制台时&#xff0c;平时惯用一个广泛使用的 wprintf() 函数&#xff0c;虽然它支持 Unicode 、UTF-8 字符&#xff0c;但在测试过程中发现它输出大文件时会有严重拖累性能&#xff0c; 测试打印文件&#xff1a;一个将近6万行的 Jav…