「让大模型直接写 SQL」听起来是最短的路:用户问一句,模型生成 SQL,查库返回。可在有几百张表、口径互相打架的真实数仓里,这条路很快就不稳——最麻烦的还不是报错,而是 SQL 跑通了、业务含义却错了。这篇写给数据架构师和 Data Agent 选型者:稳定的企业级问数,地基为什么是语义层,而不是更强的模型。
在亿问 Data Agent里,我们自研的SemanticDB 承担语义层的角色。
本篇文章介绍了 SemanticDB 为什么是亿问 Data Agent的核心基础设施:它如何用实体和事件表达业务世界,如何用 LogicForm 承接自然语言理解结果,如何把业务意图稳定地落到 SQL、API 或 URL 等不同执行方式,以及为什么这条 NL2LogicForm2SQL 路线比直接 NL2SQL 更适合真实企业场景。
亿问 Data Agent 不直接把自然语言翻译成 SQL。我们的整体链路是:
自然语言 -> LogicForm -> SQL其中,自然语言到 LogicForm 由亿问 Data Agent的上层理解模块(Alisa)完成。
语义数据库 SemanticDB 负责两件事:
所以,SemanticDB 不是 SQL 生成器前面的一个"薄封装",而是亿问 Data Agent能不能稳定理解业务、复用口径、跨库执行的基础。
直接 NL2SQL 看起来路径最短:用户问一句话,系统生成一段 SQL,然后去数据库执行。
但真实业务里,问题很少这么简单。
用户说"销售额""门店""本月""新客""同比",这些词并不等同于数据库里的某个字段。它们背后通常有固定的业务口径、跨表关系、时间规则、权限限制和数据库方言差异。
如果直接让大模型生成 SQL,大模型就必须同时完成几件事:
这就像让一个人同时做翻译、架构师、DBA 和业务专家。任何一步出错,最终 SQL 就错。更危险的是,很多错误是"SQL 能执行,但业务含义不对",这种错误在执行层无法发现。
核心问题:直接 NL2SQL 把太多责任压给模型,而模型在处理企业级复杂度时,缺乏足够的约束和可追溯性。
亿问 Data Agent 选择了一条不同的路:NL2LogicForm2SQL。
这条路线的核心思想是:把"理解业务"和"执行查询"分开。
模型负责理解用户问题,识别业务对象、指标、维度和时间条件。
LogicForm 作为中间层,承载结构化的业务意图。
语义层把 LogicForm 翻译成 SQL、API 或 URL。
这样做之后,难度被重新分配了。
大模型不再需要一次性完成所有事情。它主要负责理解用户语言,并选择合适的业务对象、指标、维度和时间条件。
语义层负责:
这使得系统更稳定,也更容易治理。
直接 NL2SQL 时,模型面对的是整个数据库结构。表名、字段名、关系路径、指标口径都可能需要模型猜。有了语义层,模型面对的是经过整理的业务世界。它需要选择业务概念,而不是临时发明 SQL。这会显著降低幻觉空间。
没有语义层时,很多业务规则只能写在提示词里。提示词可以提醒模型,但不能真正保证一致性。有了语义层后,指标、时间、关系和结果解释都可以沉淀成系统能力。这意味着同一个指标在不同问题、不同报表、不同用户那里可以复用同一套口径。
NL2SQL 最容易错的地方之一,就是跨表关联。语义层提前描述业务对象之间的关系,系统知道销售和门店、产品、客户之间如何关联,也知道门店和区域之间如何关联。因此,用户问跨对象问题时,系统可以走业务关系,而不是让模型临时猜连接路径。
经营分析中,时间口径一旦错,结论就会错。语义层把"今年""本月""同比""环比""截至目前"等表达统一处理,避免每次都让模型单独生成时间条件。这对 BI 类问题尤其关键。
上层表达的是业务意图,不是某一种数据库的 SQL。当底层数据源变化,或者同一套业务模型运行在不同数据库上时,语义层可以承担方言适配工作,上层自然语言理解部分不需要大幅调整。这让系统更适合多项目、多数据源、多客户环境。
有了 LogicForm 作为中间表达,系统就不再是一个黑盒。当结果不符合预期时,可以逐层判断:自然语言是否理解错了?业务对象或指标是否选错了?时间条件是否归一化正确?跨对象关系是否走对了?SQL 生成是否符合数据库方言?结果包装是否符合业务预期?这比直接检查一段模型生成的 SQL 更可控。
对亿问 Data Agent的上层智能体来说,SemanticDB 提供的不是一个普通查询接口,而是一个可执行的业务语义运行时。
它提供的是:
所以,上层模型真正要做的事情,不再是"直接写对 SQL",而是:
剩下的跨表关系、时间对齐、数据库方言、复杂指标拆解、结果包装,都由语义层处理。
这就是 NL2LogicForm2SQL 相比直接 NL2SQL 更工程化的地方。它不是让模型一次性做完所有事,而是让模型做它擅长的语义理解,把结构化执行交给系统。
语义层不是为了让 SQL 生成多一层流程,而是为了把数据问答从"一次性生成"升级成"可建模、可复用、可测试、可治理"的系统。
它把底层物理数据抽象成业务世界,把自然语言问题收敛成结构化意图,再把结构化意图稳定翻译成数据库查询。
对一个真正要在复杂业务场景里工作的亿问 Data Agent来说,SemanticDB 这样的语义层不是可选项,而是系统成立的前提。
不在模型能力,而在企业数仓的复杂度。真实场景下有几百张表、数千字段、跨部门口径差异、异构数据血缘。直接让大模型生成 SQL,它必须一次性完成意图理解、表关系推理、口径判断、时间处理和方言适配——任何一步错了,最终结果就错。更危险的是,很多错误是"SQL 能执行但业务含义不对",无法通过执行层发现。
传统 ER 模型围绕表和字段之间的关系建模,是数据库层面的抽象。实体-事件建模围绕业务对象和业务事实建模——"客户购买产品"是一个事件,客户和产品是实体,购买是事件。这种建模方式更接近业务人员理解世界的方式,让系统在处理自然语言问题时能先理解"哪些业务对象之间发生了什么关系",而不是"从哪几张表查什么字段"。
MQL 通常只能表达"取哪个指标、按哪个维度聚合"。LogicForm 的表达能力更高一个级别:支持 from 嵌套查询(先查询再基于中间结果继续分析)、piecewise 动态分组(按业务规则临时切分区间)、currency 汇率计算(多币种多汇率口径)、同比环比占比达成率等复杂分析逻辑。表达能力越丰富,系统能稳定覆盖的业务问题就越多。
语义层把上层业务表达和下层执行方式完全隔离。同一个 LogicForm 可以被翻译成 ClickHouse、MySQL、PostgreSQL、Oracle、SQL Server、StarRocks 等不同数据库的 SQL。时间函数、正则、数组、子查询、分页、聚合语法的方言差异全部由语义层在 LogicForm 到 SQL 的翻译阶段处理,上游理解模块不需要感知底层数据库类型。
LogicForm 作为中间表达,让系统从黑盒变成可逐层排查的管道。出问题时可以依次判断:自然语言理解是否正确、业务对象和指标是否选对、时间条件是否归一化正确、跨对象关系是否走对、SQL 是否符合目标数据库方言、结果包装是否符合业务预期。每一层都可以独立验证,比直接审查一段大模型生成的 SQL 更可控,也让系统优化从"调 prompt 碰运气"变成有据可循的工程过程。
★ 为亿问自有技术术语。词条详见「亿问技术词典」栏目。