如何使用GPT作为SQL查询引擎的自然语言

​生成的AI输出并不总是可靠的,但是下面我会讲述如何改进你的代码和查询的方法,以及防止发送敏感数据的方法。与大多数生成式AI一样,OpenAI的API的结果仍然不完美,这意味着我们不能完全信任它们。幸运的是,现在我们可以编写代码询问GPT如何计算响应,然后如果认可该方法,那我们可以自己运行代码。这意味着我们可以提出自然语言问题,比如“去年按地区的总销售额是多少?”,并且对响应的准确性感到可信。下面是一种快速而简单的技术,用于使用GPT设置自己的数据库的自然语言查询:

  1. 将数据的结构、一些示例行或两者都放入一个文本字符串中。
  2. 使用该信息加上你的自然语言问题来构建一个“提示”给AI。
  3. 将提示发送到OpenAI的GPT-3.5-turbo API,并请求一个SQL查询来回答您的问题。在数据集上运行返回的SQL来计算您的答案。
  4. (可选)创建一个交互式应用程序,以便轻松地使用纯英语查询数据集。

这种方法在处理现实世界的数据时具有几个优点。通过仅发送数据结构和一些示例行(可以包含虚假数据),无需将实际敏感数据发送给OpenAI。如果你的数据超过OpenAI的提示大小限制,也不必担心。通过请求SQL而不是最终答案,检查GPT如何生成答案的能力已经内置到了该过程中。如果真正想要使用生成式AI来开发企业级查询,可以借用一些工具,比如LangChain,它是一个用于处理多个不同的大型语言模型(LLM)的框架,不仅限于OpenAI的GPT。OpenAI最近还宣布了在API请求中包含函数调用的可能性,旨在使查询和类似任务更容易和可靠。但对于快速原型或您自己的使用,这里描述的过程是一个简单的入门方法。我的演示是用R完成的,但这种技术在几乎任何编程语言中都可以使用。

步骤1:将示例数据转换为单个字符字符串

这一步中的示例数据可以包括数据库模式和/或几行数据。将其全部转换为单个字符字符串非常重要,因为它将成为你将发送给GPT 3.5的更大文本字符串查询的一部分。 如果你的数据已经在SQL数据库中,这一步应该很容易。如果不是,我建议将其转换为可查询的SQL格式。为什么?在测试R和SQL代码结果后,我对GPT生成的SQL代码比其R代码更有信心。(我怀疑这是因为LLM在训练时使用了更多的SQL数据而不是R数据。) 在R中,sqldf包允许在R数据框上运行SQL查询,这是我在这个示例中将使用的工具。Python中也有类似的sqldf库。对于性能很重要的大型数据,你还可以查看duckdb项目。以下代码将数据文件导入R,使用sqldf函数查看如果数据框是一个SQL数据库表,SQL模式会是什么样子,使用head函数提取三行示例数据,并将模式和示例数据都转换为字符字符串。补充:ChatGPT编写了将数据转换为单个字符串的基本R部分的代码(通常我会使用paste函数执行这些任务)。

library(rio)
library(dplyr)
library(sqldf)
library(glue)
states <- rio::import("https://raw.githubusercontent.com/smach/SampleData/main/states.csv") |>
  filter(!is.na(Region))
​
states_schema <- sqldf("PRAGMA table_info(states)")
states_schema_string <- paste(apply(states_schema, 1, paste, collapse = "\t"), collapse = "\n")
​
states_sample <- dplyr::sample_n(states, 3)
states_sample_string <- paste(apply(states_sample, 1, paste, collapse = "\t"), collapse = "\n")

步骤2:为LLM创建提示

格式应该类似于“假设你是一名数据科学家。你有一个名为{table_name}的SQLite表,其模式如下:{schema}。前几行数据如下所示:{rows_sample}。基于这些数据,编写一个SQL查询来回答以下问题:{query}。只返回SQL,不包括解释。”。以下函数创建了这种类型格式的查询,接受数据模式、示例行、用户查询和表名作为参数。

create_prompt <- function(schema, rows_sample, query, table_name) {
  glue::glue("Act as if you're a data scientist. You have a SQLite table named {table_name} with the following schema:
​
             ```
             {schema}
             ```
​
             The first rows look like this: 
​
             ```{rows_sample}```
​
             Based on this data, write a SQL query to answer the following question: {query}. Return the SQL query ONLY. Do not include any additional explanation."
)
}

步骤3:将数据发送到OpenAI的API

你可以先将数据复制粘贴到OpenAI的Web界面之一中,以在ChatGPT或OpenAI API playground中查看结果。ChatGPT不收费,但无法调整结果。Playground允许设置诸如温度(即回答的“随机性”或创造性程度)和要使用的模型等参数。对于SQL代码,我将温度设置为0。

接下来,我将一个自然语言问题保存到变量question中,使用我的函数创建一个提示,并查看将该提示粘贴到API playground中会发生什么:

> my_query <- "What were the highest and lowest Population changes in 2020 by Division?"
> my_prompt <- get_query(states_schema_string, states_sample_string, my_query, "states")
> cat(my_prompt)
Act as if you're a data scientist. You have a SQLite table named states with the following schema:
​
```
0  State  TEXT  0  NA  0
1  Pop_2000  INTEGER  0  NA  0
2  Pop_2010  INTEGER  0  NA  0
3  Pop_2020  INTEGER  0  NA  0
4  PctChange_2000  REAL  0  NA  0
5  PctChange_2010  REAL  0  NA  0
6  PctChange_2020  REAL  0  NA  0
7  State Code  TEXT  0  NA  0
8  Region  TEXT  0  NA  0
9  Division  TEXT  0  NA  0
```
​
The first rows look like this: 
​
```Delaware   783600   897934   989948  17.6  14.6  10.2  DE  South  South Atlantic
Montana   902195   989415  1084225  12.9   9.7   9.6  MT  West  Mountain
Arizona  5130632  6392017  7151502  40.0  24.6  11.9  AZ  West  Mountain```
​
Based on this data, write a SQL query to answer the following question: What were the highest and lowest Population changes in 2020 by Division?. Return the SQL query ONLY. Do not include any additional explanation.

提示输入OpenAI API playground和生成的SQL代码

以下是我运行建议的SQL时的结果:

sqldf("SELECT Division, MAX(PctChange_2020) AS Highest_PctChange_2020,      MIN(PctChange_2020) AS Lowest_PctChange_2020 FROM states GROUP BY Division;")
            Division Highest_PctChange_2020 Lowest_PctChange_2020
1 East North Central                    4.7                  -0.1
2 East South Central                    8.9                  -0.2
3    Middle Atlantic                    5.7                   2.4
4           Mountain                   18.4                   2.3
5        New England                    7.4                   0.9
6            Pacific                   14.6                   3.3
7     South Atlantic                   14.6                  -3.2
8 West North Central                   15.8                   2.8
9 West South Central                   15.9                   2.7

步骤4:执行由GPT返回的SQL代码结果

通过编程方式将数据发送到OpenAI并从中返回会比将其复制粘贴到Web界面中更方便。有一些R包可以用于与OpenAI API进行交互。以下代码块使用该包向API发送提示,存储API响应,提取包含所请求SQL代码的文本部分,复制该代码,并在数据上运行SQL。

library(openai)
my_results <- openai::create_chat_completion(model =  "gpt-3.5-turbo", temperature = 0, messages =  list(
  list(role = "user", content = my_prompt)
)) 
the_answer <- my_results$choices$message.content
​
cat(the_answer)
SELECT Division, MAX(PctChange_2020) AS Highest_Population_Change, MIN(PctChange_2020) AS Lowest_Population_Change
FROM states
GROUP BY Division;
​
sqldf(the_answer)
            Division Highest_Population_Change Lowest_Population_Change
1 East North Central                       4.7                     -0.1
2 East South Central                       8.9                     -0.2
3    Middle Atlantic                       5.7                      2.4
4           Mountain                      18.4                      2.3
5        New England                       7.4                      0.9
6            Pacific                      14.6                      3.3
7     South Atlantic                      14.6                     -3.2
8 West North Central                      15.8                      2.8
9 West South Central                      15.9                      2.7

如果你想使用OpenAI API,你需要一个OpenAI API密钥。对于这个包,密钥应该存储在系统环境变量中,例如。请注意,这个API不是免费使用的,但在我把它变成我的编辑器之前,我一天运行了这个项目十几次,我的总账户使用量是1美分。

步骤5(可选):创建一个交互式应用程序

现在你已经拥有了在R工作流中运行查询的所有所需代码,可以在脚本或终端中使用它。但是,如果你想创建一个用于以自然语言查询数据的交互式应用程序,我提供了一个基本的Shiny应用程序的代码供你使用。如果你打算发布一个供他人使用的应用程序,而不仅仅是自己使用,你需要加固代码以防止恶意查询,添加更好的错误处理和解释性标签,改进样式,并对企业使用进行扩展。 与此同时,以下代码可以帮助开始创建一个用于使用自然语言查询数据集的交互式应用程序:

library(shiny)
library(openai)
library(dplyr)
library(sqldf)
​
# Load hard-coded dataset
states <- read.csv("states.csv") |>
  dplyr::filter(!is.na(Region) & Region != "")
​
states_schema <- sqldf::sqldf("PRAGMA table_info(states)")
states_schema_string <- paste(apply(states_schema, 1, paste, collapse = "\t"), collapse = "\n")
​
states_sample <- dplyr::sample_n(states, 3)
states_sample_string <- paste(apply(states_sample, 1, paste, collapse = "\t"), collapse = "\n")
​
# Function to process user input
get_prompt <- function(query, schema = states_schema_string, rows_sample = states_sample_string, table_name = "states") {
  my_prompt <- glue::glue("Act as if you're a data scientist. You have a SQLite table named {table_name} with the following schema:
​
             ```
             {schema}
             ```
​
             The first rows look like this: 
​
             ```{rows_sample}```
​
             Based on this data, write a SQL query to answer the following question: {query}  Return the SQL query ONLY. Do not include any additional explanation.")
  print(my_prompt)
  return(my_prompt)
​
}
​
ui <- fluidPage(
  titlePanel("Query state database"),
  sidebarLayout(
    sidebarPanel(
      textInput("query", "Enter your query", placeholder = "e.g., What is the total 2020 population by Region?"),
      actionButton("submit_btn", "Submit")
    ),
    mainPanel(
      uiOutput("the_sql"),
      br(),
      br(),
        verbatimTextOutput("results")
    )
  )
)
​
server <- function(input, output) {
​
# Create the prompt from the user query to send to GPT
  the_prompt <- eventReactive(input$submit_btn, {
    req(input$query, states_schema_string, states_sample_string)
    my_prompt <- get_prompt(query = input$query)
  })    
​
# send prompt to GPT, get SQL, run SQL, print results
observeEvent(input$submit_btn, {
  req(the_prompt()) # text to send to GPT
​
  # Send results to GPT and get response
  # withProgress adds a Shiny progress bar. Commas now needed after each statement
  withProgress(message = 'Getting results from GPT', value = 0, {  # Add Shiny progress message
  my_results <- openai::create_chat_completion(model =  "gpt-3.5-turbo", temperature = 0, messages =  list(
    list(role = "user", content = the_prompt())
  )) 
  the_gpt_sql <- my_results$choices$message.content 
​
  # print the SQL
  sql_html <- gsub("\n", "<br />", the_gpt_sql) 
  sql_html <- paste0("<p>", sql_html, "</p>") 
​
  # Run SQL on data to get results
  gpt_answer <- sqldf(the_gpt_sql) 
  setProgress(value = 1, message = 'GPT results received') # Send msg to user that 
  })
  # Print SQL and results
  output$the_sql <- renderUI(HTML(sql_html)) 
​
  if (is.vector(gpt_answer) ) {
    output$results <- renderPrint(gpt_answer) 
  } else {
    output$results <- renderPrint({ print(gpt_answer) }) 
  } 
})  
}
shinyApp(ui = ui, server = server)

作者: MSharon Machlis

更多技术干货请关注公号“云原生数据库

squids.cn,目前可体验全网zui低价RDS,免费的迁移工具DBMotion、SQL开发工具等

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android11 相机拍照权限,以及解决resolveActivity返回null

一、配置拍照和读写权限 <uses-permission android:name"android.permission.CAMERA"/> <uses-feature android:name"android.hardware.camera" /><uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&…

CAN转EtherNet/IP网关can协议是什么意思

你是否曾经遇到过不同的总线协议难以互相通信的问题&#xff1f;远创智控的YC-EIP-CAN网关为你解决了这个烦恼&#xff01; 远创智控YC-EIP-CAN通讯网关是一款自主研发的设备&#xff0c;它能够将各种CAN总线和ETHERNET/IP网络连接起来&#xff0c;解决不同总线协议之间的通信…

【Ajax】笔记-使用fetch函数发送AJAX请求

fetch()函数说明与使用方法详解 fetch()是XMLHttpRequest的升级版,用于在JavaScript脚本里面发出 HTTP请求,本文章向大家介绍fetch()的用法,主要包括fetch()的用法使用实例、应用技巧、基本知识点总结和需要注意事项&#xff0c;具有一定的参考价值&#xff0c;需要的朋友可以参…

IDE /完整分析C4819编译错误的本质原因

文章目录 概述基本概念代码页标识符字符集和字符编码方案源字符集和执行字符集 编译器使用的字符集VS字符集配置 有何作用编译器 - 源字符集编译器 -执行字符集 Qt Creator下配置MSVC编译器参数动态库DLL字符集配置不同于可执行程序EXE总结 概述 本文将从根本原因上来分析和解…

Vuex的使用

1. 是什么&#xff1a; vuex 是一个 vue 的 状态管理工具 &#xff0c;状态就是数据。 大白话&#xff1a;vuex 是一个插件&#xff0c;可以帮我们 管理 vue 通用的数据 (多组件共享的数据) 2. 场景&#xff1a; ① 某个状态 在 很多个组件 来使用 (个人信息) ② 多个组…

Vue基础 --- 路由

1. 前端路由的概念与原理 1.1 什么是路由 路由&#xff08;英文&#xff1a;router&#xff09;就是对应关系。 1.2 SPA 与前端路由 SPA 指的是一个 web 网站只有唯一的一个 HTML 页面&#xff0c;所有组件的展示与切换都在这唯一的一个页面内完成。 此时&#xff0c;不同…

echarts统计图x轴文字过长,以省略号显示,鼠标经过提示全部内容

效果图如下 主要代码如下&#xff1a; //1.js代码内加入extension方法&#xff0c;chart参数是echarts实例 function extension(chart) {// 注意这里&#xff0c;是以X轴显示内容过长为例&#xff0c;如果是y轴的话&#xff0c;需要把params.componentType xAxis改为yAxis/…

国产内存惹人爱,光威的价格战太凶猛,海外品牌已无力招架

现阶段&#xff0c;真的很适合升级内存条和SSD&#xff01;当然了&#xff0c;我说的是国产的品牌&#xff0c;经过这几年的发展&#xff0c;国产内存和SSD的表现都有了质的飞跃&#xff0c;像是光威之类的品牌&#xff0c;更是成功在玩家群体中获得了良好的口碑&#xff0c;而…

使用镜像搭建nacos集群

安装并配置 docker 1 先安装docker //1.查看操作系统的发行版号 uname -r//2.安装依赖软件包 yum install -y yum-utils device-mapper-persistent-data lvm2//3.设置yum镜像源 //官方源&#xff08;慢&#xff09; yum-config-manager --add-repo http://download.docker.co…

mysql进阶1——proxysql中间件

文章目录 一、基本了解二、安装部署三、proxysql管理配置3.1 内置库3.1.1 main库表3.1.2 stats库表3.1.3 monitor库 3.2 常用管理变量3.2.1 添加管理用户3.2.2 添加普通用户3.2.3 修改监听套接字 四、多层配置系统4.1 系统结构4.2 修改变量加载配置4.3 启动加载流程 一、基本了…

Jmeter(二十三):快速生成测试报告

一、jmeter配置 首先要保证jmeter命令是ok的,如果你在cmd中输入jmeter -v,有出现如下截图所示的信息,那就说明jmeter环境ok; 二、jmeter执行结合命令 生成HTML测试报告 1.完成脚本的调试、参数化、断言等操作。然后在聚合报告中指定日志文件存储路径,路径中最好不要包含有…

利用官网文档快速上手 Android 开发

官网学习链接&#xff1a;官网链接 官网教程

electron-egg 加密报错

electron框架&#xff1a;electron-egg 解决方式 npm uninstall bytenode npm install bytenode1.3.6node:internal/modules/cjs/loader:928 throw err; ^ Error: Cannot find module ‘node:assert/strict’ Require stack: D:\electron-egg-test\new-electron-egg\electr…

SpringBoot与文档excel,pdf集成案例分享

一、文档类型介绍 1、Excel文档 Excel一款电子表格软件。直观的界面、出色的计算功能和图表工具&#xff0c;在系统开发中&#xff0c;经常用来把数据转存到Excel文件&#xff0c;或者Excel数据导入系统中&#xff0c;这就涉及数据转换问题。 2、PDF文档 PDF是可移植文档格…

干翻Dubbo系列第四篇:Dubbo3第一个应用程序细节补充

前言 不从恶人的计谋&#xff0c;不站罪人的道路&#xff0c;不坐亵慢人的座位&#xff0c;惟喜爱耶和华的律法&#xff0c;昼夜思想&#xff0c;这人便为有福&#xff01;他要像一棵树栽在溪水旁&#xff0c;按时候结果子&#xff0c;叶子也不枯干。凡他所做的尽都顺利。 如…

Higress非K8S安装

Higress非K8S安装 文章目录 Higress非K8S安装环境安装安装higress进入到higress 的目录下修改下nacos的地址启动Higress登录higress管理页面 Higress 是基于阿里内部构建的下一代云原生网关&#xff0c;官网介绍&#xff1a;https://higress.io/zh-cn/docs/overview/what-is-hi…

HuggingGPT Solving AI Tasks with ChatGPT and its Friends in Hugging Face

总述 HuggingGPT 让LLM发挥向路由器一样的作用&#xff0c;让LLM来选择调用那个专业的模型来执行任务。HuggingGPT搭建LLM和专业AI模型的桥梁。Language is a generic interface for LLMs to connect AI models 四个阶段 Task Planning&#xff1a; 将复杂的任务分解。但是这里…

外文期刊影响因子去哪里查询,如何查询

期刊影响因子(Impact factor&#xff0c;IF)&#xff0c;是代表期刊影响大小的一项定量指标。也就是某刊平均每篇论文的被引用数&#xff0c;它实际上是某刊在某年被全部源刊物引证该刊前两年发表论文的次数&#xff0c;与该刊前两年所发表的全部源论文数之比。那么&#xff0c…

《嵌入式 - 工具》J-link读写MCU内部Flash

1 J-Link简介 J-Link是SEGGER公司为支持仿真ARM内核芯片推出的JTAG仿真器。配合IAR EWAR&#xff0c;ADS&#xff0c;KEIL&#xff0c;WINARM&#xff0c;RealView等集成开发环境支持所有ARM7/ARM9/ARM11,Cortex M0/M1/M3/M4, Cortex A5/A8/A9等内核芯片的仿真&#xff0c;是学…

redis 第二章

目录 1.持久化 2.主从复制 3.总结 1.持久化 通过 aof 和 rdb 将内存里的数据放到磁盘中 aof: rdb: 2.主从复制 将一台 redis 服务器的数据&#xff0c;复制到其他的 redis 服务器 3.总结 主从复制是高可用 redis 的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可…