技术

Agent 越强,为什么越需要语义层

Schema 只能说明数据长什么样。本文用收入案例拆解指标、实体、维度、业务规则与验证样例,说明语义层怎样把业务含义变成可执行、可测试的契约。

技术 #Data Agent#语义层#指标管理#知识图谱#NL2SQL#数据治理

把订单表、支付表和客户表的 Schema 交给模型,它很快就能写出一条可运行的 SQL。可当用户问“上个月收入是多少”,真正的问题才开始:收入是下单金额、实收、净收款还是财务确认收入?按下单时间还是确认时间?退款归属哪个月?

这些不是模型应该自由推断的常识,而是企业自己的业务合同。Agent 能力越强、执行链越长,一个错误定义被传播到报告和动作中的代价就越大。

语义层从业务术语到口径校验的契约链

Schema 描述数据的形状;语义层规定数据在什么条件下代表什么事实、允许怎样聚合。模型可以帮助发现冲突、起草定义,却不能替指标负责人决定口径。

语义层、本体和目录各管什么

资产目录回答“有什么、在哪里、谁负责”;语义层回答“怎么算、能按哪些维度分析”;业务本体回答客户、账户、订单等概念如何识别和关联。执行与治理系统则强制实施权限、预算和审计。

本体不一定要从复杂知识图谱起步。一个受治理的实体关系模型,能明确主键、基数、有效期和身份映射,就已经解决很多 Join 放大和概念混用问题。重要的是定义可引用、可版本化、可被查询编译或验证,而不是图画得多复杂。

六类语义资产缺一不可

资产至少要明确缺失后的典型错误
指标公式、单位、时间口径、粒度、聚合、版本、负责人把支付金额当确认收入;比率直接平均
实体主键、唯一性、关系方向、基数、有效期一对多 Join 放大金额;账户与客户混用
维度层级、合法取值、适用指标、历史归属用当前地区解释历史业绩
同义词业务域、语言、候选概念与不可等同项把营收、销售额和回款无条件合并
业务规则状态过滤、币种、财务周期、用途、生效区间测试订单进入正式报表
验证样例问题、口径、查询、快照、预期结果、验证人旧 SQL 被当成永久正确答案

这些资产可以分布在词汇表、指标服务、目录和样例库中,但必须通过稳定 ID 与版本关联。复制多份自然语言说明,通常只会制造新的漂移。

“收入”案例:先绑定定义,再写 SQL

假设团队同时维护交易总额、实收金额和财务确认收入。用户只说“收入”时,可靠流程是:

  1. 检查当前报表或会话是否已绑定某个指标;没有明确上下文就澄清。
  2. 将“上个月”转换为指定时区的具体区间,确定支付时间还是确认时间。
  3. 读取退款、税费、币种和内部账户排除规则。
  4. 先形成指标、维度、过滤与版本组成的语义计划,再编译查询。

一个最小指标契约可以长这样:

{
  "metric_id": "commerce.period_net_receipts",
  "version": "1.0",
  "definition": "期间成功收款减期间成功退款",
  "expression": "sum(receipt_cny) - sum(refund_cny)",
  "time_fields": {"receipts": "paid_at", "refunds": "refunded_at"},
  "timezone": "Asia/Shanghai",
  "grain": "calendar_day",
  "unit": "CNY",
  "allowed_dimensions": ["channel"],
  "missing_input_policy": "unknown_not_zero",
  "effective_from": "2026-08-01",
  "test_suite_ref": "tests/net-receipts-v1"
}

缺失输入记为未知,而不是零;退款与收款应先按兼容粒度聚合,再对齐计算,不能直接连接两张明细表造成乘积。最终答案还应带出采用的指标版本、时间字段、数据水位和限制。

语义如何进入运行链路

语义资产只有进入执行与验证,才不只是文档:

  • 检索阶段根据业务域、实体和用途找到候选定义,冲突时保留多个候选。
  • 规划阶段形成语义计划:指标 ID、版本、粒度、维度、过滤、关联和假设。
  • 查询阶段由编译器或生成器把计划转成 SQL、DAX 或其他查询,并执行静态检查。
  • 执行阶段重新实施权限、资源和用途限制;描述里的 policy_ref 不能替代鉴权。
  • 回答阶段展示关键口径和限制,让业务用户知道这个数字到底是什么。

Snowflake 语义视图与 Cortex Analyst展示了语义模型如何为自然语言查询提供表、关系、指标和验证样例。厂商配置说明了可落地形态,但不能证明某套定义适合另一家企业。

版本治理比“补充更多描述”更重要

口径变化必须有状态和生效区间。草稿、审核中、已发布、已废弃是不同状态;引用旧版本的报表不能静默切到新版本。兼容变更与破坏性变更也应区分:增加描述可能兼容,改变公式、时间字段或粒度通常需要新版本和影响分析。

已验证查询同样会失效。它应绑定语义版本、Schema 版本和数据快照,并记录验证人和不变量。所谓 Verified Query 不是复制一条历史 SQL,而是保存一个在明确条件下经过确认的问句—语义—查询关系。

用不变量和变形测试验收

仅对比一个查询结果不足以评估语义正确性。测试集应覆盖:

  • 同义词与歧义词的澄清行为;
  • 粒度和 Join 基数,防止金额放大;
  • 时间边界、时区、财务周期和历史维度归属;
  • 指标可加性,例如比率不能跨组直接平均;
  • 未知、空集合和零值的区分;
  • 版本变更后的兼容性与受影响查询;
  • 权限不同用户是否仍得到合法口径下的结果。

还可以使用变形测试:扩大互斥时间区间时,可加指标应满足分段和;增加一个不相关过滤条件不应改变结果;交换维度展示顺序不应改变总量。它们比逐字比较 SQL 更接近业务事实。

从一个指标域开始

最稳妥的起点不是建设“企业全域本体”,而是挑一个高频决策域:整理 10–30 个关键指标、实体关系、时间与退款规则,再收集真实问法和错误案例。让 BI、Data Agent 和人工分析共同引用同一版本,观察冲突和返工是否减少。

语义层最终承担的是组织承诺:同一个词在同一上下文里,应得到可解释、可复算的同一个业务含义。没有这份承诺,模型越强,只会更快地把歧义包装成答案。