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

?生成的AI输出并不总是可靠的,但是下面我会讲述如何改进你的代码和查询的方法,以及防止发送敏感数据的方法 。与大多数生成式AI一样,的API的结果仍然不完美,这意味着我们不能完全信任它们 。幸运的是,现在我们可以编写代码询问GPT如何计算响应,然后如果认可该方法,那我们可以自己运行代码 。这意味着我们可以提出自然语言问题,比如“去年按地区的总销售额是多少?”,并且对响应的准确性感到可信 。下面是一种快速而简单的技术,用于使用GPT设置自己的数据库的自然语言查询:
将数据的结构、一些示例行或两者都放入一个文本字符串中 。使用该信息加上你的自然语言问题来构建一个“提示”给AI 。将提示发送到的GPT-3.5-turbo API,并请求一个SQL查询来回答您的问题 。在数据集上运行返回的SQL来计算您的答案 。(可选)创建一个交互式应用程序,以便轻松地使用纯英语查询数据集 。
这种方法在处理现实世界的数据时具有几个优点 。通过仅发送数据结构和一些示例行(可以包含虚假数据),无需将实际敏感数据发送给 。如果你的数据超过的提示大小限制,也不必担心 。通过请求SQL而不是最终答案,检查GPT如何生成答案的能力已经内置到了该过程中 。如果真正想要使用生成式AI来开发企业级查询,可以借用一些工具,比如,它是一个用于处理多个不同的大型语言模型(LLM)的框架,不仅限于的GPT 。最近还宣布了在API请求中包含函数调用的可能性,旨在使查询和类似任务更容易和可靠 。但对于快速原型或您自己的使用,这里描述的过程是一个简单的入门方法 。我的演示是用R完成的,但这种技术在几乎任何编程语言中都可以使用 。
步骤1:将示例数据转换为单个字符字符串
这一步中的示例数据可以包括数据库模式和/或几行数据 。将其全部转换为单个字符字符串非常重要,因为它将成为你将发送给GPT 3.5的更大文本字符串查询的一部分 。如果你的数据已经在SQL数据库中,这一步应该很容易 。如果不是,我建议将其转换为可查询的SQL格式 。为什么?在测试R和SQL代码结果后,我对GPT生成的SQL代码比其R代码更有信心 。(我怀疑这是因为LLM在训练时使用了更多的SQL数据而不是R数据 。)在R中,sqldf包允许在R数据框上运行SQL查询,这是我在这个示例中将使用的工具 。中也有类似的sqldf库 。对于性能很重要的大型数据,你还可以查看项目 。以下代码将数据文件导入R,使用sqldf函数查看如果数据框是一个SQL数据库表,SQL模式会是什么样子,使用head函数提取三行示例数据,并将模式和示例数据都转换为字符字符串 。补充:编写了将数据转换为单个字符串的基本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创建提示
格式应该类似于“假设你是一名数据科学家 。你有一个名为{}的表,其模式如下:{} 。前几行数据如下所示:{} 。基于这些数据,编写一个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.")}