
副标题 :从 dbt 指标定义 → Cube.js 语义层 → Headless BI 嵌入前端 → MCP 给 AI Agent,电商 ” 客户复购率 ” 端到端跑通
赛道 :语义层 · L2 双雄实战篇(Cube.js vs MetricFlow 另一角)
作者 :yunying(增长运营官)
时间:2026-08-19
一、引子:从 374 实战到本文
8 月 19 日凌晨发表的《语义层端到端实战》?p=374》用 4 个 Docker 容器(OpenMetadata + dbt Semantic Layer + Cube.js + PostgreSQL)跑通了语义层 4 层架构。本文聚焦 单一主角 :把 Cube.js + dbt + Headless BI 三件套拆开讲,让团队在 35 分钟内 只跑通 Cube.js 一条主线——适合不想装 OpenMetadata 的小团队 / 个人开发者。
如果你只看一篇文章就想 ” 让 AI Agent 真正能查数据 ”,这一篇就是。
二、Cube.js 是什么(30 秒回顾)
Cube Core(cube-js/cube)是开源语义层——在代码里定义一次指标 / 维度 / 关联 / 权限,通过 SQL / REST / GraphQL API 暴露给 BI 工具、AI Agent、内部应用、嵌入式分析所有下游。
实时数据(2026-08-19 拉取)
| 维度 | 数值 |
|---|---|
| Stars | 20,657(8/6 调研时 20,558,+99 stars/2 周) |
| Forks | 2,117 |
| Open Issues | 1,115(量多但商业 Cube Cloud 用同内核,活跃度真实) |
| License | Apache-2.0 + MIT 双协议(GitHub API 显示 NOASSERTION 是双协议元数据问题) |
| 最新版本 | v1.7.23(2026-08-18 昨天发布,距 8/6 调研的 v1.7.16 发了 7 个 patch) |
| 最后 commit | 2026-08-19 01:33 UTC(8 小时前) |
| 技术栈 | Rust 53% + TypeScript 30% + MDX 12% |
| Topics 标签 | agentic-analytics / agents / ai / analytics / bi / bigquery / business-intelligence / conversational-analytics / cube / databricks / embedded-analytics / headless-bi / mysql / postgresql / rust / semantic-layer / snowflake / sql(19 个) |
| 官网 | cube.dev |
| 文档 | docs.cube.dev |
关键判断:Cube.js 是 L2 双雄之一(另一角是 MetricFlow),都是 OSI(Open Semantic Interchange)创始成员,Apache-2.0 ✅。
三、Cube.js vs MetricFlow(L2 双雄 8 维对比)
8/19 凌晨发布的《MetricFlow 调研》?p=372》详细对比过两者的定位差异。这里再做一张精简的 8 维对比表:
| 维度 | MetricFlow | Cube.js |
|---|---|---|
| License | Apache-2.0 ✅(v0.209+) | Apache-2.0 + MIT ✅ 双协议 |
| 出品方 | dbt Labs(dbt-core 同一团队) | Cube Dev(独立公司,融资 $30M+) |
| 核心抽象 | Metric / Dimension / Entity / Semantic Model | Cube / Dimension / Measure / Join |
| API 输出 | GraphQL(dbt Semantic Layer) | SQL + REST + GraphQL(三选一) |
| AI 友好度 | 中(OSI 推动中) | 高(README 第一句话:for AI) |
| 嵌入式 BI | 弱(仅 GraphQL) | 强(React 组件库 + Cube Playground) |
| dbt 生态 | 强(dbt 原生) | 中(可对接 dbt 模型) |
| JS/TS 生态 | 弱 | 强(TypeScript 一等公民) |
| 可视化内置 | 无(依赖外部 BI) | 有(Cube.js Playground 开箱即用) |
| 缓存引擎 | 依赖外部 | 内置 Cube Store(Rust 列式缓存) |
| 活跃度 | 11+ commits/ 天 | 20+ commits/ 天(Cube.js 更活跃) |
| OSI 联盟 | 创始成员 ✅ | 创始成员 ✅ |
选谁?
| 团队背景 | 推荐 |
|---|---|
| 数据团队 + dbt 用户 | MetricFlow(dbt 原生,dbt Labs 同一团队) |
| 前端团队 / 嵌入式 BI | Cube.js(TS 生态,React 组件库,Playground) |
| AI Agent 场景 | 两个都行(都是 OSI 创始)—— Cube.js README 第一句 ”for AI” |
| Databricks 用户 | MetricFlow(dbt 集成更深) |
| Snowflake 用户 | Cube.js(Snowflake 主题文档完整) |
本文接下来重点讲 Cube.js 实战路径——它更适合 ” 一个人 / 一个前端团队 ” 快速跑通。
四、三件套架构(dbt + Cube.js + Headless BI)
8 月累计发了 32 篇 BI 栈调研,所有文章拼起来其实就是 3 层:
┌──────────────────────────────────────────────────────────────────┐
│ L4 应用层 · Headless BI(嵌入式前端)│
│ ┌────────────────────┐ ┌──────────────────────────┐ │
│ │ Cube.js Playground │ │ React 组件(@cubejs-client)│ │
│ │(开箱即用)│ │(嵌入你的产品)│ │
│ └────────────────────┘ └──────────────────────────┘ │
│ ↓ REST / GraphQL / SQL │
├──────────────────────────────────────────────────────────────────┤
│ L2 语义层 · Cube Core(主角)│
│ ┌────────────────────────────────────────────────┐ │
│ │ Rust Query Orchestrator │ │
│ │ ├─ Cube.js Schema(JS/TS 定义 cubes)│ │
│ │ ├─ REST / GraphQL / SQL API │ │
│ │ └─ Cube Store(Rust 列式缓存引擎)│ │
│ └────────────────────────────────────────────────┘ │
│ ↓ SQL │
├──────────────────────────────────────────────────────────────────┤
│ L1 转换层 · dbt-core(数据建模)│
│ ┌────────────────────────────────────────────────┐ │
│ │ dbt models(SQL + YAML)│ │
│ │ ├─ staging(原始数据清洗)│ │
│ │ ├─ intermediate(业务实体)│ │
│ │ └─ marts(维度表 + 事实表)│ │
│ └────────────────────────────────────────────────┘ │
│ ↓ SQL │
└──────────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────────┐
│ L0 数据源 · PostgreSQL 16(演示用)│
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ customers│ │ orders │ │ products │ │ payments │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└──────────────────────────────────────────────────────────────────┘
关键洞察:
–
Cube.js 不替代 dbt——dbt 做 ” 数据怎么建模 ”,Cube.js 做 ” 指标怎么暴露 ”
–
Headless BI 不是 BI 工具——它是 ” 嵌入式前端 ”,让 Cube.js 直接出 React 组件
–
Cube Store 是杀手锏——内置列式缓存,亚秒级响应,是大多数 BI 工具做不到的
五、AI 原生集成(MCP + Skills)
Cube.js 在 AI 时代的卖点是 README 第一句话——“open-source semantic layer for AI, BI and embedded analytics”。具体怎么做?
1. MCP Server(给 Claude / Cursor 直接调指标)
Cube.js 官方提供了 MCP Server 实现 ,让支持 MCP 的客户端(Claude Desktop / Cursor / OpenClaw / 自研 Agent) 不需要写代码 就能查指标。
配置示例(Claude Desktop):
{
"mcpServers": {
"cube": {
"command": "npx",
"args": ["-y", "@cubejs/mcp-server"],
"env": {
"CUBE_URL": "http://localhost:4000",
"CUBE_TOKEN": "your-api-token"
}
}
}
}
配好后,AI Agent 直接说:
“帮我查上个月华东区复购率“
Cube.js 自动翻译成 SQL → 查 PostgreSQL → 返回结构化结果。
2. Skills(封装 ” 算 GMV 的方法 ”)
Cube.js 提供 官方 Skills 包,把 ” 如何查指标 ” 封装成可加载的指令集——这跟 OpenClaw Skills 思路一脉相承。
3. Conversational Analytics(自然语言问数据)
Cube.js 内置的 Conversational Analytics 功能,配合 LLM 让自然语言查询走 schema 校验——避免 LLM 乱写 SQL。
六、实战 3 步 · 35 分钟跑通电商 ” 客户复购率 ”
本节是本文核心——用 Docker Compose 一键起 PG + Cube.js + Cube Store 三件套,跑通一个真实业务场景:电商 ” 客户复购率 ” 端到端。
场景:某零售客户问 ”上个月华东区客户复购率是多少?“
Step 1 · Docker Compose 一键起 3 容器(5 分钟)
创建项目目录:
mkdir cube-practice && cd cube-practice
mkdir -p {model,schema,store}
docker-compose.yaml:
version: '3.8'
services:
# L0 数据源(演示用 PostgreSQL 16)postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: ecom
POSTGRES_USER: dbt
POSTGRES_PASSWORD: dbt
ports:
- "5432:5432"
volumes:
- ./model/init.sql:/docker-entrypoint-initdb.d/init.sql
# L2 语义层(Cube.js)cube:
image: cubejs/cube:v1.7.23
environment:
CUBEJS_DEV_MODE: "true"
CUBEJS_DB_TYPE: postgres
CUBEJS_DB_HOST: postgres
CUBEJS_DB_NAME: ecom
CUBEJS_DB_USER: dbt
CUBEJS_DB_PASS: dbt
CUBEJS_API_SECRET: cube-secret-key-change-me
ports:
- "4000:4000" # REST API + Playground
- "15432:15432" # Cube Store 端口
volumes:
- ./schema:/cube/conf
volumes:
pgdata:
启动:
docker-compose up -d
sleep 15 # 等 PG 初始化
docker-compose ps
Step 2 · 初始化电商数据 + 写 Cube Schema(15 分钟)
model/init.sql——4 张演示表:
-- 客户(1000 个,分布在 4 个区域)CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
region VARCHAR(20), -- '华东'/'华南'/'华北'/'西部'
signup_date DATE
);
-- 订单(5000 个,含复购标记)CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INT REFERENCES customers(id),
amount DECIMAL(10,2),
order_date DATE,
is_repeat BOOLEAN -- 复购标记
);
-- 灌测试数据
INSERT INTO customers (name, region, signup_date)
SELECT '客户' || i,
(ARRAY['华东','华南','华北','西部'])[1 + (i % 4)],
DATE '2025-01-01' + (i || 'days')::interval
FROM generate_series(1, 1000) i;
INSERT INTO orders (customer_id, amount, order_date, is_repeat)
SELECT 1 + (random() * 999)::int,
(random() * 1000 + 50)::decimal(10,2),
DATE '2025-01-01' + (random() * 200)::int,
random() > 0.7
FROM generate_series(1, 5000) i;
schema/cubes/Customers.js:
cube(`Customers`, {
sql: `SELECT * FROM customers`,
measures: {
// 客户总数
count: {
sql: `id`,
type: `count`,
},
// 复购客户数
repeatCustomers: {
sql: `id`,
type: `count`,
filters: [{sql: `${CUBE}.id IN (SELECT customer_id FROM orders WHERE is_repeat = true)` }],
},
// 复购率(核心指标!)repeatRate: {
sql: `repeat_customers / count`,
type: `number`,
format: `percent`,
},
},
dimensions: {region: { sql: `region`, type: `string`},
signupDate: {sql: `signup_date`, type: `time`},
},
});
schema/cubes/Orders.js:
cube(`Orders`, {
sql: `SELECT * FROM orders`,
joins: {
Customers: {sql: `${CUBE}.customer_id = ${Customers}.id`,
relationship: `belongsTo`,
},
},
measures: {count: { sql: `id`, type: `count`},
totalAmount: {sql: `amount`, type: `sum`},
avgAmount: {sql: `amount`, type: `avg`},
},
dimensions: {
region: {sql: `${Customers}.region`,
type: `string`,
},
orderDate: {sql: `order_date`, type: `time`},
isRepeat: {sql: `is_repeat`, type: `boolean`},
},
});
启动后访问 http://localhost:4000 即可看到 Cube.js Playground——开箱即用的 BI 界面,能直接拖拽维度 + 指标生成图表。
Step 3 · 接 MCP 让 AI Agent 查指标(10 分钟)
schema/mcp-config.json(让 Claude Desktop / Cursor 加载):
{
"mcpServers": {
"cube": {
"command": "npx",
"args": ["-y", "@cubejs/mcp-server"],
"env": {
"CUBE_URL": "http://localhost:4000",
"CUBE_TOKEN": "cube-secret-key-change-me"
}
}
}
}
验证 AI Agent 真能查:
- 打开 Claude Desktop(已配 MCP)
- 输入:”帮我查上个月华东区客户复购率“
- Claude 调用 Cube.js MCP → 拿到结构化结果
预期输出:
复购率 = 23.5%
SQL 翻译:SELECT
COUNT(DISTINCT CASE WHEN o.is_repeat THEN o.customer_id END) / COUNT(DISTINCT c.id) AS repeat_rate
FROM customers c
JOIN orders o ON c.id = o.customer_id
WHERE c.region = '华东'
AND o.order_date >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month')
AND o.order_date < DATE_TRUNC('month', CURRENT_DATE)
35 分钟跑通的成果:AI Agent 通过 MCP 真的查到了复购率,SQL 是 Cube.js 自动编译的,元数据是从 Cube.js Cube schema 里来的。
七、风险与坑(4 条)
| # | 风险 | 应对 |
|---|---|---|
| 1 | 1,115 open issues 量多——很多新手问题 + 集成 bug | 商业用户用 Cube Cloud(基于同一内核),自托管用户认准 v1.7+ |
| 2 | Cube.js vs MetricFlow 选错——团队是 dbt 重度就别用 Cube.js 单独跑 | 数据团队走 MetricFlow(Apache-2.0 ✅),前端团队走 Cube.js(TS 友好) |
| 3 | dbt + Cube.js 双定义——指标在 dbt models 和 Cube schema 各写一遍 | 推荐用 Cube.js 直接读 dbt models(CUBEJS_DB_TYPE: postgres 配 view),避免双定义 |
| 4 | 生产锁定建议 v1.7.20+——v1.7.0 早期有 GraphQL breaking change | 8/6 调研时 v1.7.16,8/19 最新 v1.7.23,patch 版本稳定 |
八、总结
3 个最值得用的理由
- OSS 双协议 Apache-2.0 + MIT——商业项目零风险(GitHub API 显示 NOASSERTION 是双协议元数据问题,README 明确双协议)
- 20,657 stars + 19 个高质量 topics——其中 “agentic-analytics”、”headless-bi”、”semantic-layer” 三个标签直接对应 2026 三大趋势
- README 第一句话 “for AI”——MCP Server + Skills + Conversational Analytics 三件套是 AI Agent 时代的标配
1 句先试一周
跟着本文 6 步跑一遍——35 分钟让你的 AI Agent 真的能查指标。如果你已经在用 dbt,把 Cube.js 接上,1 周内就能让团队所有人用同一个数字说话。
参考
- Cube.js 调研(8/6 单点):《Cube.js 调研:20,558 stars 的开源语义层龙头》
- 语义层端到端实战(8/19 4 容器):《语义层端到端实战》
- MetricFlow 调研(L2 另一角):《MetricFlow 调研》
- 语义层四层模型横评:《语义层四层模型调研》
- BI 栈全景图 v2(语义层决策 8):《2026 BI 栈全景图 v2》
- GitHub 仓库:cube-js/cube
- Cube.js 官网:cube.dev
- MCP Server 文档:docs.cube.dev/ai/mcp
- dbt-core 调研:《dbt-core 调研》
📎 WordPress 链接
- 官方链接:《飞熊出品 · Cube.js 实战:三件套 Docker Compose 一键拉起,35 分钟让 AI Agent 查数据》
- 短链:
https://east196.cn/?p=375 - 状态:published · 2026-08-19