01首页 02智能体能力矩阵 03数据工程智能体 04数智基建 05行业方案 06关于我们 07技术交流
首页/产品/数据工程智能体
Semantic IR 确定性编译 八层校验 十层评测

数据工程智能体

把「一句话问数」做成一套可校验、可留痕、可评测的工程系统。 自然语言不直接转 SQL,而是先转 Semantic IR —— 中间表示让语义可校验、可留痕、可复用, 下层不再重新解释上层已确定的东西。

Architecture
15层

六大模块 · 逐层有明确输入输出

Compilation
4段

IR → Logical → Physical → SQL AST

Validation
8层

语法到结果,越靠后越危险

Evaluation
10层

目的不是打分,而是归因

01 / 问数实录

一句话问下去,
它自己走完取数、核对、成图

以下三段是同一个问题在实际系统中的连续三步,界面取自公司交付并上线运行的系统。 值得留意的是每一步都会交代「本次查询口径」——用了什么时间口径、过滤了谁、 哪些指标是直接输出、哪些地方数据不足需要人来核对。

一句话查询一利五率指标后返回的结果表格
① 一句话取数查看大图 ↗
把同一组指标按 2025H1 与 2026H1 逐月对照的结果
② 追问一句,自动改成逐月对照查看大图 ↗
由同一份查询结果直接绘制的逐月对比图表
③ 一句「做成图表」,换一种呈现查看大图 ↗
请留意第 ① 步的「本次查询口径」与第 ② 步的「两处需要业务核对」。 后者在数据出现异常走势时没有直接下结论,而是指出营业收现率同比跳升、以及某个指标全期为空, 把判断交回业务;前者把时间口径、过滤条件与聚合方式写明(比率与原值直接输出,未做 SUM / AVG 再聚合)。 口径不漂移、结论可复核,是我们更愿意用真实运行界面而不是渲染图来说明这件事的原因。
02 / 为什么企业 AI 会卡住

不是模型不够强,
而是语义没有治理。

数据库存的是一组字段,业务说的是另一套语言。这段空白靠提示词补不上—— 它需要一层被治理的语义定义,以及一套确定性的解析流程。

FAILURE MODE 01

指标口径不在词里

「销售额」是含税还是净额?是否只算已完成?同一个词在不同部门有不同算法。 口径是业务约定,不在 Schema 里——模型只能猜。

口径漂移同问不同果
FAILURE MODE 02

维度值是别名,不是常量

用户说「华东」,库里是 EAST_CHINA; 说「新能源车」,标准值是 NEW_ENERGY_VEHICLE。 映射关系不在 Schema 里。

别名未登录歧义并列
FAILURE MODE 03

SQL 正确 ≠ 业务正确

一条 1,000 元的订单被 3 个订单商品复制成 3 行,SUM 得到 3,000。语法完全合法,业务结果差三倍——行膨胀不会报错。

Fan-out静默算错
能确定性检查的,不交给 LLM。 语法 · 结构 · 指标 · 关系 · 粒度 · 时间 · 权限 · 结果 —— 八类判断由程序执行,模型只负责理解、消歧与规划。
三条技术路线的工程对比
路线语义由谁决定口径可治理失败模式
自然语言 → LLM → SQL每次重新决定无同一问题两次结果不同
解析后再让 LLM 写 SQL上层定、下层可推翻部分责任不清、口径被覆盖
Semantic IR → 确定性编译语义层一次确定有归属、有版本覆盖不足会缺指标,不会静默算错
03 / 语义建模

一个成熟的语义模型,
有六层结构

建模顺序建议:先实体 / 维度 / 维度值(能被检索)→ 再指标(能被计算)→ 再关系(能被正确 Join)→ 最后补计算规则与访问策略。

六层语义模型示意

六层结构,逐层有归属

实体与维度决定「按什么看」,维度值与别名决定「看到的到底是谁」, 指标决定「算什么」,关系决定「能不能安全地 Join」,计算规则决定「时间与口径怎么对齐」。

建模顺序建议:先实体 / 维度 / 维度值(能被检索)→ 再指标(能被计算)→ 再关系(能被正确 Join)→ 最后补计算规则与访问策略。
LAYER 01 — 02

实体与维度

实体是业务上被讨论的主体,不是物理表:一张表是一份存储,一个实体可以对应多表、视图或分区; 表会随数仓重构变化,实体名应当稳定。维度分四类:枚举、层级、时间、高基数。

Entity ≠ Table高基数不建索引
LAYER 03

维度值与别名

只存值是不够的:「华东」在订单、客户、仓库三处都存在,必须带所属实体、所属维度与维度中文名。 显示值与标准值分离,别名独立成表——可做唯一约束、可统计命中率、可为不同别名设权重。

display ≠ canonical标准值归一
LAYER 04

指标口径

区分度量、原子指标、派生指标与比率指标。指标表达业务公式,SQL 由编译器生成,方言只出现在渲染层。 比率指标声明分子分母,展开为 SUM(分子)/SUM(分母),禁止对行级比率求平均。

表达式不存 SQLis_rate 声明
LAYER 05

关系与基数

关系不仅是 Join 条件,它同时携带两个编译期约束:这条路径是否被允许、会不会改变聚合粒度。 只写 ON 条件、不声明基数的语义层,无法阻止 Fan-out。

many_to_one 不放大one_to_many 需处理
LAYER 06

计算规则与时间语义

同比口径、分摊规则、舍入与单位显式声明。时间口径是事故最集中处:期间流量与时点存量、 累计 YTD 与月度列、自然年与财年——缺失任一声明都会产生方向性错误。

stock / period 声明财年对齐
PRINCIPLE

未知语义必须保留

拿不准的点写成 unknown_semantics 待澄清, 而不是静默降级成近似字段。一个判据:如果这份模型交给不了解数据库的人, 他能据此说清「华东一类客户新能源车销售额」该怎么算,模型就算合格。

不硬选可复核
粒度与 Fan-out:五道防线
防线位置检查内容不通过时
指标粒度声明语义模型Metric.grain 是否与事实表粒度一致建模期拒绝发布
关系基数声明语义模型Join 路径两侧基数是否明确编译期拒绝生成
Join 路径合法性编译器路径是否在关系图中存在且被允许报错并提示候选路径
聚合安全性编译器 / 校验层放大比例是否影响最终指标口径改写查询或提示换粒度
结果对账结果校验层与明细合计、其他路径结果是否一致标注异常,不直接给结论
04 / 检索与链接

把用户口中的业务词,
稳定地映射到语义对象

这是整个链路里不确定性最高的一段,因此更需要工程手段: 召回与精确分开追求,低置信度不硬选,澄清必须给出有界选项。

Mention 抽取只抽词,不判类型
从问题中抽出业务词。不要让抽取器输出「华东 = region」——那会把语义判断提前塞进一个没有上下文的位置,后面的检索与消歧就没有纠正机会。「今年」「排名」「前五」这类词也是 Mention,它们决定后续的 Time 与 Operator 语义。
四层匹配召回Exact → Alias → Keyword → Embedding
精确匹配解决「用户说的就是标准说法」;别名匹配归一到标准值;关键词检索覆盖词形差异与长尾表述;向量检索只在语义相近但字面差异大时才有价值。工程顺序建议逐层补齐并分别度量命中率,先验证标准值 + 别名能覆盖多少,再决定是否引入向量。
混合检索与重排召回与精确分开追求
合并侧按 (实体, 维度, 标准值) 去重、分数归一、加权或 RRF 融合、保留 Top-K;重排侧引入完整问题、已识别对象、关系可达性与用法频次。Retriever 优化的是召回率,Reranker 优化的是精确率——两者目标不同,不能合并成一个模型。
置信度门控宁多问一句,不做错误映射
高置信度直接进入 Semantic Query;中段结合上下文继续收敛;低置信度转受控澄清。澄清不是把问题丢回给用户,而是给出有界选项,且选项来自已配置的候选,不来自模型的自由发挥。阈值按业务风险分级:涉及金额与对外披露的链路提高门槛,纯内部探索可以放宽。
低基数做索引,高基数做过滤
维度类型典型基数是否建维度值索引检索方式
性别 / 状态2 ~ 20是Exact / Alias
客户等级 / 地区5 ~ 几百是Exact / Alias / Keyword
产品类别几百 ~ 几千是(分层)Keyword 为主
客户名称千万级否精确 / 前缀过滤
合同号 / 单据号亿级否精确匹配
把全库值都做向量化,是典型的「用算力掩盖建模缺失」。 成本随基数线性增长,而召回质量并不会因此提高 —— 真正的收益来自别名表与层级结构。
高基数维度的处理原则:不作为语义召回对象,但可以作为过滤条件与下钻终点。 链路是——用户给出明确名称 → 精确 / 前缀过滤 → 命中后回填标准值 → 再进入编译器。
05 / 知识与规划

知识图谱给 Planner 提供
受治理的分析空间

不是把整张图交给模型。广度优先搜索在技术上可行、语义上不够—— 它会等权对待所有边,把上下文塞满与问题无关的节点。

知识图谱子图与受治理的分析路径

知识建模四要素

  • Concept 概念:业务上可被讨论的名词,既可以是分析概念,也可以是具体指标。
  • Relation 关系:带语义类型的有向边。类型决定可遍历方向,也决定能推出什么。
    depends_on 支持确定性拆解且贡献可加总; affected_by 只是待验证假设。 把二者混为一谈,等于把相关性写成因果。
  • Rule 规则:可判定的业务规则,约束解释,不参与数值计算。
  • Provenance 溯源:来源、审核状态、生效时间与可信度层级。没有溯源的知识不应参与推理。
子图的三条装配规则:① 只保留当前意图允许的关系类型;② 跳数上限由预算决定,不是固定值; ③ 每条边必须带可信度与出处,未验证的知识不进子图。
为什么不能简单 BFS 三跳。广度优先搜索在技术上可行、语义上不够: 它会等权对待所有边,把上下文塞满与问题无关的节点。问题问「为什么销售额下降」, 上下文里却出现仓库面积、采购人员、供应商评级。子图按相关、权威、置信、时效四个维度打分剪枝 —— 检索阶段的目标是「不漏」,剪枝阶段的目标是「不脏」。
Intent 七分类与路由含义
Intent典型问法需要的算子
Query 查询华东销售额是多少单指标单维度,可确定性执行
Comparison 比较华东与华南哪个高对齐口径与区间
Ranking 排名各地区销售额排名RANK / TOP_N
Trend 趋势最近 12 个月走势TREND + 时间粒度
Composition 构成各产品销售额占比SHARE + 合计窗
Diagnostic 诊断为什么下降进入 Planner,开环分析
Analytical 综合经营质量怎么样进入 Planner,多维评价

前五类可单次编译执行,后两类必须进入规划器 —— 这是「确定性执行」与「分析智能体」的分界线。

State 是 Planner 不失忆的前提。原始问题、当前目标、已确认事实、当前锚点、 待验证假设、已执行任务、待执行任务、证据 —— 八个字段逐轮更新,分析结束即归档。
Reflection 的位置。自检放在「生成计划后」与「结果返回后」两个检查点, 且只检查可验证的属性:引用是否完整、口径是否声明、结论是否有证据。它不能替代确定性校验。
STOP / 五类停止条件 · Planner 的核心能力是知道何时停
STOP 01

目标已满足

证据链已足以解释问题,不再继续消耗预算。

STOP 02

没有显著信号

继续查的维度变化都在阈值内,再查只是消耗。

STOP 03

最大分析深度

达到深度上限,防止概念链无限展开。

STOP 04

成本预算

任务数、时长或模型调用达上限,保留证据链。

STOP 05

知识不足

图谱中没有进一步诊断路径——此时应拒答,而不是硬编一个原因。

06 / 编译与校验

四段编译链 · 八层校验

最危险的不是报错。语法错误会被立刻发现; 「SQL 正确、业务错误」不会——它表现为一个非常自信的错误数字。 因此校验必须分布在全链路,而不是最后做一次。

STAGE 01Semantic IR业务语义的唯一权威
STAGE 02Logical Query与实现解耦,可等价改写
STAGE 03Physical Plan映射到物理表,处理粒度
STAGE 04SQL AST → Renderer同一 AST 渲染到不同数据库

最重要的一条设计:上层已经把语义确定好了,下层不再有机会重新解释 —— 这是 Semantic Compiler 与「让 LLM 再写一次 SQL」的本质区别。

八层校验 —— 越靠后越难发现,越危险
层校验对象检查内容失败动作
① SyntaxSQL 文本 / AST能否被目标数据库解析拒绝生成,报语法位置
② Schema表与字段表存在、列存在、类型兼容、函数支持拒绝执行
③ SemanticIR ↔ Logical ↔ AST三者语义是否一致回退重编译
④ Metric指标口径是否使用了 Metric Graph 定义的计算方式拒绝执行并提示正确算法
⑤ RelationshipJoin 路径路径是否被允许、基数是否正确、是否 Fan-out改写或拒绝
⑥ Grain聚合粒度是否把不同粒度的数据错误聚合拒绝或换粒度
⑦ Time时间语义期间 / 时点、财年、同比区间对齐修正区间或报错
⑧ Permission权限行级与列级授权是否生效改写为授权范围或拒绝
⑨ Result执行结果合理性、量级、勾稽、交叉验证标注异常,谨慎回答

护栏:权限、拒答、可追溯、对账

  • 权限必须确定性执行。不能在提示词里写「用户只能看华东」。权限必须在编译器与执行层注入,并在校验层确认生效。
  • 拒答(Abstention)。「现有数据可以确认 A 与 B 相关,但不足以可靠判断 C」——这比给出三个可能原因更专业。
  • 可追溯(Traceability)。语义定义 → 查询 → 数据 → 证据 → 结论,任何重要结论都要能反向点回原始查询。
  • 对账与交叉验证。总数与明细勾稽,同一指标用两条独立路径计算。差异超阈值时先查口径,不要先解释。
结果校验可以做到什么程度。利用指标的元数据:类型(比率 / 金额)、期望区间、典型区间。 毛利率 35% → 正常;毛利率 850% → 触发异常告警;员工人数 18.7 → 明显不合理。 注意:异常不等于错误,而是提示「需要重新检查」,不能自动改写结论。
编译失败时的行为。找不到合法路径、基数未声明、粒度不匹配 —— 应当报错并给出候选路径, 而不是生成一条「能跑」的 SQL。
07 / 分层评测

评测的目的不是打分,是归因

同一个错误答案,可能是没召回、映射错、口径错、规划跑偏或结论越界。 分层评测让每一个错例都能定位到具体一层。

十层分层评测 —— 测试集必须包含歧义、越权、脏数据、口径冲突等历史事故类型,而不只是正常问题
层评测对象核心指标失败时的定位价值
01Mention 抽取Mention Recall / Precision区分「没抽到词」与「选错了对象」
02语义检索Recall@K判断是检索漏召还是重排出错
03实体 / 维度链接Linking Accuracy定位映射错误
04指标解析Metric Resolution Accuracy定位口径选择错误
05查询语义Operator Accuracy定位排名 / 同比等算子被漏掉
06意图分类Intent Accuracy定位路由错误(该分析却单查)
07Semantic IRIR Exact Match / 语义等价判断上层理解是否完整
08Planner路径合法率 / 证据覆盖率 / 无效查询率判断分析策略优劣
09SQLExecution Accuracy判断编译与执行
10答案Groundedness / Abstention Accuracy / 幻觉率判断结论是否有证据支撑
08 / 真实落地

把方法用在一套真实数仓上

这一节不是案例包装,而是把每一层对应到真实数仓上:哪些地方按设计执行了, 哪些地方被真实数据推翻。范围决策先于建模——653 张表里排除 37 张 0 行空表, 排除理由与范围一起落盘,换人接手可复核。

653张
建模范围 dm 表
全列扫描 22,155 列 · 约 131 亿行
336实体
已发布语义实体
5,640 指标 · 9 关联 · 7 个主题域
420张
粒度经唯一性探针证实
229 张未证实 · 4 张未探针
44轮
经营问答
产出 12 份可复算 HTML 报告
粒度不靠命名推断:唯一性探针四档递进
档位候选键构成实测结果
第 1 档全部业务键列(按基数升序)420 张首先通过
第 2 档业务键列 + 业务时间列多数宽表在此档通过
第 3 档全部维度列 + 业务时间列部分明细表在此档通过
第 4 档全列组合(仅 ≤3,000 万行的表执行)229 张仍未证实

宁可少发,不发口径不明的

  • 219 个单位未定(留草稿)。注释与列名都判不出单位时写 unit: 待确认 并登记评审,不填一个看起来合理的值——占位符不是单位。
  • 196 个粒度未证实(留草稿)。没有粒度就没有可加性,无法判断 SUM 是否正确。
  • 82 个注释错位(留草稿)。多列共用一条注释会直接污染业务名与单位。
门禁三态:pass / fail / unknown。fail 一律阻断;unknown 必须被显式接受才可发布 —— 「unknown ≠ pass」是最容易被忽略、也最关键的一条。结构门禁保证声明自洽, 评审包负责语义可用,两者不可互相替代。
09 / 缺陷与边界

最贵的错误
不在语法里

结构门禁 fail = 0,端到端冒烟却 0/8 全挂。 「声明自洽 ≠ 能跑」—— 这三个真实缺陷,是我们对交付质量的理解方式。

缺陷一 · base_filter 与 delete_time0/8 → 40/40
编译器对未声明 base_filter 的实体会无条件注入 delete_time IS NULL, 而 653 张表里只有 1 张有这一列——等于给其余全部表注入了不存在的条件。修复:在实体上显式声明 base_filter, 并把判断理由写入 caveats 留痕;抽样 40 个实体真编译、真打库,40/40 通过。 本体自身的声明是自洽的,只有把 SQL 真的打到数据库上,才会暴露「列不存在」这类缺陷。
缺陷二 · 时间语义的静默丢数112 个实体曾恒假
时间列为 day_id,实际存 20260115, 过滤条件却渲染成 day_id < '2026-10-01'—— 字符串比较恒假,查询返回空,且不报错。它不产生异常、不产生红字,只是让「有数据」变成「没数据」。 修复后对全部有时间声明的实体做全量健康扫描,静默丢数归零。
缺陷三 · 单位解析三连修1,628 → 1,689 个指标
期间词被当成单位(「考核终端已执行配额_月汇总」被判成单位 = 月);数值型标识列被建成 SUM 度量(求和年份没有业务含义); 「完美订单交付率(分子)」中的「分子」污染了比率判定。最终定下单位判定优先级: 括号强单位 → 列名后缀 → 注释强单位 → 括号弱单位 → 比率判定。 一条小规则会影响上百个指标,值得为它写优先级链而不是打补丁。

在阻断面前:拒答,而不是编数

不会在没有数据的情况下编造数字,也不会拿旧结果凑另一个口径——两者不是同一口径、时间范围也对不上。 已把恢复后要跑的分析范围写清,等数据源恢复即执行。

  • 先量级,再结论。异常先算占比:净入库为负 27 家合计 -1,703 件,占全量 -0.06% —— 属正常退货/调出,不制造处置动作。
  • 选表先查数据截止期。10 张表已停更(最久停在 2025-07-19),2 张表存在未来日期。
  • 不猜单位、不猜口径。数量列注释单位不一致且语义未定义时,按「不猜」原则不发布该指标。
  • 只写「变化发生在哪里」。结论止于结构定位,因果另案——不把相关性写成因果。
正常停止
目标满足 / 无显著信号
输出要求
结论 + 证据链 + 口径说明
预算停止
深度 / 任务数 / 时长任一超限 → 列出未展开方向
能力停止
知识不足 / 工具缺失 → 明确拒答边界,不给推测性原因
异常停止
校验失败 / 数据不可用 → 报告失败原因与已获得的证据
Knowledge 说「可能查什么」,
Evidence 说「实际发生了什么」。 知识、规则、图谱、检索候选都不是证据,只有查询结果才是。
10 / 交互演示

看一眼 Semantic IR 长什么样

以下为语义链路演示,数值为示例数据;真实结果由受治理查询返回,并附带完整口径说明。

SEMANTIC IR / 交互演示

选择一句业务提问,观察它如何被翻译成结构化的语义中间表示,而不是直接拼成 SQL。

注意 unknown_semantics 字段。 拿不准的语义写入待澄清项,而不是静默降级成近似字段。
NEXT / 从一次具体的技术对话开始

先看能不能算准,
再谈跑得多快。

我们可以用你现有数仓的一小部分表做一次语义建模与端到端冒烟, 连同失败样本一起交付——包括那些我们没能算准的部分。

成都微银合创科技有限公司
Address
四川省成都市高新区吉泰五路 88 号
香年广场 T2
Telephone
028-82880460/13808180736
Email
business@weinventing.com