销售负责人问:"上个月华东区的销售额是多少?"在 Text-to-SQL Demo 中,这个过程通常很顺畅:
-
模型识别"上个月""华东区"和"销售额";
-
找到对应的表和字段;
-
生成 SQL 并提交查询;
-
返回一个数字或一张图表。
但在真实企业中,数据团队往往还需要追问:
-
"销售额"按合同额、开票额、回款额,还是已确认收入计算?
-
"华东区"按客户注册地、项目所在地,还是销售组织归属划分?
-
"上个月"对应自然月、财务月,还是业务自定义周期?
-
当前提问者可以查看华东区全部数据,还是只能查看自己负责的客户?
这些问题并不属于 SQL 语法,却会直接决定 SQL 应该如何生成,以及最终答案是否符合业务预期。
这也是 Text-to-SQL 从 Demo 进入生产环境时需要面对的核心差异:Demo 主要验证模型能否把自然语言转换为可执行的 SQL;企业生产环境还要求系统正确理解业务定义、遵守权限,并说明答案是如何得到的。
环境差异:Demo 预设表结构与问题范围
Demo 环境与真实企业数据环境的差异,可以概括为以下几个方面:

在 Demo 中,数据库结构和问题边界通常经过筛选。模型面对的候选答案较少,表、字段与业务概念之间也更容易建立对应关系。
真实企业环境则不同。模型不仅需要找到一条能运行的查询路径,还要从多个可能的表、字段、关联关系和业务口径中做出选择。如果缺少明确约束,这些选择很容易变成基于名称和上下文的推测。
Text-to-SQL 进入生产后常见的四类问题
1. 数据映射问题:模型可能选错表与字段
企业数据库中经常同时存在原始表、加工表、宽表、临时表和已停用的历史表。字段命名也未必能够直接表达业务含义。
例如,在回答"上个月的销售额"时,模型可能:
-
选择订单明细表,而实际经营分析使用的是收入确认表;
-
将
order_date作为统计时间,而标准口径使用recognized_date; -
根据字段名称自行判断表之间的关联关系;
-
使用仍可查询、但已不再维护的历史字段。
这类问题不一定会造成 SQL 报错。查询可能正常执行,结果也可能处于看似合理的范围内,但所选数据并不符合企业实际采用的定义。
因此,"SQL 执行成功"只能说明查询在技术上成立,不能说明数据选择在业务上正确。镜舟在上下文治理层 MirrorMind 里处理这类问题的方式,就是把"销售额该用哪张表、哪个字段"这类判断提前确认下来,做成一份可以被复用和检查的映射关系,而非让模型在每次查询时重新推断。
2. 指标定义问题:同一指标存在多种业务口径
同一个业务概念可能对应多种计算方式。不同口径不一定互相矛盾,它们可能分别服务于财务核算、销售管理和经营分析。
以"销售额"为例:
-
财务部门可能关注已确认收入;
-
销售团队可能关注合同签约金额;
-
经营分析可能使用扣除退款和一次性项目后的调整口径;
-
管理层周报可能按照固定汇率进行跨区域比较。
当用户只提出"查询销售额"时,模型需要知道当前场景对应哪一种定义。如果企业没有把这些口径明确记录并与适用范围关联,模型只能根据字段名称、表描述或提示词进行判断。
这也是同一个问题在不同模型、不同提示词或不同轮次中可能得到不同答案的原因之一。变化的不只是生成出来的 SQL,更是 SQL 背后没有被固定下来的业务选择。
镜舟在新产品 MIP (MirrorShip Intelligence Platform)里 NL2SL2SQL 的设计思路也是针对这一点:自然语言先对齐语义层,确认当前场景应该采用哪一种口径,再生成 SQL,而非让模型直接面对裸表去猜测。
3. 权限控制问题:现有规则未必覆盖 Agent 查询
在传统 BI 场景中,用户通常通过已经配置好的报表和数据集查数。部分权限规则已经固化在账号、看板或数据集内。
自然语言问数提供了更灵活的查询方式。Agent 可以组合多个字段、跨表检索,并生成过去没有预定义过的查询路径。这意味着权限控制不能只依赖最终访问了哪张表,还需要考虑:
-
谁提出了问题;
-
用户当前所属的角色和组织;
-
可以访问哪些指标、维度和数据范围;
-
查询过程中调用了哪些数据和工具;
-
最终结果是否包含不应暴露的信息。
如果这些规则没有进入问题理解、查询生成、执行和结果返回的完整链路,系统即使给出了正确答案,也可能不符合企业的数据访问要求。
我们把这一层校验放在闭环控制层 MirrorControl 里统一校验:身份与工具级权限、成本护栏、审批节点和全链路 Trace 贯穿查询生成和执行的每一步,而非依赖每张报表或每个数据集各自配置一套规则。
4. 结果说明问题:缺少口径、范围与数据来源
假设系统回答:"上个月华东区销售额为 2,300 万元。"业务用户可能继续关心:
-
使用了哪一种销售额口径?
-
华东区的范围如何定义?
-
数据更新到什么时间?
-
是否排除了退款、测试订单或内部交易?
-
数据来自哪些表,经过了哪些计算?
只展示最终数字,难以回答这些问题。直接展示 SQL 也不一定足够,因为业务用户通常更关心计算逻辑、业务口径和数据范围,而非查询语句本身。因此,企业数据问答需要同时提供结果和必要的解释信息。
在镜舟看来,"可解释"和"可追溯"应该是同一次回答自带的两个属性,不应该用户质疑之后才补充的说明,前者说清楚用的是什么口径,后者留下能被检查的执行痕迹。
理解过程:为什么SQL 生成前需要进行业务判断?
Text-to-SQL 主要解决自然语言与查询语言之间的转换。企业问数还包含一组发生在 SQL 生成之前的判断。
可以把完整过程拆分为五个环节:

生成 SQL 只是其中一个环节。如果前面的业务判断没有被明确表达,模型即使生成了语法正确的 SQL,也可能无法稳定得到符合业务预期的答案。
这类问题也很难只通过增加提示词解决。提示词可以补充某一次查询的背景,但企业的指标定义、对象关系和权限规则会持续变化,也需要被不同用户、模型和 Agent 重复使用。把这些信息分散在提示词、文档和个人经验中,会增加维护和验证的成本。
语义约束,统一定义指标、关系与权限
让自然语言问数进入生产环境,需要在用户问题和底层数据之间建立一层可复用、可约束的业务语义。
这层业务语义至少需要明确:
1.业务对象:客户、订单、合同、产品等概念如何定义;
2. 指标与维度:指标如何计算,可以按哪些维度分析;
3. 对象关系:不同业务对象和数据实体之间如何关联;
4. 适用范围:不同口径分别适用于哪些部门和分析场景;
5. 权限规则:不同身份可以访问哪些对象、指标和数据范围;
6. 解释信息:结果需要展示哪些口径、来源和计算依据。
它不是简单地为字段增加一段文字说明,也不是替模型直接回答问题。它更像一份可以被系统读取、由业务人员验证的约定,让模型在生成 SQL 之前,先将自然语言映射到企业已经定义的业务概念和规则。
语义视图(Semantic View)可以被理解为这种约定的一种实现方式。它把指标、维度、关系和约束组织成面向查询的语义定义,减少模型直接面对裸表时需要自行猜测的内容。
我们把这层语义视图,做成了系统可以直接读取和执行的定义内置在数据引擎 MirrorBase,这样每接入一个新模型或新 Agent,都不需要重新学习一遍这些业务规则。
当一个问题存在多个合理解释时,系统也不应默认选择其中一种。更合适的处理方式可能是向用户澄清口径,说明当前采用的定义,或在问题超出已有语义范围时暂停生成。这些行为虽然不像"立即给出答案"那样流畅,却更符合企业使用数据时对确定性的要求。
从查询入口走向生产系统
Text-to-SQL 降低了使用自然语言查询数据的门槛,但自然语言入口本身不能替代企业已有的数据定义、权限和治理工作。
从 Demo 走向生产,需要补齐的也不仅只是 SQL 生成准确率,也需要一条从业务问题到查询结果的完整链路:
明确业务含义 → 选择统一口径 → 应用权限约束 → 生成并执行查询 → 解释和追溯结果
当这条链路能够被持续维护,并被不同模型、Agent 和数据应用复用时,自然语言问数才更有可能稳定地服务于真实业务。
Text-to-SQL 本身不会消失,它仍然是自然语言进入数据库的入口。真正决定它能否走出 Demo 的,是入口背后有没有这样一层持续维护的业务理解。