由于 ChatGPT 背后的技术,用简单的英语查询数据集变得非常简单。
与大多数生成式AI一样,OpenAI的API结果仍然不完美,这意味着你不能只相信它们。幸运的是,您现在可以编写代码来询问 GPT 如何计算响应,然后如果您同意该方法,则可以自行运行代码。这意味着您将能够提出自然语言问题,例如“去年按地区划分的总销售额是多少?”并对响应的准确性充满信心。
以下是使用 GPT 设置您自己的数据库的自然语言查询的技术:
- 将数据的结构、几个示例行或两者放入单个文本字符串中。
- 用这些信息和你的自然语言问题向AI制作一个“提示”。
- 将提示发送到OpenAI的GPT-3.5-turbo API,并请求SQL查询来回答您的问题。
- 运行返回到数据集的 SQL 以计算答案。
- (可选)创建一个交互式应用程序,以便以简单的英语轻松查询数据集。
此方法在处理实际数据时有几个优点。通过仅发送数据结构和一些示例行(可能包括虚假数据),无需将实际敏感数据发送到 OpenAI。如果您的数据对于 OpenAI 的提示大小限制来说太大,也不必担心。而且,通过请求 SQL 而不是最终答案,检查 GPT 如何生成其答案的功能被烘焙到流程中。
面向企业查询的生成式 AI
如果你真的想使用生成式人工智能来开发企业级查询,你可能想研究像LangChain这样的工具,这是一个用于处理多种不同大型语言模型(LLM)的框架,而不仅仅是OpenAI的GPT。OpenAI最近还宣布了在API请求中包含函数调用的可能性,旨在使查询和类似任务更容易,更可靠。但对于快速原型或您自己的使用,此处描述的过程是一种简单的入门方法。我的演示是用R完成的,但该技术几乎适用于任何编程语言。
步骤 1:将示例数据转换为单字符字符串
此步骤中的示例数据可能包括数据库架构和/或几行数据。将其全部转换为单字符字符串非常重要,因为它将成为您将发送到 GPT 3.5 的较大文本字符串查询的一部分。
如果数据已在 SQL 数据库中,则此步骤应该非常简单。如果不是,我建议将其转换为SQL可查询格式。为什么?在测试 R 和 SQL 代码结果后,我对 GPT 生成的 SQL 代码比其 R 代码更有信心。(我怀疑这是因为LLM比R有更多的SQL数据用于训练。
在 R 中,sqldf 包允许在 R 数据帧上运行 SQL 查询,这就是我将在本例中使用的内容。Python中有一个类似的sqldf库。对于性能很重要的较大数据,您可能需要查看 duckdb 项目。
以下代码将数据文件导入 R,用于查看数据帧是 SQL 数据库表时 SQL 架构的外观,使用 ‘s 函数提取三个示例行,并将架构和示例行转换为字符串。免责声明:ChatGPT 编写了代码的基本 R 部分,将数据转换为单个字符串(我通常使用 执行这些任务)。sqldf
dplyr
filter()
apply()
purrr
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")
Step 2: Create a prompt for the LLM
The format should be something like “Act as if you’re a data scientist. You have an SQLite table called with the following schema: . The first rows look like this:. Based on this data, write an SQL query to answer the following question: . Return the SQL only, do not include explanations.”{table_name}
```{schema}```
```{rows_sample}```
{query}
The following function creates a query in that type of format, taking arguments for the data schema, sample rows, user query, and table name.
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游乐场中查看结果。ChatGPT 不收取使用费,但您无法调整结果。游乐场可让您设置温度等内容(即响应应该有多“随机”或创造性)以及要使用的模型。对于 SQL 代码,我将温度设置为 0。
接下来,我将一个自然语言问题保存到变量中,使用我的函数创建一个提示,看看当我将该提示粘贴到 API 操场时会发生什么:my_query
create_prompt()
> 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.
以下是我运行建议的 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
ChatGPT 不仅生成了准确的 SQL,而且我不必告诉 GPT“2020 年人口变化”在Pop_2020列中。
步骤 4:执行 GPT 返回的 SQL 代码的结果
以编程方式向 OpenAI 发送和返回数据比将其剪切并粘贴到 Web 界面中要方便得多。有一些用于使用 OpenAI API 的 R 包。以下代码块使用包向 API 发送提示,存储 API 响应,提取包含具有请求 SQL 代码的文本的响应部分,打印该代码,然后对数据运行 SQL。openai
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
如果要使用该 API,则需要 OpenAI API 密钥。对于此包,密钥应存储在系统环境变量中,例如 。请注意,API 不是免费使用的,但是在我将其转换为编辑器的前一天,我运行了这个项目十几次,我的总帐户使用量是 1 美分。OPENAI_API_KEY
步骤 5(可选):创建交互式应用程序
现在,你已拥有在脚本或终端的 R 工作流中运行查询所需的所有代码。但是,如果您想创建一个交互式应用程序,以使用简单的语言查询数据,我已经提供了您可以使用的基本 Shiny 应用程序的代码。