飞熊出品 · Cube.js 实战:三件套 Docker Compose 一键拉起,35 分钟让 AI Agent 查数据

44次阅读
飞熊出品 · Cube.js 实战:三件套 Docker Compose 一键拉起,35 分钟让 AI Agent 查数据

副标题 :从 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 Corecube-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 真能查

  1. 打开 Claude Desktop(已配 MCP)
  2. 输入:”帮我查上个月华东区客户复购率
  3. 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: postgresview),避免双定义
4 生产锁定建议 v1.7.20+——v1.7.0 早期有 GraphQL breaking change 8/6 调研时 v1.7.16,8/19 最新 v1.7.23,patch 版本稳定

八、总结

3 个最值得用的理由

  1. OSS 双协议 Apache-2.0 + MIT——商业项目零风险(GitHub API 显示 NOASSERTION 是双协议元数据问题,README 明确双协议)
  2. 20,657 stars + 19 个高质量 topics——其中 “agentic-analytics”、”headless-bi”、”semantic-layer” 三个标签直接对应 2026 三大趋势
  3. README 第一句话 “for AI”——MCP Server + Skills + Conversational Analytics 三件套是 AI Agent 时代的标配

1 句先试一周

跟着本文 6 步跑一遍——35 分钟让你的 AI Agent 真的能查指标。如果你已经在用 dbt,把 Cube.js 接上,1 周内就能让团队所有人用同一个数字说话。


参考


📎 WordPress 链接

正文完