导语|本文将重点介绍 AI 与数据分析结合的应用,通过实际案例与相关技巧,描述 ChatGPT 如何助力数据分析,帮助读者更好地理解并掌握这一领域的创新实践。
本文作者:krryguo,腾讯 IEG前端开发工程师
在如今 AI 爆炸的时代,涌现出各种 AIGC 能力,可能我们已是司空见惯了。
之前分析过一句话生成图表和BI看板,这一次将重点介绍AI数据分析,通过实际案例与相关技巧,描述ChatGPT 如何助力数据分析。
声明:本文涉及与 ChatGPT 交互的数据已严格脱敏。
介绍
AI 数据分析,我这里实现了两种方式,支持多维数据分析:
SQL分析:分析平台自身的使用情况,如图表配置化平台,输入一句话可分析用户配置图表相关的数据
个性化分析:平台上支持上传数据,可提供数据信息(非必填),以此自定义分析用户自己上传的数据
分析完成后展示结果数据的图表和分析结论,图表支持折线图和柱状图,可随意切换。
演示
话不多说,直接上视频。
,时长01:08
注:视频中上传和 AI 分析的数据均是假数据,仅供测试。
视频展示内容:
演示SQL分析过程,输入想分析的内容,点击分析,输出数据图表和分析结论。
演示个性化分析,上传两个文件案例:单维度数据分析、多维度数据分析,可追加描述内容辅助 ChatGPT 进行分析。
由于我这个是图表配置化平台,所以这里用的第一个演示内容是 “分析每种图表的使用情况”。
流程
逻辑流程图如下:
上面说的两种方式对应流程图的上下两个步骤,红色部分是重点。
SQL分析:用户描述想分析的内容,后台连接 DB,附带表结构信息让 AI 输出SQL语句,校验是SELECT 类型的 SQL,其他操作如 UPDATE/DELETE 绝不能通过!!校验通过后执行 SQL 返回结果数据。
再将数据传给 GPT(附带上下文),让 AI 学习并分析数据,最后输出分析结论和建议,和结果数据一起返回给前端页面渲染图表、展示分析结论。目前已实现两张表关联查询。
个性化分析:用户上传文件,如有需要可以简单描述这是什么数据、字段意义或作用辅助分析。前端解析用户上传的文件,再传给 GPT 分析数据,后续步骤与上面一致。
流程描述得比较详细,就不具体讲解开发过程和代码了,而是会更多讲述开发时的一些 问题、重点和技巧。
相关重点:
第一个 user prompt:限定 SELECT SQL,这里告诉它:不要用 SELECT * 来查询全部列,且仅回复一条 SELECT SQL 语句。至少查询两列:数据项、数据值,且不能直接查询如 mediumtext/longtext 这样的长类型字段,可以用 count/substring 等函数查询这些长类型列。
system prompt 是表结构信息,如有难以理解的字段可以告诉 GPT 字段的意义,有多个表可分开描述。
需校验 GPT 生成的 SQL,不通过直接返回提示:抱歉,不支持此类请求。通过再执行 SQL 查询数据。
数据分析的 user prompt:提示数据分析,限定返回的 JSON 格式:conclusion、keyMap、title。
keyMap 的作用:数据 key 的映射,获取结果数据对应的维度、数据项、数据值的 key 值,用于映射数据渲染图表。由于支持多维数据,单维度数据的 keyMap 没有维度项,就存在让 GPT 返回两种结构的情况。这里我采取 分开定义单维度数据和多维度数据的 prompt,根据结果数据 tableData 的维度,用条件运算符选择对应的 prompt,再传递给 GPT。
结果数据 tableData 是跟随接口一起返回到前端,已经通过 SQL 查询的数据,不能让 GPT 又生成一次,否则非常耗时。
接口
实现了三个接口
生成 SQL 校验并执行 /api/getGPTSQLQuery
根据结果数据分析出结论 /api/getGPTAnalyze
封装了前面两个接口调用 /api/getGPTSQLAnalyze
方式一 SQL 分析调用第三个接口实现;
方式二个性化分析只调用第二个接口实现;
后续若只需要返回 SQL 也可以只调用第一个接口。
API getGPTSQLAnalyze 返回示意图
ChatGPT 两次回答内容
问题与技巧
对上面的流程,记录开发时一些问题和技巧,部分我采用一问一答形式说明。
公用逻辑
1、为什么在 user prompt 限定 SQL 和数据分析及其返回格式,而不用 system prompt?
有两个方面,一是因为 system prompt 已经承载了表结构信息;二是 user prompt 遵循力度更高。尝试多次,还是让 user prompt 承载具体返回格式更为精确,这一操作在后端进行,防止用户通过开发者工具查看参数。
2、为什么分开定义单维度数据和多维度数据的 prompt,而不直接丢给让 GPT 判断?
最好不要给让 GPT 存在两种返回格式的 prompt。例如:“如果数据是单维度,你就返回 {xxx},如果数据是多维度,你就返回 {xxx}”。这类存在 两种结果导向 的 prompt,我尝试了多次,大约有 50% 的几率 GPT 会犯傻(明明是单维度,却返回多维度格式,反之多维度却返回单维度格式)
所以最好的解决方式是在发送请求前用条件运算符区分这两个格式的 prompt,代码判断一下是单维度还是多维度数据,再决定用哪个 prompt,再传给 ChatGPT,尽量让这个 prompt 只存在 一种结果导向。
3、前端如何渲染图表?
SQL 分析的接口或个性化分析解析的数据文件所获得的 tableData,其格式与渲染表格的格式一样:对象数组。让 GPT 判断出对象的 key 值映射:keyMap,得知 维度、数据项、数据值的 key,就可以拿到并处理成图表所需的 series、xAxis。
SQL 分析
1、为什么还要反复校验是不是 SELECT SQL 语句?
这里不仅仅是 AI 不完全可控的原因,还有 永远不要相信用户的输入,万一用户恶意输入一些描述,非要执行 UPDATE/DELETE 等恶意操作,那就完了。所以一定要再次校验 AI 生成是否是安全的 SELECT SQL 语句,非查询类 SQL 坚决不通过!!提示不支持此类请求。
2、为什么到 AI 分析那一步骤还要拼接上下文?
上文是有表结构信息和 SQL 语句,这些可以提供给 GPT 更好理解数据和字段的意义,分析更准确。
3、针对表结构长类型字段,不允许直接查询,防止 token 消耗过多。其实最好还是告诉 GPT 只允许查询哪几个字段,或者用哪几个 SQL 函数,尽量让 GPT 生成可控。
个性化分析
1、用户上传的数据解析后需要判断数据格式是否符合要求,超长可以限制截取前面若干项,防止 token 消耗过多。
2、在前端解析用户上传的数据,分析完可以直接用于渲染数据图表,无需再让后端再返回。
3、需要支持用户补充输入,可以简单描述这是什么数据、字段意义或作用,用于 辅助 AI 分析。如果都是易理解语义化的字段名,可以无需描述,GPT 也能识别。
遇到一些多维度数据,GPT 可能会误将其他字段作为维度分析,为了准确性可以输入:“以xxx(字段名)为维度分析”;还可以输入:“这是xxx数据” 更好帮助 AI 分析。
Function calling
可以发现为了让 ChatGPT 返回符合要求的 JSON 格式,prompt 的定制就尤为重要和复杂。
好消息是,在当地时间 6 月 13 日,OpenAI 发布函数调用及其他 API 更新。现在开发人员可以向 gpt-4-0613 和 gpt-3.5-turbo-0613 描述函数,并让模型智能地选择输出一个包含调用这些函数所需参数的 JSON 对象。这是一种更可靠地将 GPT 的能力与外部工具和 API 连接起来的新方法。
传送门:Function calling and other API updates
官网有很详细的例子,这里就不再描述代码了。我用本文案例总结大致流程:
有个好处是不需要让 ChatGPT 生成 SQL 了,减少 SQL 注入的风险。本地写一个函数执行 this.app.mysql.select(table, condition),根据 GPT 返回的函数名、参数(字段和 where)来查询数据,更为安全。
但这个方法又有局限性,事先定义函数查询不如 SQL 查询来的灵活,所以这里也可以让函数改为 SQL 查询 this.app.mysql.query(sql),GPT 的函数调用改为:getSqlQuery(sql: string),函数名 getSqlQuery,参数:sql,更为灵活。
总结:让 GPT 与函数调用结合,本地控制返回 JSON 格式,prompt 的定制更为简单,AI 的输出更为可控。根据实际业务需求采用 函数查询 或 SQL 查询,值得一试!
SQL 分析示例
注:以下 SQL 分析的数据均是在数据库中伪造的数据,仅供测试。
分析每种图表的使用情况
分析图表类型是柱状图的创建时间和数量
个性化分析示例
注:个性化分析中上传的数据均是假数据,包括下面所有示例:游戏A流水数据、游戏产品数据、页面事件统计和用户行为数据,仅供测试。