跳转至

为什么用 Dosi

这一页不预设任何背景,讲清楚两件事:Dosi 解决什么问题,以及它为什么是现在这个样子。 只想先跑起来的话,从安装第一个指标查询教程开始,回头再看这里的"为什么"。

问题:人人都在重新定义"营收"

在多数数据团队里,一个指标的定义同时散落在几十个地方 —— BI 看板、手写 SQL、 电子表格、notebook。每份副本都略有出入:一处过滤了已取消订单,另一处忘了, 第三处 JOIN 了一张表、把总额悄悄翻倍。结果大家都熟悉: 两个都"正确"却对不上的数字,外加一场"该信哪个"的会。

语义模型的解法是把每个指标只定义一次revenue 是什么意思、来自哪张表、 表与表如何关联,作为唯一事实来源。之后所有查询都从这份定义派生,不再各写各的。

OSI 是什么

OSI(Open Semantic Interchange) 是一个开放标准,用来把语义模型写下来: 就是一份普通 YAML 文件,里面写清楚数据集(表)、表与表之间的关系, 以及用普通 SQL 表达式定义的指标。它厂商中立 —— 没有私有格式,也不绑定谁 —— 所以同一份模型,任何支持 OSI 的工具都能读懂。

OSI 描述的是指标是什么。至于怎么把它们变成某个数仓的正确 SQL,OSI 刻意不管。 这正是 Dosi 要补的那块。

Dosi 做什么

Dosi 是一个小巧快速的 Rust 引擎,读一份纯 OSI 模型,把一次指标请求变成对应数仓的 正确 SQL,还可以顺手执行:

flowchart LR
    A["你的 OSI 模型<br/><small>指标只定义一次</small>"] --> B["Dosi"]
    B --> C["正确的 SQL<br/><small>面向你的数仓</small>"]
    C --> D["结果"]

给出一个指标、几个分组维度、一种数仓方言,剩下的 JOIN、聚合,以及那个方言特有的 SQL 写法,都由 Dosi 算出来。同一份模型可以为 DuckDB、Postgres、MySQL、ClickHouse、Snowflake、BigQuery、StarRocks、Trino 等等生成正确 SQL。换数仓改一个参数,指标定义不动。

用法有三种:命令行工具REST/Arrow 服务Python 绑定。 底下是同一个引擎,给出同样的答案。

这些数字凭什么可信

用引擎而不是自己写 SQL,图的是它能挡住那些制造"对不上的数字"的错误:

  • 绝不悄悄重复计数。 当一个指标要 JOIN 不同明细层级的表 —— 也就是那个会把营收 翻倍的经典"扇出" —— Dosi 要么在各自粒度上正确计算,要么停下来报错。 它不会把一个虚高的总数交给你。
  • 时间范围没有歧义。 2024 年 1 月 表示 [2024-01-01, 2025-01-01), 含起始、不含结束,月份边界上的天数不会被算两次。
  • 错误会告诉你怎么修。 指标名写错,换来的不是一段堆栈,而是一条列出最接近选项的 提示。--format json 下每个错误都带稳定错误码和修复建议,自动化工具和 AI Agent 据此就能自我纠正。

这些保证都精确写进了一份规范性契约,见语义契约。 不读也能用 Dosi;想确切知道引擎承诺了什么,再去查也不迟。

适合谁

  • 分析与数据工程师 —— 想要一份指标定义,在每个数仓、每个消费端都保持正确。
  • 正在迁移或多数仓并存的团队 —— 不愿为每个引擎重写一遍指标 SQL。
  • 数据应用与 AI Agent 的开发者 —— 需要一个带结构化、机器可读错误的指标 API, 而不是自由格式的 SQL。

下一步