
它不做 BI 看板,它做 BI 后面那一层——让指标、维度、权限在代码里定义一次,SQL/REST/GraphQL/API 全部用同一份定义喂给下游一切。
写在前面
如果你做过 BI 选型,大概率踩过这个坑:
- 业务方说 ” 算一下 GMV”,Tableau 算了一遍,Metabase 算了一遍,dbt 模型又算了一遍,三个数字对不上——因为 Join 路径、过滤条件、汇率口径都不一致。
- 你想给 AI Agent 喂 ” 过去 30 天美国区客单价 ”,结果 Agent 不知道从哪个表 Join,也不知道哪些字段是 ” 已付费订单 ”。
- 数据团队加了字段、改了语义,业务方还在用旧定义,没人通知、没人审核。
这些问题的共同根源是:缺一层 ” 语义层 ”(Semantic Layer)——把指标的 ” 是什么、怎么算、谁能看 ” 从下游工具里抽象出来,集中在一处定义,所有下游共享同一份。
Cube.js(cube-js/cube)做这件事做了 8 年。它把自己定位成 “open-source semantic layer for AI, BI, embedded analytics”——20,558 stars、Rust 主写、Apache-2.0 + MIT 双协议、v1.7.16 还在 2026-07-31 持续更新。
不管你最后用不用它,这篇文章值得你花 10 分钟。因为 ” 语义层 ” 这件事,是 BI 抽象的下一步,是 AI Agent 真正 ” 能看懂业务 ” 的必经之路。
一、它解决什么问题
一句话:Cube.js 让你 在代码里定义一次业务指标,然后通过 SQL / REST / GraphQL API 暴露给 BI 工具、AI Agent、内部应用、嵌入式分析——所有下游用同一份定义,不再各算各的。
基本信息
| 维度 | 数值 |
|---|---|
| 仓库 | cube-js/cube |
| 定位 | Open-source semantic layer for AI, BI and embedded analytics |
| Stars | 20,558 |
| Forks | 2,103 |
| 协议 | Apache-2.0(默认)+ MIT(双协议,按文件头可选) |
| 主语言 | Rust 53% + TypeScript 30% + MDX 12% |
| 最新版 | v1.7.16(2026-07-31) |
| 最近 commit | 2026-08-06(5 天前还在修 GCS OOM) |
| Open Issues | 1,069 |
| Watchers | 154 |
| 官网 | https://cube.dev |
| 文档 | https://docs.cube.dev |
关键观察:1,069 open issues 看起来吓人,但 Cube.js 商业产品(Cube Cloud)跑的就是这个内核,活跃度真实可信。
二、核心能力:定义一次,全场景用
Cube.js 的核心能力用一句话说:“ 代码即语义层 ”——你写一个 schema/ 目录,里面用 JS/TS 定义 cubes(每个 cube = 一个业务实体),里面声明 dimensions(维度)、measures(指标)、joins(关联)、access policies(权限)。
1. 三种 API 同时输出
同一份 schema 定义 ↓
├─ SQL API:直接给 BI 工具(Superset / Metabase / Tableau)├─ REST API:给前端 / 移动端 / GraphQL BFF
└─ GraphQL API:给 AI Agent / 内部应用
这就是 ” 语义层 ” 的核心价值——不用为每个工具重新实现一遍 Join 逻辑。
2. 内置缓存引擎(Cube Store)
Cube.js 配套了一个 Rust 写的列式缓存引擎 Cube Store,把 ” 已计算过的指标 ” 缓存起来,提供亚秒级查询响应 + 高并发。架构图:
SQL API / REST / GraphQL
↓
Query Orchestrator(Rust)↓
┌────┴────┐
↓ ↓
Source DB Cube Store(缓存)(PG/Snowflake/BigQuery)
这种 ” 查询结果缓存 ” 是大多数 BI 工具做不到的——Metabase 和 Superset 都没有这个层。
3. 完整 SQL 数据源
文档明确列出支持的全部 SQL 数据源:
- 云数仓:Snowflake、Databricks、BigQuery、Amazon Redshift
- 查询引擎:Presto、Amazon Athena、Trino
- 应用数据库:PostgreSQL、MySQL、ClickHouse、DuckDB
- 文件:通过 DuckDB / Spark 间接支持
4. AI 原生集成(2026 新重点)
README 直接强调 “agentic-analytics” 是头号 feature。Cube 给 AI Agent 提供了:
- MCP Server(Model Context Protocol)—— 让 Claude / Cursor / OpenClaw 直接调指标
- Skills(跟 OpenClaw Skills 一脉相承)—— 把 ” 算 GMV 的方法 ” 封装成 Agent 可加载的指令
- Conversational Analytics—— 自然语言问 ” 上个月华东区 GMV”,Cube 翻译成 SQL 执行
这跟飞熊 4 月发的 LangFlow 调研(237)”15 万星 MCP server” 是同一波浪潮——AI Agent 倒逼 BI 升级。
三、差异化能力:双产品架构(Cube Core vs Cube)
这是 Cube.js 区别于其他开源 BI 项目的 最关键设计 —— 核心引擎 + 商业产品分层:
| 维度 | Cube Core(开源) | Cube(商业) |
|---|---|---|
| 协议 | Apache-2.0 + MIT | 商业 SaaS(Cube Cloud) |
| 语义层 | ✅ 完整 | ✅ 完全兼容 Cube Core |
| 数据建模 | ✅ JS/TS 定义 | ✅ 同上 |
| SQL/REST/GraphQL API | ✅ | ✅ |
| BI 看板 | ❌ Headless,无 UI | ✅ Analytics Chat + Workbooks + Dashboards |
| 嵌入式分析 | ❌ 自己接 | ✅ Embedded analytics surfaces |
| 多租户 | ❌ | ✅ |
| RBAC | ❌ | ✅ |
| 托管部署 | ❌ 自己 Docker | ✅ Cube Cloud 一键 |
| Tableau / Power BI / Excel 集成 | ❌ | ✅ |
官方原话(README):
“Use Cube Core when you want to own the stack — a custom BI experience, deeply integrated embedded analytics, or AI agents that need a governed semantic foundation. Use Cube when you want a managed, full-featured BI platform out of the box.”
底层完全兼容——你在 Cube Core 里写的 schema,迁到 Cube Cloud 上不用改一行;反过来也一样。这意味着:
- 从 Cube Core 起步 → 业务跑通后平滑升级到 Cube Cloud, 零迁移成本
- 不会被绑定 → 不想用 Cube Cloud?直接 Docker Compose 跑 Core,永远免费
这是 ” 开源 + 商业 ” 分层能跑通的最经典的样本。
四、编辑器与工具能力
| 能力 | 实现方式 |
|---|---|
| 数据建模 | schema/ 目录下 JS/TS 文件,每个 cube 一个文件 |
| Join 类型 | one_to_one / one_to_many / many_to_one / many_to_many |
| 指标类型 | count / sum / avg / countDistinct / runningTotal / timeSeries |
| 权限控制 | accessPolicy 字段(角色、行级、字段级) |
| 预聚合 | preAggregations 字段(cube 级 + rollup),自动物化到 Cube Store |
| 缓存策略 | refreshKey / every / 等多种失效粒度 |
| 多数据源 | 单 schema 可跨多个底层 DB(联邦查询) |
| Playground | localhost:4000 自带 Schema Playground,实时看生成的 SQL |
| REST 文档 | 自动生成 OpenAPI 3.0 文档 |
| CLI | npx cubejs-cli create 一键脚手架 |
一个 cube 的最小例子
// schema/Orders.js
cube(`Orders`, {
sql: `SELECT * FROM orders`,
measures: {
gmv: {
sql: `amount`,
type: `sum`,
title: `GMV`,
},
orderCount: {type: `count`,},
},
dimensions: {status: { sql: `status`, type: `string`},
createdAt: {sql: `created_at`, type: `time`},
region: {sql: `region`, type: `string`},
},
joins: {
Users: {sql: `${CUBE}.user_id = ${Users}.id`,
relationship: `belongsTo`,
},
},
preAggregations: {
main: {measures: [gmv, orderCount],
timeDimension: createdAt,
granularity: `day`,
},
},
});
这段代码生成什么?
- Superset / Metabase 能直接连 SQL API 问 “ 每日的 GMV + 订单数 ”
- 前端能直接调 REST API:
GET /orders/gmv?region=cn&timeRange.last=30%20day - AI Agent 能调 MCP 工具
cube.get_measure({measure: 'Orders.gmv', filters: [...]}) - 全部用同一份定义,指标永远一致
五、对比:语义层赛道的 4 个玩家
| 项目 | 定位 | 协议 | Stars | 一句话差异 |
|---|---|---|---|---|
| Cube.js | 开源语义层 | Apache-2.0 + MIT | 20,558 | 全场景 SQL/REST/GraphQL + 内置缓存 + AI 集成 + 商业化路径清晰 |
| dbt-core | 数据转换层(ETL/ELT) | Apache-2.0 | 10K+ | 只做 SQL 转换,不暴露 API 给 BI 工具,跟 Cube 互补 |
| LookML | 语义层(Looker) | 商业 | — | 只能给 Looker 用,开源生态为零 |
| Metabase | BI 工具 | AGPL | 48K | 做 BI 看板 + 简单建模,无统一 API 暴露 |
关键判断
Cube.js vs dbt 不是替代关系,是上下游关系:
- dbt 负责 ” 数据清洗 + 宽表生成 ”(跑 SQL 转换)
- Cube.js 负责 ” 指标定义 + 多 API 暴露 ”(包装成可消费的接口)
- 一个典型现代数据栈:dbt → Cube → BI 工具 / AI Agent
Cube.js vs Metabase / Superset:
- Metabase / Superset 是 消费侧(做 BI 看板)
- Cube.js 是 供给侧(定义指标 + 提供 API)
- 如果你已经有 BI 工具但缺统一指标层 → Cube.js
- 如果你只有 BI 工具需求 → Metabase / Superset 即可
适合谁
| 场景 | 选 Cube.js? |
|---|---|
| 内部 BI 工具但需要统一指标口径 | ✅ 强烈推荐 |
| 给客户做嵌入式 BI / SaaS 看板 | ✅ 强烈推荐 |
| AI Agent 需要 ” 算业务指标 ” 的工具 | ✅ 强烈推荐 |
| 数据团队 + 业务团队协同(防止口径不一致) | ✅ 强烈推荐 |
| 只想快速看几个图表 | ❌ 直接 Superset / Metabase |
| 不需要 API 暴露、只内部用 SQL 查询 | ❌ dbt + BI 工具足够 |
六、实战:3 步跑通一个最小 Cube.js
Step 1:跑 Docker
mkdir cube-test && cd cube-test
docker run -p 4000:4000 \
-p 15432:15432 \
-v ${PWD}:/cube/conf \
-e CUBEJS_DEV_MODE=true \
cubejs/cube
浏览器打开 http://localhost:4000,进入 Playground。
Step 2:连 Postgres 做 Schema
新建 schema/Orders.js:
cube(`Orders`, {
sql: `SELECT * FROM public.orders`,
measures: {gmv: { sql: `amount`, type: `sum`},
count: {type: `count`},
},
dimensions: {status: { sql: `status`, type: `string`},
createdAt: {sql: `created_at`, type: `time`},
},
});
Playground 里立刻能预览生成的 SQL:
SELECT
COUNT(orders.id) AS orders_count,
SUM(orders.amount) AS orders_gmv
FROM public.orders AS orders
Step 3:调 API
# REST API
curl "http://localhost:4000/cubejs-api/v1/load?query={\"measures\": [\"Orders.gmv\", \"Orders.count\"],
\"timeDimensions\": [{
\"dimension\": \"Orders.createdAt\",
\"dateRange\": \"last 30 days\"
}]
}"
# 返回 JSON,前端 / AI Agent 都能直接消费
3 步 = 5 分钟,直接跑通 ” 从定义到 API” 的全链路。
七、风险与坑
- Rust 编译门槛:本地跑需要 Rust 工具链(Docker 镜像已内置,但自己改源码要装 Rust)。对习惯 NodeJS 全栈的团队有学习成本。
- 1,069 open issues:开源项目体量大,issue 摊薄很严重。简单问题能在 Discord/Slack 社区秒答,复杂问题需要排队。
- 预聚合不能滥用:每个
preAggregations都是 Cube Store 的一份物化。百亿级数据 + 几百个预聚合 = 存储爆炸。要按业务温度分层(热数据预聚合 + 冷数据走源查询)。 - 没有内置 BI 看板:Cube Core 是 headless,看板要自己接或用 Cube Cloud。对 ” 开箱即用 ” 用户来说有摩擦。
- 生态集中在 BI 老炮:上游 BI 工具集成 Tableau / Power BI / Excel 等老牌工具做得很扎实,但跟 Superset / Metabase 这种开源 BI 集成略松。
八、总结
3 个 ” 最值得装 ” 的理由
- “ 定义一次,全场景用 ” 是必答题——如果你同时跑 BI 工具 + AI Agent + 嵌入式分析,缺这一层迟早会撞上 ” 指标口径不一致 ” 的墙
- AI Agent 时代的中间件——MCP Server + Skills 让你的 Agent 真正理解业务指标,不是模糊文本匹配
- 商业化路径清晰 ——Cube Core 跑通后想托管?直接迁移 Cube Cloud, 零 schema 改动
一句话建议
先用 Docker 跑 5 分钟,再判断要不要上生产。语义层不是 BI 工具的附属品,是 AI 时代的必备基础设施。