OSI 字段映射:所有语义层,同一份规范
一份逐字段的对照参考:MetricFlow、Cube、LookML、AtScale、Snowflake Semantic Views、GoodData、Power BI 与 Databricks Metric Views 如何翻译到 Open Semantic Interchange schema——现代语义层的厂商中立传输格式。
1 · 数据集层(表与数据源)
各家产品如何命名支撑某个语义对象的物理表,以及 OSI 如何把这些名字统一到 dataset.name + dataset.source 之下。
dataset.namesemantic_model.namecubes[].nameview: view_nameTABLES (alias AS …)dataset.idtable 'Name'CREATE METRIC VIEW namedataset.sourceref() or source YAMLcubes[].sql_tabledataset.sourcesql_table_name / derived_tableTABLES (alias AS db.schema.table)dataset mappingpartition.source (M / SQL)source: catalog.schema.tabledataset.primary_keyentities[] with type: primarydimensions[] with primary_key: truelevel_attributes[].key_columnsdimension: + primary_key: yesPRIMARY KEY (col)attribute labelscolumn.isKey: truedataset.descriptionsemantic_model.descriptionCOMMENT = '…'dataset.descriptiontable.descriptionCOMMENT '…'语义对象的叫法在各家工具里差别极大——cube、view、semantic_model,或者一个裸 SQL 别名——但最终每家都指向同一张物理表。 OSI 把它收敛成两个字段:dataset.name 是指标引用的逻辑标识,dataset.source 则是下游消费方真正打到的那张表。
2 · 维度层(字段与属性)
字段级元数据:名称、表达式、标签、描述,以及大多数产品缺失的两样东西——时间标记与 AI 上下文槽位。
fields[].namedimensions[].namedimensions[].namedimension.unique_namedimension: field_nameDIMENSIONS (table.dim AS …)attribute.id + label.idcolumn.namedimensions[].namefields[].expression.dialects[]dimensions[].expr (single dialect)dimensions[].sql (single dialect)level_attribute.columndimension: { sql: ${TABLE}.col }DIMENSIONS (… AS sql_expr)label.source_columncolumn.sourceColumn or DAX calc columndimensions[].expr (SQL)fields[].dimension.is_timetype: time + time_granularitytype: timetype: TIMEdimension_group + timeframesattribute onlydataType: dateTime + mark-as-date-tablefields[].labeldimensions[].labeldimensions[].titlelevel_attribute.labeldimension.labellabel.titledimensions[].labelfields[].descriptiondimensions[].descriptiondimensions[].descriptionlevel_attribute.descriptiondimension.descriptionCOMMENT = '…'attribute.descriptioncolumn.descriptiondimensions[].commentfields[].ai_contextWITH SYNONYMS = ('…')column.synonyms (Q&A)fields[].custom_extensionsdimensions[].type_paramsdimensions[].metadimension.type / formattags / group_labelWITH TAG (…)label.value_typeannotations[]OSI 的 fields[].expression.dialects[] 是唯一能原生容纳多方言 SQL 的地方—— MetricFlow、Cube 和 LookML 都默认只有一种方言。而fields[].dimension.is_time 是消费方唯一能依赖的跨产品时间维度标记: 不必再分别去嗅 LookML 的 dimension_group、MetricFlow 的 type: time 和 Snowflake 的裸 SQL,用三种方式去猜同一件事。
3 · 指标层(度量与聚合)
各家产品如何描述聚合、过滤条件与派生指标——以及 OSI 如何把聚合从 SQL 字符串里拎出来,变成一等字段。
metrics[].namemeasures[].namemeasures[].namemetric.unique_namemeasure: field_nameMETRICS (table.metric AS …)metric.idmeasure.namemeasures[].namemetrics[].aggregationmeasures[].agg (sum, count_distinct…)measures[].type (sum, avg…)metric.aggregation_typemeasure: { type: sum }SUM(...))SUM(...))SUM(...))metrics[].expressionmeasures[].exprmeasures[].sqlmetric.expressionmeasure: { sql: ${TABLE}.col }METRICS (… AS sql_expr)metric.maqlmeasure.expression (DAX)measures[].expr (SQL)metrics[].descriptionmeasures[].descriptionmeasures[].descriptionmetric.descriptionmeasure.descriptionCOMMENT = '…'metric.descriptionmeasure.descriptionmeasures[].commentmetrics[].filtermeasures[].filtermeasures[].filters[]metric.filtermeasure: { filters: [...] }CALCULATE(..., filter)WHERE in measure exprmetrics[].labelmeasures[].labelmeasures[].titlemetric.labelmeasure.labelmetric.titlemeasures[].labelmetrics: block (ratio, derived)measures[].sql referencing other measurestype: number, sql: ${m1}/${m2}metric.maql referencing other metricsMEASURE(name) reference in metric viewmetrics[].ai_contextWITH SYNONYMS = ('…')measure.synonyms (Q&A)Snowflake Semantic Views 和 GoodData 把聚合埋在表达式字符串里(AS SUM(...)、SELECT SUM({fact}))。OSI 把它提到 metrics[].aggregation,这样 Agent 和 BI 工具不解析 SQL 也能理解这个运算。 引用其他指标的派生指标,则通过 metrics[].expression 原样保留。
4 · 关系层(Join)
Join 在哪里声明、在哪里只能靠推断。OSI 把它们提升成一等的 relationships[] 块。
relationships[].nameentity.namejoins[].nameRELATIONSHIPS (name AS …)reference declarationrelationship.namejoins[].namefrom_dataset / to_datasetentity.type: foreignjoins[].nametable_a (col) REFERENCES table_bfromTable / toTablejoins[].sourcerelationships[].foreign_keyentities[].exprjoins[].sqljoin: { sql_on: ${a}.fk = ${b}.pk }fromColumn / toColumnjoins[].on (SQL predicate)relationships[].cardinalityjoins[].relationshiprelationship: many_to_onecardinality: manyToOne这是六款产品里最不一致的一层。MetricFlow 和 AtScale 从 entities /level bindings 推导 join;Cube 和 LookML 直接内联声明;Snowflake 和 GoodData 介于两者之间。 OSI 的 relationships[] 块给所有消费方同样的四个字段——name、from_dataset、 to_dataset、foreign_key——外加显式的 cardinality,目前只有 Cube 和 LookML 会声明它。
5 · 时间语义层(粒度)
各家产品如何标记时间维度、如何表达粒度。OSI 的 is_time + granularity 是最小公约数。
fields[].dimension.is_timetype: timetype: timetype: TIMEdimension_group: { type: time }dataType: dateTime + date tablefields[].dimension.granularitytime_granularity: daydimensions[].granularitytimeframes: [date, week, month]DATE_TRUNC(...))DATE_TRUNC(...))LookML 带 timeframes 的 dimension_group 最完整;Snowflake 则把时间完全丢给 SQL。 OSI 把这一层收敛成单个时间字段,带 is_time: true 和一个granularity 值——下游若需要日 / 周 / 月 / 季 / 年,可以基于基础字段加粒度元数据自行生成, 信息不丢,而每个消费方只需判断一个标记。
6 · AI 上下文层(OSI 的差异点)
OSI 在整个生态里领先的一层。目前只有 Snowflake Semantic Views 有原生对应能力。
fields[].ai_contextWITH SYNONYMS = ('…')column.synonyms (Q&A)metrics[].ai_contextWITH SYNONYMS = ('…')measure.synonyms (Q&A)AI_SQL_GENERATION '<instr>'AI_VERIFIED_QUERIES (…)这正是 OSI 被造出来要解决的一层。Snowflake 在 2026 年发布了 WITH SYNONYMS、AI_SQL_GENERATION 与 AI_VERIFIED_QUERIES——至今还没有第二家主流语义层有对应能力。 OSI 把这些提示标准化到每个字段和指标的 ai_context 里,于是读取 OSI 的 Agent 无论源头是 Snowflake、Cube 还是自研 YAML 存储,都能用同一种方式找到同义词、自然语言名称和已验证的示例查询。 当下游工具采纳 OSI 后,这些 AI grounding 元数据会跟着指标一起走——而不是被锁死在某一家厂商的 SQL 方言里。
OSI 为数据团队带来了什么
语义层一旦讲同一种厂商中立的格式,团队就能解锁四类模式——从终端一路到对话界面。
一份指标定义,通吃所有 BI 工具
metrics[].aggregation、fields[] 和 relationships[] 变成厂商中立的契约。同一份营收或留存定义可以同时下发到 Cube、Looker、Metabase 和 Python Notebook,不会悄悄跑偏。转换结果可以在OSI Playground 里校验。把 AI Agent 锚定在业务语义上
ai_context 里。Datus-Chat 和模型层读的是同一份 grounding,所以「ARR」会被解析成年度经常性收入, 而不是某个机场代码。在语义层之间迁移,不用重写
在看板坏掉之前发现 Schema 漂移
dataset.source、relationships[] 或 metrics[].filter 变了。 治理检查是从 CLI 针对这份规范跑的,而不是针对某家厂商的 YAML。 它在整体中的位置见 Datus 功能介绍。常见问题
LookML、Snowflake AI 上下文、Cube 的 join、dimension_group timeframes、双向转换与 MAQL——OSI 各是怎么处理的。
LookML 的指标能用 OSI 表达吗?
可以。每个 LookML measure 都能翻译成一个 OSI metric:type 对应 aggregation,sql 对应 expression,filters 对应 filter。LookML 的派生 measure(type: number 且引用其他字段)映射为 OSI 的派生指标,引用同一文件中其他指标的名称。
OSI 支持 Snowflake Semantic Views 的 WITH SYNONYMS 和 AI_SQL_GENERATION 吗?
支持——而且这正是 OSI 标准化力度最大的一层。维度或指标上的 WITH SYNONYMS 直接映射到 OSI 的 ai_context.synonyms;AI_SQL_GENERATION 与 AI_VERIFIED_QUERIES 都有一等公民的位置,任何厂商的 Agent 都能读到同一份 grounding 提示。
OSI 怎么表示 Cube 的 joins[] 块?
Cube 的 joins[] 条目对应 OSI 的 relationships[] 条目:joins[].sql 对应 foreign_key,joins[].relationship(many_to_one / one_to_many)对应 cardinality,目标 cube 对应 to_dataset。不需要推断,是 1:1 映射。
MetricFlow 里有哪些东西是 OSI 目前表达不了的?
OSI v0.2 覆盖了 MetricFlow 的全部核心结构——semantic_models、measures、dimensions、entities 以及顶层 metrics——但少数高级能力(saved queries、带 grain-to-date 的累计指标、部分转化指标选项)仍在演进中。Datus Playground 会把所有被丢弃的字段显式列出来,不会悄悄丢失。
OSI 有对应 LookML dimension_group timeframes 的东西吗?
OSI 把 LookML 的 dimension_group 收敛成单个时间字段,用 is_time: true 加上一个 granularity 值来表达。下游工具如果需要全部时间粒度(date、week、month、quarter、year),可以基于这个基础字段和粒度元数据自行生成——既保持了 OSI 的厂商中立,也没有丢信息。
能做双向转换吗:MetricFlow → OSI → LookML?
OSI 目前主要是交换与消费格式。从 MetricFlow 或 Cube 正向转成 OSI 支持得很好(见 Datus Playground);反向转回 LookML 或 MetricFlow 原生 YAML 还在社区路线图上。实际做法是:大多数团队把 OSI 当作共享的读取层,编写仍留在各自的源头工具里。
OSI 会支持 GoodData 的 MAQL 表达式吗?
MAQL 通过 metrics[].expression.dialects[] 得以保留:原始 MAQL 字符串存放在自己的方言下,认得 GoodData 的消费方仍可执行它,不认得的消费方则回退到 SQL 方言。OSI 处理任何厂商专有表达式语言用的都是这套机制。
Datus Playground 什么时候支持 MetricFlow 之外的转换?
先做 MetricFlow → OSI,是因为 dbt 语义层 YAML 是最常见的起点。Cube 和 LookML 转换器是路线图上的下一步;也欢迎贡献——Playground 是 Apache 2.0 的,每个转换器都是纯浏览器端的函数。