找回密码
 立即注册

QQ登录

只需一步,快速开始

dexteryao 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-6-21 17:58  /   查看:2221  /  回复:0
在SpreadJS中集成ChatGPT一文中提到ChatGPT插件的一个明显问题,“返回的结果格式可能插件也无法分析使用”
模型预言的限制,ChatGPT是基于语言模型的,其性能受模型训练和数据集的限制。对于复杂的问题可能并不能准确返回结果,同时返回的结果格式可能插件也无法分析使用。
但随着6月13日发布Chat Completions API 的function calling能力,这个问题得到了很好的解决。此次更新带来了新的模型,更大的内容,更低的价格,而Function calling更是带来了革命性的互动方式。
通过Function calling,OpenAI model可以根据你对系统中functions的描述来生成外部系统可以直接使用的结构化的JSON参数,这样GPT就可以更好的和外部系统结合。

以前文中“建议的数据透视表”为例,对于提供的表格数据,text-davinci-003 model会返回建议的文本内容:
  1. "text": "\n\n行:销售人员\n列:品牌\n值:销售额\n\n通过这样设置可以分析出每个销售人员销售的不同品牌的总销售额。"
复制代码
虽然有换行等符号可以解析所需要的行列值,但是稳定性十分不确定,程序很难直接使用。

通过使用Function calling,数据透视表的建立会非常简单。还是以OpenAI官方提供的nodejs支持为例。

1.        在对话中加入functions描述
  1.         let messages = [
  2.             {"role": "user", "content": "最后的JSON数据第一行是数据字段,创建有分析意义的数据透视表\n" + JSON.stringify(data)}
  3.         ]
  4.         let functions = [{
  5.             "name": "pivot_talbe_analyze",
  6.             "description": "对数据创建数据透视表,返回数据透视表结果",
  7.             "parameters": {
  8.                 "type": "object",
  9.                 "properties": {
  10.                     "rowFieldName": {
  11.                         "type": "string",
  12.                         "description": "行字段名称"
  13.                     },
  14.                     "columnFieldName": {
  15.                         "type": "string",
  16.                         "description": "列段名称"
  17.                     },
  18.                     "dataFieldName": {
  19.                         "type": "string",
  20.                         "description": "值字段名称"
  21.                     },
  22.                 },
  23.             },
  24.             "required": ["rowFieldName", "dataFieldName"]
  25.         }]

  26.         var response = openai.createChatCompletion({
  27.             "model": "gpt-3.5-turbo-0613",
  28.             "messages": messages,
  29.             "functions": functions,
  30.             "functions_call": {"name": "pivot_talbe_analyze"}
  31.         });
复制代码
一次对话可以有多个function描述,每个function描述包含名称,描述,方法参数(描述规则是JSON Schema),以及那些parameter是必选的。 对于选择区域创建数据透视表,需要提供行、列、值三个维度的字段名称,因此需要rowFieldName、columnFieldName和dataFieldName三个paramenter。
另外,可以通过function_call设置选择function的模式,当functions字段不为空时默认为“auto”,示例中指定了function pivot_talbe_analyze。
完成调用直接返回了function name 和parameters中的三个参数:
  1. {name: 'pivot_talbe_analyze', arguments: '{\n  "rowFieldName": "销售人员",\n  "columnFieldName": "品牌",\n  "dataFieldName": "销售额"\n}'}
复制代码

2.        使用GPT返回结果创建透视表
通过返回的function name 和parameters可以直接调用系统中的对应方法创建的透视表了
  1. let args = JSON.parse(completion.data.choices[0].message.function_call.arguments)
  2. let pivotTable = sheet.pivotTables.add("PivotTable", "Table1", 2, 7, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.medium2);
  3. pivotTable.add(args.rowFieldName, args.rowFieldName, GC.Spread.Pivot.PivotTableFieldType.rowField);
  4. if(args.columnFieldName)
  5.     pivotTable.add(args.columnFieldName, args.columnFieldName, GC.Spread.Pivot.PivotTableFieldType.columnField);
  6. pivotTable.add(args.dataFieldName, "求和项:" + args.dataFieldName, GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum);
复制代码
获取SpreadJS透视表结果
  1. let ptRange = pivotTable.getRange().content;
  2. let ptData = sheet.getArray(ptRange.row, ptRange.col, ptRange.rowCount, ptRange.colCount);
复制代码

3.        给GPT反馈公式调用结果
  1. messages.push(completion.data.choices[0].message)
  2. messages.push({"role": "function", "name": "pivot_talbe_analyze", "content": JSON.stringify({pivotTable: ptData})})

  3. response = openai.createChatCompletion({
  4.     "model": "gpt-3.5-turbo-0613",
  5.     "messages": messages,
  6.     "functions": functions,
  7.     function_call: "none"
  8. });
  9. response.then(function(completion){
  10.     let desc = completion.data.choices[0].message.content;
  11.     GC.Spread.Sheets.Designer.showMessageBox(desc, "分析结果", GC.Spread.Sheets.Designer.MessageBoxIcon.info)
  12. });
复制代码
将历史和获取到的透视表信息添加到messages中,这里message rule多了function类型,content就是调用function的返回结果。
调用时function_call设置none,不要使用function calling, GPT根据上下文返回了如下信息:
  1. {role: 'assistant', content: '以下是创建的数据透视表:\n\n```\n[\n  ["求和项:销售额", "品牌", null, null…\n]\n```\n\n该数据透视表按照销售人员和品牌对销售额进行了汇总,可以更方便地进行数据分析和比较。'}
复制代码
接下来可以发送新的请求让GPT对数据做进一步的分析处理,当然对于一些系统操作,我们做到步骤2就可以了。

Untitled picture.png

总结一下,通过Function calling,我们自己的系统和openai model互动更加简便,耦合的更加紧密,系统通过互动的方式向ChatGPT model发起请求,model可以智能选择需要调用的系统function,进一步提升了系统的创造性。 不过还是需要提醒,对于调用系统数据更新删除的方法,还是要做好确认再去执行。

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部