AI + Data中的 Semantic View:从语义层到 AI 可用的“业务语言”

0 阅读20分钟

面向读者:数据平台/数仓/湖仓架构师、数据工程师、分析工程师、AI 应用工程师、数据治理负责人

  1. 背景:为什么“语义”成了 AI 时代的数据平台刚需 传统 BI 时代,数据团队最常见的内耗之一就是:同一个指标,不同团队算出不同结果。

到了 GenAI / Agentic Analytics 这波浪潮,这个坑不但没消失,反而更容易被放大:

业务同学问一句“本季度 NRR 多少?”

BI 报表给出一个数字

数据科学同学在 Notebook 里算出另一个

LLM 做 Text-to-SQL 又吐出第三个数字,还能顺便写一段听起来很“像那么回事”的解释

很多时候锅不在工具,而在更基础的东西:

业务概念没有以结构化方式沉淀成可复用资产

语义没有变成平台级资产(平台原生、可治理、可发布)

说得直白一点:组织需要一层稳定的“翻译器”,把业务语言和数据的物理结构(表、字段、Join 、过滤、权限)对齐起来,并且让 BI、数据应用、AI/Agent 都复用同一套定义。

本文要聊的核心就是:Semantic View。

  1. Semantic View 是什么?不是普通 View,也不只是“指标层” 2.1 定义(从平台视角看) 你可以把 Semantic View 理解为:

Semantic View(语义视图),本质上是在数据之上加一层“可理解的业务语义层”,把底层复杂的数据结构(表、字段、Join、计算逻辑)抽象成业务可读、可复用的指标与维度。

一个像样的 Semantic View,通常至少要解决这些事:

抽象:把物理表结构抽象成业务对象(指标、维度、实体关系)

一致:指标定义一次,多工具复用,少写一堆重复 SQL

可治理:权限、审计、血缘、认证等跟着语义对象走

AI 就绪:给机器一份“读得懂、查得到”的业务上下文,别让模型靠猜

2.2 和普通 SQL View / Dataset 的差别 维度 普通 SQL View 语义 View(Semantic View) 目标 复用查询 / 简化 SQL 统一业务语义 + 多消费面输出一致 指标可重用性 指标常写死在 select / group by 指标定义与维度分组解耦,运行时按任意维度切片 Join 管理 依赖使用者手写 关系声明是模型的一部分,可复用/可推导 治理 主要靠底层表/视图权限 语义对象可携带治理与元数据(owner、certification、policy、audit) AI 友好性 LLM 仍要理解字段含义/Join 路径 提供“业务词典 + 指标定义 + 同义词 + guardrails” 2.3 语义层、指标层、语义 View:怎么把这些名词放回正确位置 行业里叫法很多:Semantic Layer、Metrics Layer、Semantic Model、Metric View、Semantic View……

如果用更工程化一点的拆法,会清楚不少:

语义层(Semantic Layer):一组能力的集合,用来统一业务语义

语义模型(Semantic Model):语义层里的模型定义(实体/关系/维度/指标/规则)

语义视图(Semantic View):语义模型在平台里的可执行/可发布形态(对象/资源/接口)

指标层(Metrics Layer):语义层的一个子集,更聚焦指标的标准化与复用

落地时常见几种形态:

把 Semantic View 做成数据库内对象(schema-level object)

做成 catalog 管理的对象,用 YAML/DSL 描述

或者干脆做成 headless API(语义层服务化)

  1. 为什么在 AI + 数据平台里,Semantic View 更重要? 3.1 让 AI 从“写 SQL”变成“调用业务真相接口” 纯 Text-to-SQL 的坑其实挺集中:

字段含义不确定:revenue、sales_amount、gmv 到底哪个是财务口径?

Join 路径不确定:订单 join 用户,还是账单 join 合同?

过滤条件容易漏:测试账号、退款、内部订单、跨期规则……

难审计:LLM 生成的 SQL 怎么保证口径一致、怎么追责?

Semantic View 的思路更像“先把规则固化,再让调用方组合”。常见链路大概是:

复杂逻辑提前沉淀成指标/维度/关系

查询时尽量少直接碰底层明细表

先检索语义模型(可用指标、维度、释义、同义词、权限)

再通过平台提供的语义查询接口执行

结果很直观:AI 的工作从“生成任意 SQL”变成“选对语义对象并组合查询”。模型能发挥的空间变小了,稳定性反而更高。

3.2 让组织从“对数”走向“对语义资产” 没有语义层时,很多团队的协作路径是这样的:

会上对齐一次口径

然后把口径塞进各类报表、脚本、Notebook

口径一变,开始到处改、到处对数

有了语义层/语义视图后,协作对象就更像“资产”:

可版本化的语义定义(Semantics as Code)

可认证、可审计的指标资产

从治理角度看,这类投入减少的是“决策债务”:口径越晚统一,未来返工和扯皮的成本越高。

3.3 让治理更像系统能力,而不是每个工具重复配置 多 BI、多数据应用、多 Agent 的环境里,差异会很明显:

语义散落在各工具:权限、行列级策略、脱敏、审计要重复做

语义对象在平台内:治理策略跟着语义对象走,消费面天然继承

这在合规场景(审计、访问记录、可追溯性)里尤其关键。

  1. Semantic View 的核心能力清单(你通常会期待它具备什么) 下面按“能力清单”把一个成熟的 Semantic View(或语义层)常见要素梳理一下。

4.1 语义建模:指标、维度、实体关系 维度(Dimensions):切片、分组、过滤的业务属性

例:地区、渠道、客户等级、产品层级、财年、自然月

度量/指标(Measures / Metrics):可聚合的业务结果

例:收入、活跃用户数、NRR、转化率、留存率

关系(Relationships):实体之间如何连接

例:订单→用户、账单→合同、商品→类目

关键点:指标定义要和维度分组解耦。否则它很快就退化成“固定粒度 view”,下游还是会在不同场景里算出不一致的结果。

示例:用 YAML / DDL 定义“非累加指标”(Non-additive / Semi-additive) 语义层最“值钱”的内容之一,就是非累加指标。原因很简单:这类指标在不同粒度下二次聚合很容易错。

常见例子:

distinct_customer_count:去重客户数(聚合后再 sum 基本就错了)

revenue_per_customer:人均收入 = SUM(revenue) / COUNT(DISTINCT customer_id)(比率在不同粒度下要重算)

conversion_rate:转化率 = converted_users / eligible_users(分子分母必须在同一粒度计算)

示例 A:Databricks Metric View(YAML)——“比率 + distinct” Databricks 的 metric view 用 YAML 把 measures 和 dimensions 分开定义,引擎在运行时生成正确的聚合计算(查询时用 MEASURE() 显式引用)。下面是一个示意(字段名按你的模型调整即可):

metrics/revenue_metrics.yaml

version: 1 metric_view: name: mv_revenue description: "Revenue metrics with non-additive measures"

source: # 可以是表、视图或 SQL(文档中说明 source 可为 view/table/query) table: main.analytics.fact_orders

dimensions: - name: order_date expr: order_date type: date - name: region expr: region type: string

measures: - name: total_revenue expr: revenue_amount agg: sum description: "Sum of revenue"

- name: distinct_customers
  expr: customer_id
  agg: count_distinct
  description: "Distinct customers"

# 非累加:人均收入(比率)
- name: revenue_per_customer
  expr: total_revenue / distinct_customers
  agg: ratio
  description: "SUM(revenue) / COUNT(DISTINCT customer)"

一键获取完整项目代码

查询时(示意):

SELECT region, MEASURE(revenue_per_customer)AS rev_per_cust FROM main.analytics.mv_revenue GROUPBY region; 这套写法的价值在于:下游换了 group by 粒度,仍然是在“当前粒度”重算比率,而不是对已经算好的比率再做聚合。

(Databricks 文档也强调了 metric view 会把 measure 定义与维度分组分离,用来处理 ratios、distinct counts 这类复杂度量。)

示例 B:dbt Semantic Layer / MetricFlow(YAML)——“可加 vs 非可加” dbt Semantic Layer(MetricFlow)里,一般先定义 semantic_model(entities、dimensions、measures),再定义 metrics。下面示意一个“订单事实表”的语义模型,并定义一个非累加比率指标:

models/semantic/order_semantic.yml

semantic_models:

  • name: orders_semantic model: ref('fct_orders') description: "Order fact semantic model"

    entities:

    • name: order type: primary expr: order_id
    • name: customer type: foreign expr: customer_id

    dimensions:

    • name: order_date type: time type_params: time_granularity: day
    • name: region type: categorical

    measures:

    • name: revenue agg: sum expr: revenue_amount

    • name: customers agg: count_distinct expr: customer_id

metrics:

  • name: revenue_per_customer description: "SUM(revenue) / COUNT(DISTINCT customer)" type: ratio numerator: measure: revenue denominator: measure: customers 一键获取完整项目代码

两个点值得注意:

customers 用 count_distinct 定义成 measure,避免下游对已聚合结果再聚合

revenue_per_customer 用 type: ratio 明确它是比率指标,执行时按分子/分母在当前粒度计算

示例 C:Snowflake Semantic View(DDL)——“把语义作为 schema-level object” Snowflake 的 semantic view 是数据库里的对象,DDL 会声明 tables、relationships、dimensions/metrics 等。下面是极简示意(语法细节以官方文档为准):

CREATE OR REPLACE SEMANTIC VIEW SALES_SEMANTIC_VIEW tables ( ORDERS primary key (ORDER_ID), CUSTOMERS primary key (CUSTOMER_ID) ) relationships ( ORDERS_TO_CUSTOMERS as ORDERS(CUSTOMER_ID) references CUSTOMERS(CUSTOMER_ID) ) dimensions ( ORDERS.ORDER_DATE as order_date, CUSTOMERS.REGION as region ) metrics ( -- 可加:收入 ORDERS.TOTAL_REVENUE as SUM(ORDERS.REVENUE_AMOUNT),

-- 非累加:去重客户数
ORDERS.DISTINCT_CUSTOMERS as COUNT(DISTINCT ORDERS.CUSTOMER_ID),

-- 非累加:人均收入(比率)
ORDERS.REVENUE_PER_CUSTOMER as
  (SUM(ORDERS.REVENUE_AMOUNT) / NULLIF(COUNT(DISTINCT ORDERS.CUSTOMER_ID), 0))
  WITH SYNONYMS = ('arpc', 'revenue per customer')

); 一键获取完整项目代码 sql

这种模式的优势主要体现在两点:

语义对象和数据库治理/权限/审计在同一个控制面

同义词(synonyms)这类元数据对 NLQ/Agent 的命中稳定性很有帮助

4.2 业务规则内建:过滤、口径、时间窗 语义定义通常会携带业务规则,比如:

排除测试账号

只统计已完成订单

退款/冲正怎么处理

时间窗:滚动 7 天、自然月、财务季度

这些规则如果散落在报表和脚本里,口径漂移几乎是必然的。把规则放进语义对象本身,复用成本会低很多。

4.3 元数据与语义增强:让“人”和“AI”都能读懂 更偏 AI-ready 的 Semantic View 往往会带这些信息:

指标/维度描述(description)

口径说明(business definition)

owner / steward

认证状态(certified / experimental)

同义词(synonyms)、缩写(acronyms)

展示格式(currency、percent、precision)

示例问法/示例查询(可选)

这些元数据会直接影响:LLM/Agent 能不能稳定选到正确对象。

4.4 治理能力:权限、审计、血缘、影响分析 语义对象进了生产环境,治理能力往往决定它能走多远:

和 catalog 集成(统一资产目录)

行/列级权限、脱敏策略继承

访问审计(谁在何时用哪个指标)

血缘(指标来自哪些表/字段/模型)

影响分析(改一个指标会影响哪些报表/应用/Agent)

4.5 性能能力:物化、增量、缓存、路由 如果语义层只做逻辑抽象,落地后很容易被吐槽“慢”。比较成熟的实现通常会提供:

常用聚合结果缓存

声明式物化(materialization)

增量更新(incremental refresh)

查询重写(query rewriting)与路由

价值在于:把性能优化从“每个报表单独调优”变成“平台级共享优化”。

4.6 多消费面:SQL / API / BI / Agent Semantic View 的消费面不止 BI:

SQL(分析师、Notebook)

JDBC/ODBC(第三方工具)

REST/GraphQL(数据应用、指标服务)

NLQ(自然语言查询)

Agent 工具调用(function calling / tool use)

  1. 架构:Semantic View 在 AI + 数据平台中的位置 5.1 逻辑分层 一个常见、也比较好沟通的参考分层(从下到上):

Storage / Lakehouse / Warehouse:原始表、明细事实表、维表

Transform / Modeling:数据建模层(星型/雪花)、数据质量、dbt 等

Semantic View(语义视图层):指标/维度/关系/规则/元数据/治理

Serving / Consumption:BI、Notebook、数据应用 API、NLQ、Agent

语义层一般在建模之上,同时尽量靠近平台的治理与目录体系。

5.2 三种主流落地模式(实现路径) 模式 A:平台内原生对象(Platform-native / In-Database) 语义对象作为数据库/平台的一级对象

优点:治理继承强、性能优化空间大、统一入口

挑战:跨平台迁移成本更高,能力边界受平台约束

模式 B:目录/元数据驱动(Catalog-native) 语义定义存储在 catalog(或类似元数据服务)

查询时由引擎做 query rewrite / 生成执行计划

优点:语义与治理紧耦合,天然支持多消费面

挑战:对 catalog 能力和执行引擎的协同要求更高

模式 C:Headless 语义服务(API-first) 语义层是独立服务,对外暴露统一 API 给 BI/应用

优点:工具无关、多平台复用

挑战:治理策略与底层平台的继承需要额外工程;性能优化复杂度也更高

很多团队会混着用:核心指标用平台原生承载,长尾或实验指标用服务化方式接住。

  1. 一个工程化的语义模型:最小完备要素(MVP) 从 0 开始做语义层,建议先把“最小闭环”跑通。别一上来想覆盖全域,最后容易变成“做了很多定义,但谁也不敢用”。

6.1 实体与关系(Entities & Relationships) 核心事实实体(Fact):订单、账单、事件日志、订阅等

维度实体(Dimension):用户、产品、组织、渠道、时间

关系:外键/业务键/多对多桥表

关系声明的价值很直接:查询生成器/优化器/Agent 不需要靠猜来拼 join。

6.2 指标(Metrics) 一个能长期维护的指标定义,通常会包含:

名称(canonical name)

业务释义(business definition)

计算表达式(aggregation + expression)

粒度(grain):按订单、按用户、按合同等

可切片维度范围(可选):哪些维度组合在治理/性能上更合适

内建过滤(filters):口径规则

时间语义(time):归属日期字段、窗口

格式化(format):货币、百分比、小数位

6.3 维度(Dimensions) 名称与描述

类型:枚举/层级/时间

层级(Hierarchy):类目→子类→SKU、国家→省→市

同义词/别名:服务自然语言、也服务跨团队命名

6.4 语义元数据(Semantic Metadata) owner / domain

certification(生产可用/实验/弃用)

lineage

tags

示例

6.5 权限与策略(Governance) MVP 阶段至少要跑通:

基于角色/用户的访问控制

行/列级策略继承(至少和底层表一致)

审计日志

  1. Semantic View 的查询方式:从“写 SQL”到“声明式语义查询” 不同实现会提供不同的 query 形态,但共性差不多:

调用方选择 metrics + dimensions

平台负责:

Join 路径解析

过滤规则注入

正确聚合(尤其是 ratio、distinct、semi-additive 指标)

查询重写与加速

7.1 为什么比普通 view 更安全:不可重聚合指标(Non-additive) 典型坑:

distinct_count 很难安全二次聚合

比率类指标(如 sum(revenue)/count(distinct user))在不同粒度下需要重算

语义层把这些东西定义成“度量对象”,执行时由引擎生成正确计算计划,下游只负责选维度与过滤条件。

7.2 一个通用的“语义查询”抽象 可以把语义查询抽象成:

SELECT , FROM <semantic_view> WHERE ...

区别主要有两点:

<semantic_view> 不是明细表

不是简单字段,而是可执行的指标定义

  1. 面向 AI/Agent:让语义层进入 RAG + Tool 的链路 在 AI + 数据平台里,Semantic View 不只是建模层,它也像一个“结构化业务知识库”。

8.1 语义层如何进入 Agent 的工作流 更稳的问数链路通常是:

意图理解:识别问题里的业务概念(指标、维度、时间范围)

语义检索:从语义层检索候选指标/维度(同义词、描述、认证状态)

权限校验:确认调用者能访问哪些对象

生成语义查询:组合 metrics + dimensions + filters

执行与解释:返回结果,同时引用语义定义说明口径

好处很直观:join、口径、权限这些“最容易出事”的环节由语义对象兜底,模型临场发挥的空间小很多。

8.2 语义层对 AI 额外有价值的元数据 更贴近 AI 使用习惯的字段通常包括:

synonyms:同义词/别名/常见问法

glossary_terms:业务术语词典

guardrails:禁止/限制维度组合(例如不能下钻到个人隐私粒度)

explain_template:解释模板(“口径为…,包含…,不包含…”)

examples:问法→语义查询示例

一句话:Semantic View 既提供“业务语义知识”,也提供“可执行的数据计算接口”。

  1. 落地经验:怎么把 Semantic View 做成可持续资产 9.1 从少量高价值指标起步 更常见、也更稳的推进方式是:

先选 5–20 个公司级核心指标(财务、增长、留存、转化)

每个指标配套 5–10 个核心维度(时间、地区、产品、渠道、客户分层)

先让这批指标同时跑通:BI + API + NLQ/Agent

再逐步扩展长尾指标

9.2 Core / Edge 分层 一个比较健康的形态是:

Core(核心层):认证指标、标准维度、严格变更流程、影响分析

Edge(边缘层):团队实验指标、临时口径、Agent 专用同义词

Edge 里跑出来的内容,评审通过后再晋升到 Core;Core 的每次变更则尽量保持可追溯。

9.3 Semantics as Code 把语义定义当作代码来管,维护成本会低很多:

PR 评审(业务 + 数据一起看)

自动化测试(指标一致性、数据质量、性能回归)

环境分层(dev/staging/prod)

变更公告与影响分析

9.4 指标测试(Metric Tests)与数据质量 语义层落地时常见“背锅点”是数据质量:指标口径写得再漂亮,底层数据一波动,结果照样不可信。

核心指标一般会配几类测试:

和财务/对账系统的基础一致性测试

异常检测(环比/同比阈值、结构变化)

关键维度覆盖率测试(渠道、地区缺失)

  1. 常见坑与反模式 把语义层当成“另一个报表层”,指标仍散落在报表里

只做指标,不做关系与维度治理,Agent 还是得猜 join

缺少认证/owner/变更流程,语义对象很快腐化

忽略非可加指标(distinct、ratio),多粒度下算错

只服务 BI,不服务数据应用与 AI,价值被锁死在一个场景

性能策略全靠下游调优,语义层容易被贴上“慢且没用”的标签

  1. 云器(Yunqi)的 Semantic View 能力与业务实践 11.1 云器语义层的双形态:Lakehouse 原生 + Agent 语义层 云器目前有两套互补的语义层实现:

云器 Lakehouse 语义层(LH 语义层)

原生支持 SQL:可以直接用 SQL 定义与查询语义层对象

通过 MCP 支持 YAML:便于和业界常见的 YAML 语义视图表达对齐(材料中提到“通过 MCP 使用 snowflake yaml 表示 semantic view”)

同时支持 SQL 与 API 查询

DataGPT / Analysis Agent 语义层

最初是为“兼容多种数据源”设计,因此做成独立语义层

提供 AI 辅助生成、管理界面、与索引结合等能力

更偏“智能问数/分析助手”的端到端体验

可以这么理解:

Lakehouse 语义层更像平台级语义资产层(platform-native semantics)

Analysis Agent 语义层更像面向交互与分析链路的语义工作台(agent-native semantics)

11.2 自然语言问数准确率 95%+:云器的实践经验 引入Semantic View的背景:

语义层在自然语言问数场景的核心价值之一,是提升准确率

走语义层问数时,LLM 往往不直接写 SQL,而是“指标/维度/过滤匹配 → 语义层拼接 → SQL”,因此幻觉更低

至于“95%+”,对外表达时建议把评测口径一起讲清楚:评测集是什么、业务域是什么、题型分布如何、是否包含歧义问法等。否则数字很容易被误解。

(1)把 Text-to-SQL 变成 Text-to-Semantics-to-SQL 传统链路:Schema + 知识 + LLM → SQL

语义层链路:指标匹配 + 过滤条件 + 维度选择 + 语义层拼接 → SQL

直观效果:生成空间从“任意 SQL”收敛成“语义组件组合”,每个组件都有明确的定义和边界。

(2)用索引解决歧义:指标/维度/列值的召回 一个典型歧义问题:

“给我看看张三去年七夕和情人节的相关交易额” —— 张三是谁?客户?销售?库管?负责人?

云器的实践做法包括:

指标名称/描述的入库与召回:常用向量索引(并处理长短匹配)

列值召回:常用标量索引(并判断是否需要索引)

知识召回:常用向量索引

材料里也给了 Lakehouse 的索引最佳实践:

yunqi.tech/documents/L…

语义层 + 索引 这套组合的核心作用,是在问数早期把概念先对齐,尽量别让模型在歧义空间里碰运气。

(3)Dynamic Table / 表外索引:降低对原表改造成本 材料中提到一个用户案例:

用户用语义层问数

通过 dynamic table 在数据表外维护标量索引

现实意义很大:业务表不一定允许频繁加列/加索引,而表外索引通常能更快迭代。

(4)把高频问法沉淀为语义资产 准确率要长期跑稳,还是得靠资产化。高频问题往往会沉淀成:

认证指标(certified metrics)

标准维度(standard dimensions)

内建口径规则(filters)

同义词与解释模板(synonyms / explain template)

这也呼应前文的转变:从“对数”到“对语义资产”。

  1. 参考实现(不局限于某产品):从“能力点”映射到“实现方式” 下面按能力点概括几条常见实现路径,方便选型/自研时对照。

12.1 语义对象存储 In-DB 对象:语义定义与数据库对象同生命周期

Catalog 对象:语义定义注册在统一目录(含 YAML/JSON/DSL)

Git-as-source:语义定义以代码形式存储,平台负责发布与注册

12.2 查询接口 SQL 扩展(特殊函数/语法)

语义 API(REST/GraphQL)

BI 连接器(JDBC/ODBC + 元数据暴露)

NLQ/Agent 工具接口(tool calling)

12.3 治理集成 与权限系统统一(RBAC/ABAC)

行/列级策略继承

审计:语义对象级访问日志

血缘:从指标追溯到表/字段/作业

12.4 性能策略 结果缓存(query result cache)

声明式预聚合(pre-aggregation)

增量物化(incremental materialization)

查询重写(rewrite)与 cost-based routing

  1. 总结:Semantic View 是 AI 数据产品化的“中间件” 在 AI + 数据平台语境里,Semantic View 的价值可以概括成一句话:

把组织对业务的理解,变成机器可执行、可治理、可复用的“真相接口”。

没有语义层时:

指标口径在工具间漂移

LLM/Agent 需要猜表、猜字段、猜 join、猜过滤

数据治理很难扩展到所有消费面

语义层成熟后:

指标定义一次,跨 BI / 应用 / AI 复用

口径、权限、审计、血缘与语义绑定

AI 更像在“调用语义接口”,而不是临场拼 SQL