自然语言转 SQL(Text2SQL)技术旨在降低数据查询的技术门槛,但一直面临 "灵活性"、"准确性" 与 "查询复杂性" 难以兼顾的困境。直接由大语言模型生成 SQL 存在语义 "幻觉" 造成准确性偏低,引入结构化中间层获得准确性的有限提升却会牺牲查询复杂性,难以满足企业级 BI 需求。润乾 NLQ 技术采用 "规范文本" 作为中间层,构建人机均可理解的中介语言,将不确定性限制在自然语言理解阶段,通过人类确认的方式解决准确性问题,再利用规则引擎转换准确的 SQL 进行查询,同时 "规范文本" 的设计还能支持复杂查询。这样将同时获得灵活性、准确性与复杂性,还有巨大的成本优势,为 Text2SQL 的实用化提供了一条可行的工程路径。
在商业智能(BI)领域,让非技术背景的业务人员直接、高效地获取数据洞察,一直是个关键的需求。ChatBI 等自然语言交互式查询技术的出现,正是为了满足这一需求,将用户以自然语言表述的查询意图,转换为可执行的 SQL 语句。大语言模型(LLM)的突破性进展,使得利用 LLM 实现从自然语言到 SQL 转换成为可能。
用 LLM 直接将自然语言转换为 SQL 语句是最直观的技术路径,具体来讲,就是通过提示工程、模型微调或检索增强生成等技术将领域知识注入模型,生成符合业务需求的 SQL 语句。
LLM 能够理解和泛化千变万化的口语,对用户而言几乎没有表达上的限制,体现出强大的灵活性。同时,得益于在海量代码数据上的预训练,LLM 理论上具备生成多表 JOIN、嵌套子查询等复杂 SQL 功能的能力,为处理复杂业务场景提供了可能。
然而,该方案有个根本性的缺陷:LLM 幻觉导致的准确性问题,这对企业级应用是致命的。LLM 可能生成语法正确但语义错误的 SQL,比如混淆关键业务指标、错误构建多表关联逻辑,或在时间计算等业务规则上出现偏差。在企业决策场景中,错误的查询结果就可能导致重大损失,这种不确定性是企业无法接受的。
不幸的是,缺乏有效的确认机制来克服幻觉问题。Text2SQL 的应用场景大都是 BI,其用户是业务人员,LLM 生成的 SQL 对业务人员而言是读不懂的 "天书",也就无法确认查询意图是否被正确理解,这使得语义错误难以及时发现和纠正。
此外,该方案的实施成本极高。无论是通过微调训练专用模型,还是构建 RAG 知识库,都需要专业的 AI 技术团队,其技术难度和实施成本相当于 "为了坐飞机而建立飞行员团队",对绝大多数企业而言不具备可操作性。
为应对 LLM 直接生成 SQL 时的不可控性,业界引入 "中间表示" 的折中方案。将 Text2SQL 任务拆解为两个阶段:首先由 LLM 将自然语言转换为结构化的中间表示,比如许多解决方案会设计一套 MQL(Metrics Query Language)语法,再用确定性的规则引擎将 MQL 编译为 SQL 执行。
然而,这种方案在准确性方面并未得到实质性提升。虽然将 LLM 的任务限定为生成结构固定的中间表示确实约束了其输出空间,但由于 MQL 等中间语言缺乏公开的大规模训练语料,当中间层设计得较为复杂时,未经训练的 LLM 会因不熟悉语法规则反而容易出现更严重的幻觉。即使投入成本进行 Fine-tuning,也因缺乏充足的训练样本而难以达到理想效果,准确性问题依然存在。
为了在表面上提升准确性,不得不严重压制查询的复杂性。将中间层设计得足够简单,LLM 受限后,准确性确实能大幅提高。但这又导致无法表达很多复杂业务逻辑(如多表关联、嵌套查询等)。虽然在一定程度上降低了出错率,却又限制了应用范围。无论用户如何变换问法,都无法实现复杂功能的查询,制约了其实用价值。
而且,仍然缺乏有效的确认机制。简化中间层只能降低错误率,不可能完全消除 LLM 的幻觉。而以 JSON、XML 或自定义 MQL 格式呈现的中间层对业务用户而言仍然难以理解,无法有效确认,准确性问题不能根除。
此外,实施成本也依然居高不下。中间表示本身无法解决领域知识缺失的问题,仍需依赖 Fine-tuning、RAG 等高成本技术手段将企业特定的业务知识注入模型,导致整体实施与维护成本难以控制。
当前的技术路径未能完美解决 Text2SQL 的核心挑战,这是一个“三难困境”:在现有的技术框架下,灵活性(理解多样化表达)、准确性(生成正确 SQL)与查询复杂性(支持高级操作)三者难以兼得。
两条路径看似取舍不同,但核心困境如一:生成的 SQL 或 MQL 均无法被业务用户理解和确认。当查询的准确性始终存在疑虑且无法验证时,技术自然难以落地。
针对上述困境,润乾 NLQ 提出了一种新的三阶段架构,其核心在于可由人类确认的 "规范文本",重构了人机协作的查询生成流程。
架构的转换路径:

这里增加了一个规范文本环节。从自然语言到规范文本的转换由 LLM 实现;从规范文本到 MQL 的转换由专门的 NLQ 引擎完成;从 MQL 到 SQL 的转换则就是常规的代码翻译程序了。
突破在于“规范文本”的引入,规范文本作为人类可读的中间层,为用户提供了确认查询意图的机会,这是解决准确性问题的关键。
规范文本,顾名思义,就是一种规范的自然语言形式,其价值在于同时具备人类可读性与机器可解析性。
这里列举一些规范文本的例子:
可以看到仍然是自然语言形式的规范文本并不是非常死板,有些甚至还包含了动词,解析起来有相当的难度。
类似的,再举一些不规范文本,也就是灵活的自然语言的例子:
规范文本具有一个关键特性:人机双向可读。
人类可确认性。由于采用业务人员熟悉的自然语言形式,而非 JSON、XML 等技术格式,用户能够直观理解并确认:"对,这就是我想查的!" 。确认环节是解决幻觉问题的关键。
同时,规范文本具备机器可解析性,虽然表现形式类似于自然语言,但遵循规范的结构约束和词汇表限制,可以通过确定的解析规则自动化处理。
规范文本的结构化特性为后续的 MQL 设计提供了基础,使其能支持包括多表关联、指标计算等复杂查询功能,而不会像以往中间层那样压制查询能力。
这个架构中,LLM 的角色定位发生了根本性转变。以往方法中,LLM 被期望直接生成准确的 SQL 或 MQL。而在新架构中,LLM 的任务被简化为将多变的自然语言表达转写为标准化的规范文本,这一任务与 LLM 的语义理解能力匹配。
这种角色转变带来了显著优势。 LLM 仅需按照简单的 prompt 规则进行文本变换,无需深度理解企业特定的领域知识。现成的通用大模型就可以工作,不再需要投入高昂成本进行 Fine-tuning 或构建 RAG 知识库。实施工作转变为构建 NLQ 业务词典,这个任务的技术门槛远低于模型训练,普通开发人员即可胜任。
任务简化还带来了成本优势。LLM 的提示词长度大幅缩减,推理过程更加轻量,单次查询的token 消耗和计算成本可降低 1-2 个数量级。NLQ 引擎基于规则实现,涉及的词汇在数千到数万量级,不需要多大算力,用普通 CPU 即可实现高并发处理,整体成本很低。
在稳定性方面,即使 LLM 在生成规范文本时出现偏差,也有两重保障:一方面,规范文本的人类可读性使用户能够及时发现并纠正问题;另一方面,NLQ 引擎会对输入进行校验,确保只有符合规范的文本才会进入后续流程。
基于规范文本的 NLQ 架构成功解决了 Text2SQL 的困境,实现了灵活性、准确性和复杂性三者兼得。 LLM 处理自然语言的多样性,确保了灵活性;规范文本的可确认性和后续的确定性转换,保障了准确性;规范文本的结构化特性为复杂查询提供了基础,企业级应用的需求能够得到满足。
其实,规范文本的生成并不强制依赖 LLM。由于规范文本本身就是自然语言形式,业务人员经过简单培训后可以直接编写,此时甚至不需要 LLM,只用 NLQ 引擎解析规范文本就可以实现 Text2SQL,这就形成了成本更低的解决方案,以适应更多应用场景。
通过规范文本的创新设计,在自然语言的灵活性与机器处理的确定性之间找到了平衡点。特别是可确认的 "规范文本" 这一中间表示,解决困扰 Text2SQL 领域的准确性问题,为其在企业级应用中落地提供了切实可行的工程路径。
引入 MQL 层具有重要意义。作为规范文本的确定性编译目标,MQL 承担着双重使命:首先,要利用它彻底消除自然语言中可能存在的残余歧义,规范过的文本,仍然有可能存在多种合理的解释或者无法解释,还需要有种严格的语法来确定最终的查询意义;其次,它要通过精心设计的语法结构限制查询能力,杜绝过于随意的查询请求,但仍要保持足够的复杂度。既满足企业级复杂需求,又可以基于可控性获得准确性。MQL 需要精心设计以平衡表达力与规范性。
接下来将继续解析 MQL 的设计逻辑及其实现机制。
MQL 承担着承上启下的作用。作为规范文本的确定性编译目标,需要建立精确的语义基准,消除自然语言中可能存在的残余歧义。同时通过精心设计的语法结构,在保持对企业级复杂查询足够表达力的前提下,将查询能力限制在合理范围内,确保可控性与准确性。
这种平衡体现在 MQL 的四类查询范式中:单表明细查询、单表汇总查询、多表明细查询、多表汇总查询。这些范式基本覆盖了 BI 场景下的典型查询模式,为从规范文本到精确查询的转换提供了系统的表达框架。
文本:“订单金额不低于 1 千元的订单”
MQL 实现:
SELECT 订单金额 as 订单金额,订单编码,客户名称,签单日期,发货日期,收货日期
FROM orders
WHERE 订单金额>=1000这是最简单的查询范式,基于单一数据源且不涉及聚合计算。MQL 在此场景中的作用主要体现在:
此类查询常见于基础数据检索和简单条件过滤,为其他查询提供基础能力支撑。
文本:“各城市发货总金额”
MQL 实现:
SELECT orders.sum(订单金额) as 总金额
ON city as 城市
FROM orders
BY 发货城市这里引入了维度和聚合的概念,体现了 MQL 的核心价值:
此类查询是 BI 分析的基础,MQL 通过清晰的语法结构将业务分析需求转换为准确的数据聚合逻辑。
文本:“订单数大于 5 的客户信息以及总订单金额”
MQL 实现:
SELECT
客户编码,
客户名称,
联系人,
联系人职务,
城市编码,
orders.count(DISTINCT 订单编码) AS 订单数,
orders.sum(订单金额) AS 总订单金额
FROM
customer
JOIN
orders
HAVING
(订单数> 5)这个例子展现了 MQL 处理复杂数据关系的能力:
此类查询满足了在主体信息基础上附带相关统计指标的业务需求,体现了 MQL 在复杂场景下的表达能力。
文本:“各个类别的订单总数和在线订单数”
MQL 实现:
SELECT orderdetail.count(DISTINCT 订单编码) as 订单总数,
website_event.sum(在线订单()) as 汇总在线订单数
ON ProductType as 类别
FROM orderdetail
BY 产品类别
JOIN website_event
BY 产品分类这是更复杂的指标查询范式,展现了 MQL 的高级特性:
此类查询常见于跨主题的综合分析场景,MQL 通过统一的维度模型和指标体系,实现了数据关系的简洁表达。
这四项查询范式能够描述从简单筛选到复杂跨源分析的各类 BI 场景,为自然语言查询提供了较全面的表达能力。同时,MQL 采用类 SQL 的语法设计,具备严格的规范性,将查询能力进行限制,杜绝过于随意的查询请求,但仍保持了足够的复杂度,在表达力与规范性之间有效平衡。
仔细观察上面的 MQL 语法,多表查询的语句只是处理了聚合后的对齐,SQL 中经常出现的多对一的外键关系并没有出现。比如在订单中引用其客户地址,也就是主查询表是订单表,但要和客户表 JOIN 获取其地址信息。
MQL 可以应对这种外键关联场景吗?如何应对呢?
答案是 MQL 和 SQL 之间还有一个中间层DQL(Dimensional Query Language),一种基于维度的查询语言。DQL 通过 "外键属性化" 特性,巧妙地解决了表间关联的复杂性。我们通过具体实例说明这一机制:
比如用户输入“请帮我查一下北京发往青岛的订单”,首先会由 LLM 转换成标准文本“北京 发往 青岛 订单”,接下来 NLQ 引擎解析后生成 MQL:
SELECT 发货城市 as 发货城市,收货城市 as 收货城市,订单编码,客户名称,签单日期,发货日期,收货日期,订单金额
FROM orders
WHERE (发货城市=30101) AND (收货城市=20201)到这一步还只有订单表,不涉及客户表。
然后,这一句 MQL 将会被进一步转换为 DQL:
SELECT shipcity, customerid.citycode,ordered,customerid,signdate,shipdate,receivedate,amount
FROM orders
WHERE shipcity=30101 and customerid.citycode=20201这时候还是没有出现客户表,但收货城市被转换成了一个对象形式:customerid.citycode。cutstomerid 是订单表的字段,而 citycode 则是客户表中的字段。
DQL 引擎会再生成可执行的 SQL:
SELECT o.shipcity, c.citycode, o.ordered, o.customerid, o.signdate, o.shipdate, o.receivedate
FROM orders o
JOIN customer c ON o.customerid = c.id
WHERE o.shipcity = 30101 AND c.citycode = 20201这个最终执行的 SQL 有了显式的 JOIN 子句,关联了 orders 和 customer 两个表。
DQL 仍然基于单表查询,但在获取客户表的收货城市时使用了 customerid.citycode,即外键. 外键字段(类似对象. 属性)的方式。这种将多对一的外键关系抽象为对象属性的访问方式称为“外键属性化”,这样无论有多少层表间关联,都可以通过点操作符逐级访问到,而 FROM 后面只有一个单表,这样就巧妙地建立了表间关联,但语法中消除了显式的 JOIN。DQL 之所以可以使用外键属性化,是因为数据之间的关系已经在数据模型层面定义好了,直接使用即可。模型定义很简单,一般技术人员就能完成。
DQL 为 MQL 以单表查询实现多表关联奠定了基础,MQL 中 FROM 子句中的一个单表,在 SQL 并不是单表,它很可能是个关联很多层维表的复杂 JOIN。
尽管 MQL 和 DQL 能够覆盖大部分 BI 查询场景,但在处理复杂业务指标时仍存在局限。诸如股票连涨天数、用户留存率等需要多步计算或特殊算法的场景,SQL 的实现会非常复杂而且难以被嵌入复用,这时候需要引入更专业的计算能力,也就是SPL(Structured Process Language)。
SPL 作为专门处理复杂计算的语言,在架构中扮演着计算引擎的角色:
MQL 可以直接使用 SPL 定义的指标,比如要计算大订单数量,大订单是指订单金额超过最大金额 50% 的订单。这时就可以定义 SPL 计算指标:
(x=?1.max(订单金额)/2,?1.count(订单金额>=x))MQL 碰到用 SPL 定义的指标时,将会先生成读数用的 DQL(再转换成 SQL)执行后再用 SPL 在结果集上继续计算出这些复杂指标。如果 MQL 中没有 SPL 定义的指标,那将会被转换成 DQL 继续解析掉关联生成完整的 SQL 执行。
到这里润乾 NLQ 架构的各个组件均已呈现:
各组件在保持独立性的同时,通过清晰的接口定义实现无缝衔接,形成了一个既灵活又可靠、既强大又可控的解决方案。
润乾 NLQ 通过 MQL、DQL、SPL 的协同设计,构建了一个层次清晰、职责分明的 Text2SQL 执行机制。MQL 作为规范文本的精确编译目标,在保持足够表达力的同时确保了查询的规范性;DQL 通过维度建模和关联透明化,降低了数据访问的复杂度;SPL 则专注于复杂指标计算,扩展了系统的分析能力。
NLQ 引擎是另一个关键的技术挑战。它要具备一定程度的语言解析能力,能够准确理解规范文本中多样的表达方式。从技术层面看,这相当于构建了一个小语言模型(Small Language Model),其开发难度也不容小觑。
由于 NLQ 引擎基于规则构建,不同语种的语法规则和表达习惯完全不同,无法直接通用。例如,汉语和英语在语序、分词、句式结构等方面存在根本性差异,需要分别构建独立的解析体系。这里将先聚焦于解决汉语环境下的 NLQ 解析问题。
NLQ 规则引擎如何能像“理解了一门语言”一样,将仍有相当自由程度的规范文本准确地转换为语法严格的 MQL?这就是NLQ 词典的任务。
NLQ 词典是一个结构化的业务 - 数据映射知识库,定义了业务语言中每个“词”在数据世界中身份、行为逻辑和关联关系。
NLQ 词典围绕以下几个概念展开,它们共同构成了从自然语言到 MQL 的转换路径:
为了覆盖多样化的自然语言表达,NLQ 词典配备了多种特色词型:
下面用几个示例,理解词典如何驱动 MQL 生成。
SELECT 性别 ,…,ORDERS.sum(订单金额) AS 订单金额总和 FROM EMPLOYEE WHERE (性别 ='女') JOIN ORDERS HAVING 订单金额总和 >20*10000
SELECT EMPLOYEE.count(雇员编码) AS 员工数, PRODUCT.count(产品编码) AS 产品数, ORDERS. 大订单数 () AS 大订单数 ON 省份 FROM EMPLOYEE BY 省份 JOIN PRODUCT BY 省份 JOIN ORDERS BY 省份
这个例子展示了 NLQ 如何同时处理多表关联(员工表、产品表、订单表按省份关联)、基础聚合(计数统计)和复杂指标计算(基于相对阈值的大订单判定)。
解析过程是基于词典规则的、确定性的,不用“再训练”,每一步可追溯、可解释、可调试。当出现解析错误或无法解析的查询时,可以在规则框架下快速定位问题,是缺少词条、字段簇配置不当,还是维度映射不完整,当然也有可能是引擎的 BUG。这种可解释性将获得持续优化的能力,通过补充词典配置等操作即可修复问题。相反, LLM 过于复杂而失去可解释性,用它直接生成 SQL 或 MQL 也就缺乏可控性:生成失败时难以诊断根源,即使投入大量成本进行再训练,也难以预测和保证改进效果。
词典构建是实现准确性的核心,润乾 NLQ 提供了可视化的设计器来支持这一过程。
这个过程由懂业务的开发人员实施,技术门槛远低于 AI 模型的训练与调优,确保了 NLQ 方案的普适性和可落地性。
将 LLM 的泛化能力限定在 "文本转写" 范畴,并将企业特有的知识固化为可管理、可优化的词典规则,构建一条通往实用可靠的自然语言数据查询的工程路径。这种基于词典的规则引擎方案,使 Text2SQL 具备了可实施、可维护、可信任的企业级应用特性。
润乾 NLQ 技术已解析完毕。我们从“规范文本”破局,用“MQL”实现复杂性,继而用“NLQ 词典”保证准确性。三者环环相扣,共同构成了一个同时满足灵活性、准确性、复杂性的 Text2SQL 架构。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。