NL2SQL在大型语言模型(LLM)的支持下得到了广泛应用,为了对基于LLM的NL2SQL解决方案进行系统化研究,我们需要全面理解和实践,包括Prompt工程、指令微调(SFT)、Agent、RAG等技术方案。为深入研究NL2SQL提供一些参考和指导。
1. 什么是NL2SQL
简言之,Natural Language to SQL (NL2SQL) 是指将用户的自然语句转为可以执行的 SQL 语句。
2. 基于LLM的NL2SQL现状
Spider和BIRD是比较受欢迎的两个NL2SQL的benchmark。Spider包含了1万多个自然语言的问题和相关的SQL语句,以及用来运行这些SQL的200多个数据库,横跨了100多个应用领域;BIRD相对于Spider更专注于学术研究,BIRD则更加考虑了真实应用中的数据库中信息的复杂性,且考虑了模型生成的SQL运行效率。BIRD也包含了约12000多个自然语言与SQL,涵盖了约37个专业领域的90多个数据库。
可以看到在Spider和BIRD上,GPT是远比开源模型效果要好的;在Spider榜单上,开源模型没有超过80分的,且在BIRD榜单上GPT也都没有超过60分。因此实现一个NL2SQL的模型简单,但是在实际应用时它的表现却没有想象的那样好,当前AI模型输出SQL的准确性还远无法达到人类工程师的输出精度。
3. 难点简析
应用难:真实企业应用数据库的结构更复杂、分析逻辑更复杂、准确性和相应性能要求高。深度学习的AI模型预测本身就有置信度的问题,无法确保绝对可靠性,这一点在大语言模型依然存在,尤其是在NL2SQL任务上,自然语言表达本身具有歧义性,而SQL是一种精确编程语言。因此在实际应用中,可能会出现无法理解,或者错误理解的情况。比如,“谁是这个月最厉害的销售”,那么AI是理解成订单数量最多,还是订单金额最大呢?输出的不确定性也是目前限制大模型在关键企业系统应用最大的障碍。
测评难:评估NL2SQL模型输出正确性很困难,既不能用SQL的执行结果来判断,也不能直接用SQL语句进行对比来判断。
- 用SQL执行结果来判断:在database 1上,Predicted1的结果和正确SQL的结果一模一样,但实际上Predicted1的SQL是错误的。
- 如果直接对比SQL语句:由于Predicted2和正确的SQL不完全一致,但其实Predicted2的SQL和正确的SQL是等价的。
那么大语言模型在应对这些问题时是否有很好的解决方案呢?遗憾的是,从当前的一些模型测试结果看,让大语言模型能够在这些场景下完全胜任,达到人类工程师的精度是不现实的。但是我们可以在几个方面考虑其优化,以实现在部分场景下的优先可用:
- 提示词工程优化
- 大模型指令微调
- Agent/RAG增强
4. NL2SQL通用优化方案
4.1 提示词工程优化
随着LLM的发展,使用LLM进行NL2SQL已成为一种新的范式。在这一过程中,如何利用提示工程来发掘LLM的NL2SQL能力显得尤为重要。
在利用LLM完成NL2SQL这一任务时,提示工程的关键在于将自然语言问题与必要的数据库信息转化为适用于LLM的自然语言序列输入,即问题表示。同时,当允许输入一些样例以利用LLM的in-context learning能力时,还需要考虑如何选择样例以及如何将这些样例有机地组织到输入序列中。
在zero-shot场景中有五花八门的Prompt模版,这里展示现有文献中四个最具代表性的。此外,再展示一个在 Alpaca中使用的Prompt模板,因为它在监督式微调中非常受欢迎。下表总结了这五种方法:
问题表示 | INS | RI | FK | LLMs | EM |
---|---|---|---|---|---|
B S P BS_P BSP | x | x | - | - | - |
T R P TR_P TRP | ✓ | x | x | Code-Davinci-002 | 69.0 |
O D P OD_P ODP | ✓ | ✓ | x | GPT-3.5-Turbo, GPT-4 | 70.1 |
C R P CR_P CRP | ✓ | x | ✓ | Code-Davinci-002, GPT-3.5-Turbo | 75.6 |
A S P AS_P ASP | ✓ | x | x | - | - |
EX:SQL执行准确率、INS:指令(任务描述)、RI:规则信息(指导性语句,比如“仅输出SQL语句,无需解释”)、FK:外键(数据库的外键信息)
基本提示
基本提示(Basic Prompt)是一种简单的Prompt模板,它由表模式、以 Q: 为前缀的自然语言问题、以及提示LLM生成SQL的响应前缀 A:SELECT 组成。之所以命名为基本提示,是因为它并未包含任何指令内容。
Table table_name1, columns = [column1, column2, ...]
...
Table table_name2, columns = [column1, column2, ...]
Q: The question
A: SELECT...(目标SQL)
文本表示提示
文本表示法提示(Text Representation Prompt)相比于基本提示,它在提示的开头添加了指导LLM的指令。在零样本场景中,它能在 Spider-dev 上实现了69.0%的执行准确率。
The Instruction(e.g. Given the following database schema: )
Table table_name1, columns = [column1, column2, ...]
...
Table table_name2, columns = [column1, column2, ...]
Answer the following: The question...
SELECT...(目标SQL)
OpenAI范式提示
OpenAI示范提示(OpenAI Demostration Prompt)首次在OpenAI的官方NL2SQL演示中使用,它由指令、表模式和问题组成,其中所有信息都用“#”进行注释。与文本表示提示相比,OpenAI示范提示中的指令更具体,而且还有一条规则约束,“仅完成sqlite SQL查询,无需解释”。
### The Instruction
# SQLite SQL tables, with their properties:
#
# table_name1(column1, column2, ...)
# ...
# table_name2(column1, column2, ...)
#
### The question...
SELECT...(目标SQL)
代码表示提示
代码表示提示(Code Representation Prompt)是一种基于SQL语法实现NL2SQL任务的方式。具体来说,它直接将表创建语句“CREATE TABLE …”放到Prompt中。相较于其他的问题表示方法,代码表示提示的独特之处在于,它能够提供创建数据库所需的全面信息,例如列名、列类型、主键/外键等。在这样的表示方式下, Code-Davinci-002能够正确预测约75.6%的SQL。
/* Given the following database schema: */
CREATE TABLE table_name1(
column1 type primary key,
column2 type,
foreign key(column3) references table_name2(xxx)
);
CREATE TABLE table_name2(
column1 thpe primary key,
column2 type,
foreign key(column3) references table_name1(xxx)
);
/* Answer the following: The question...
SELECT...(目标SQL)
Alpace指令微调提示
Alpace指令微调提示(Alpaca SFT Prompt)是一种用于监督微调的提示方式,它指导LLM按照指示并根据Markdown格式上下文来完成任务。
The description of the NL2SQL Task
### Instruction:
Write a sql to answer the question "The question"
### Input:
table_name1(column1, column2, ...)
...
table_name2(column1, column2, ...)
### Response:
SELECT...(目标SQL)
以上问题表示方法使大型语言模型(LLM)能够通过zero-shot学习直接输出所需的SQL。然而,在NL2SQL任务中,LLM通过上下文学习可以表现更出色,而这只需要在问题表示中提供了少量示例即可。
In-Context 学习
在In-Context 学习中,NL2SQL 涉及两个子任务:选择最有帮助的示例、将这些选定的示例组织到问题表示里面去,分别称作“示例选择(Example Selection)”和“示例组织(Example Organization)”。
示例选择
示例选择(Example Selection)在先前的研究中主要有以下几种策略:
- 随机选择(Random):此策略随机采样 k k k个可用候选的示例 Q Q Q,现有的工作已经将其作为示例选择的基准方案。
- 问题相似性选择(Question Similarity Selection):此方案选择与目标问题 q q q最相似的 k k k个示例。具体来说,使用预训练的语言模型(比如BERT等)将示例问题 Q Q Q和目标问题 q q q嵌入到同一个向量空间。然后,计算每个<示例问题, 目标问题>对应用预定义的距离度量,如欧氏距离或负余弦相似度。最后,利用 k k k近邻(KNN)算法从 Q Q Q中选择 k k k个与目标问题 q q q相近的示例。
- 遮蔽问题相似性选择(Masked Question Similarity Selection):对于跨领域NL2SQL,遮蔽问题相似性选择通过使用掩码标记(MASK)替换所有问题中的表名、列名和值,从而消除领域的特定信息,然后使用最近邻算法计算其嵌入向量的相似性。
- 查询相似性选择(Query Similarity Selection):此方案不是计算文本问题之间相似度,而是选择与目标SQL查询最相似的 标签:难点,Prompt,示例,模型,NL2SQL,LLM,SQL From: https://blog.csdn.net/pydaxing_pdx/article/details/142134910