跳转到内容

快速开始

marivo init 初始化项目(参见安装), 然后编写你的声明。一个最小 Marivo 项目包含 manifest、数据源声明 和语义声明:

your-project/
marivo.toml
models/
datasources/
warehouse.py
semantic/
sales/
_domain.py

先声明数据源:

import marivo.datasource as md
import marivo.semantic as ms
md.duckdb(
name="warehouse",
path="warehouse.duckdb",
ai_context=ms.ai_context(
business_definition="Local DuckDB warehouse for sales analysis.",
guardrails=["Use only for development or approved local analysis."],
),
)

再声明语义对象:

import marivo.datasource as md
import marivo.semantic as ms
ms.domain(
name="sales",
ai_context=ms.ai_context(
business_definition="Sales order analysis domain.",
guardrails=["Revenue metrics should only use completed orders."],
),
)
orders = ms.entity(
name="orders",
datasource=md.ref("datasource.warehouse"),
source=ms.table("orders"),
primary_key=["order_id"],
ai_context=ms.ai_context(
business_definition="One row per sales order.",
guardrails=["Exclude cancelled test data in metric definitions."],
),
)
region = ms.dimension_column(
name="region",
entity=orders,
column="region",
ai_context=ms.ai_context(
business_definition="Sales region assigned to the order.",
guardrails=["Do not treat missing region as a real region."],
),
)
order_date = ms.time_dimension_column(
name="order_date",
entity=orders,
column="order_date",
granularity="day",
is_default=True,
ai_context=ms.ai_context(
business_definition="Calendar date when the order was placed.",
guardrails=["Use this as the default time axis for order metrics."],
),
)
amount = ms.measure_column(
name="amount",
entity=orders,
column="amount",
additivity="additive",
unit="CNY",
ai_context=ms.ai_context(
business_definition="Completed order amount at row level.",
guardrails=["Use only where order amount is already net of cancellations."],
),
)
revenue = ms.aggregate(
name="revenue",
measure=amount,
agg="sum",
ai_context=ms.ai_context(
business_definition="Total completed order amount.",
guardrails=["Use only where order amount is already net of cancellations."],
),
)

你不必手写这些对象。marivo init 已经把 marivo-semantic 技能 安装到 .agents/skills/.claude/skills/.codex/skills/,因此在项目中运行的编码智能体可以和你一起构建 语义层。把它指向你的表并提出请求:

使用 marivo-semantic 技能为 sales 领域中的 orders 表建模。

该技能会引导智能体走一个有纪律的编写循环,每次只处理一个对象:

  • 遵循 ladder —— 领域 → 实体 → 维度 → 时间维度 → 度量 → 指标 → 关系 —— 让每个对象的依赖先于它存在。
  • 先规划,再编写。 对每个对象,智能体先调用匹配的 ms.prepare_* API,根据返回的 brief 分支判断,再把声明写入 models/semantic/<domain>/_domain.py。默认的 指标路径是先调用 ms.prepare_measure(...),写入并验证度量,再声明 ms.aggregate(...)ms.prepare_metric(...) 只用于度量-backed 流程需要 指标-层级上下文的场景。
  • 验证后再前进。 每写完一个对象就运行 ms.verify_object(ref),在它失败时不会继续。
  • 收尾时设闸。 最后运行 ms.readiness(),在把目录交给分析之前解决阻塞项。

智能体只会就那些无法从数据或项目文档推断的决策征询你(例如某个金额是否已扣除退款)。它产出 的,正是上面展示的同一批 Python 声明 —— 可以像其他代码一样在 git 中评审。

分析前先探索目录:

import marivo.semantic as ms
catalog = ms.load()
catalog.list().show()
report = catalog.readiness()
if report.status == "blocked":
report.show()

目录就绪后,开启分析会话:

import marivo.analysis as mv
session = mv.session.get_or_create(name="revenue-check", question="Why did Q4 drop?")
catalog = session.catalog
revenue = catalog.get("sales.revenue")
region = catalog.get("sales.orders.region")
current = session.observe(
revenue,
timescope={"start": "2026-10-01", "end": "2027-01-01"},
grain="month",
dimensions=[region],
)
baseline = session.observe(
revenue,
timescope={"start": "2025-10-01", "end": "2026-01-01"},
grain="month",
dimensions=[region],
)
delta = session.compare(current, baseline)
attribution = session.attribute(delta, axes=[region])
attribution.show()
delta.contract().affordances # mechanical compatibility, not recommendations
delta.quality_summary # cheap metadata projection
quality = session.assess_quality(delta)
quality.show()

如果自定义 Ibis 计算结果还要回到 Marivo 类型化指标流程,使用 session.derive_metric_frame(...)。语义引用只用于指标与轴绑定, 查询输出列名仍是普通字符串。跨后续脚本时,用 session.frame_summaries()session.get_frame(ref) 恢复已有产物,不要重跑上游查询。用 artifact.contract().affordances 查看机械兼容性事实。

同样的项目结构,可以从一次性脚本一路扩展到经过评审、可共享的分析项目。三个习惯决定 了差别。

把语义层当作共享的知识库来建设

Section titled “把语义层当作共享的知识库来建设”

语义层不只是触达表的管道 —— 它是智能体在分析之前所读取的知识库。在每个对象上 投入 ms.ai_context(...)

  • business_definition —— 这个指标或维度在业务上意味着什么
  • guardrails —— 智能体必须遵守的规则:必需的过滤、排除项、范围限制。
  • synonymsexamples —— 让智能体把自然语言问题解析到正确的对象,而不是靠猜。

一个充分丰富的对象,无需人类介入就能回答智能体的“我能用它吗,怎么用?”。就绪检查守住底线: 缺失 business_definition 会阻塞分析,缺失 guardrails 会发出警告。完整的 ms.ai_context(...) 契约参见 语义层

一个 Marivo 项目就是纯文本:marivo.toml 加上 models/ 下的 Python 文件。这让语义 layer 成为一个可评审、可共享的工件 —— 把它当作应用代码来对待。

  • 对契约做版本控制。 提交 marivo.tomlmodels/。对指标定义或 guardrail 的每一次 改动都会以 diff 的形式呈现。
  • 像评审代码一样评审语义改动。 通过 pull 请求合入定义改动,让领域负责人在 智能体使用之前批准一个指标的含义
  • 通过仓库共享。 任何 clone 该项目的人 —— 以及任何在其中运行的智能体 —— 都得到同一份 可信目录。
  • 把状态与密钥排除在 git 之外。.marivo/ 加入 .gitignore:它保存的是项目 本地的会话与证据状态,不是契约。凭据以 *_env 引用的形式编写,从环境(或 缓存于 user-global 的 ~/.marivo/secrets.toml)解析 —— 它们从不写入项目。

一个典型的 .gitignore

.marivo/

加载后运行 ms.readiness(),并在任何分析会话之前解决阻塞项。一个项目可以在 就绪检查仍为 blocked 时成功加载,因此绝不要把一个 blocked 的目录交给智能体。参见 就绪检查