查询 · 2023 起
Text2SQL
把自然语言问题转换为受约束的 SQL,让 RAG 从非结构化文档扩展到关系型数据库。
要解决的问题
模型不了解真实表结构和业务术语时,会编造表名、字段或错误连接;直接执行生成的 SQL 还可能带来数据泄露和写入风险。
相对前一代的变化
普通查询改写生成的是更适合搜索的文本。Text2SQL 需要读取数据库模式、字段语义和问题—SQL 示例,输出可校验、可执行的结构化查询。
做法
先检索相关 DDL、字段说明和少样本查询,再让模型生成 SQL;随后做语法与权限检查,在只读连接中限行执行,并把数据库错误反馈给模型进行有限次数的修正。
局限
复杂连接、时间口径和企业内部术语仍容易出错。生产环境必须使用只读账号、表列白名单、查询超时与结果行数限制,不能把模型输出直接交给数据库。
在链路中的位置
位于查询理解与结构化数据源之间;检索模块负责找模式和示例,SQL 执行结果再进入回答生成。
详解
「详解」根据 Datawhale《All-in-RAG》 的 文本到 SQL:检索模式、生成与安全执行 改写,有删节和重组,未包含原教程的代码、图片和练习。原教程与本节详解均按 CC BY-NC-SA 4.0 许可提供:使用时需署名并标明修改,不得用于商业目的,再次改编须以相同许可共享。
模型必须看见真实的表,而不能想象一张表
文本到 SQL 把问题翻译成关系库能执行的语句。失败通常来自三类情况:模型编造不存在的表或字段;不理解表之间该如何连接;用户使用了“上个月”“销售冠军”这类业务说法,而库里只有日期和金额字段。
把模式、说明和例句一起检索出来
最基本的上下文是相关表的 CREATE TABLE。只有表名、字段类型和外键,模型才知道能写什么。少量表格的“问题—SQL”例句能示范连接和聚合的写法。更稳的做法是再保存自然语言说明:每个表做什么、每个字段的业务含义、同义词映射,以及复杂查询示例。
查询到来时,先在这个知识库里检索最相关的 DDL、字段说明和例句,再把它们与原问题合成提示。知识库可以用向量库存放,但被检索的内容是模式和例句,不是业务表里的每一行。
生成、执行、把错误交回去
一次查询可以分成三步。先检索知识,再生成一条 SQL,然后在数据库里执行。执行失败时,把数据库返回的错误、原 SQL 和同一批知识交给模型修改,并限制重试次数。以“年龄大于 30 的用户”为例,检索应带回 users 表结构、age 字段说明,以及类似“年龄超过 25 岁”的例句;模型再把阈值换成 30。
提示需要明确只返回 SQL、只能使用上下文中的表和字段,并在需要连接时依据外键。温度设低一些,可以让相同输入更稳定。
执行权限比提示词更重要
模型输出不能直接交给生产库。连接应使用只读账号,表和列放在白名单里,并设置超时。SELECT 没有 LIMIT 时由程序补上,限制返回行数。禁止或拦截更新、删除和管理语句。
封装好的框架能少写代码,但检索、生成和执行混在一起时很难判断错在哪一层。自己留住这三步的输入和输出,才能知道是知识没检索到、SQL 写错,还是数据库拒绝执行。