快速开始
用 marivo init 初始化项目(参见安装),
然后编写声明。一个最小 Marivo 项目包含 manifest、数据源声明
和语义声明:
智能体:在编写前请先查阅
md.help("authoring")和ms.help("authoring")了解分阶段 编写工作流,并查阅md.help("ai_context")了解共享的ms.ai_context(...)契约。
your-project/ marivo.toml models/ datasources/ warehouse.py semantic/ sales/ _domain.py先声明数据源:
import marivo.datasource as mdimport 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 mdimport marivo.semantic as ms
ms.domain( name="sales", owner="Mina Zhang", 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 —— 领域 → 实体 → 维度 → 时间维度 → 度量 → 指标 → 关系 —— 让每个对象的依赖先于它存在。
- 先发现,再编写。 对数据源-backed 对象,智能体先调用匹配的
md.discover_*API,再结合ms.help(...)确定构造器值,并把一个 声明写入models/semantic/<domain>/_domain.py。默认指标路径是md.discover_measures(...),author 并验证度量,再声明ms.aggregate(...)。 - 验证后再前进。 每写完一个对象就运行
ms.verify_object(ref),在它失败时不会继续。 - 收尾时做就绪检查。 最后运行
ms.readiness(),在把目录交给分析之前解决阻塞项。
智能体只会就那些无法从数据或项目文档推断的决策征询你,例如某个金额是否已经扣除退款。 它产出的就是上面展示的 Python 声明,可以像其他代码一样在 git 中评审。
分析前先探索目录。对数据源-backed 编写,发现-首个流程先收集有界证据, 再每次 author 一个对象:
import marivo.datasource as mdimport marivo.semantic as ms
warehouse = md.ref("datasource.warehouse")orders_source = md.table("orders")
md.inspect_table(warehouse, orders_source).show()md.inspect_partitions(warehouse, orders_source).show()
scope = md.partition({"dt": "20260629"})
md.discover_entity(warehouse, orders_source, scope=scope).show()ms.help("entity")结合发现证据和 ms.help("entity") 契约,一次只 author 一个对象,然后运行
ms.verify_object(ref),通过后再继续。
加载目录并检查就绪状态:
import marivo.semantic as ms
catalog = ms.load()catalog.list("domain").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.catalogrevenue = catalog.get("metric.sales.revenue")region = catalog.get("dimension.sales.orders.region")
current = session.observe( revenue, time_scope={"start": "2026-10-01", "end": "2027-01-01"}, grain="month", dimensions=[region],)baseline = session.observe( revenue, time_scope={"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 recommendationsdelta.quality_summary # cheap metadata projectionquality = session.assess_quality(delta)quality.show()当多个相同-范围指标共享同一窗口时,把指标列表传给
session.observe(...)。Marivo 会把同一数据源的指标合并为一次查询,
跨数据源的指标则按时间轴 outer-连接。用 frame.metric(id) 投影出
arity-1 frame,对单个指标做深入分析时不会重新查询后端。
report = session.observe( [ catalog.get("metric.sales.revenue"), catalog.get("metric.sales.total_orders"), catalog.get("metric.sales.failed_orders"), ], time_scope={"start": "2026-10-01", "end": "2027-01-01"}, grain="month",)report.show() # bucket_start + 三个值列revenue = report.metric("sales.revenue") # arity-1 frame,用于 drill-down如果自定义 Ibis 计算结果还要回到 Marivo 类型化指标流程,使用
session.derive_metric_frame(...)。语义引用只用于指标与轴绑定,
查询输出列名仍是普通字符串。跨后续脚本时,用 session.frame_summaries() 和
session.get_frame(ref) 恢复已有产物,不要重跑上游查询。用
artifact.contract().affordances 查看机械兼容性事实。
同样的项目结构,既可以支撑一次性脚本,也可以逐步沉淀为经过评审、可共享的分析项目。 差别主要来自下面三个习惯。
把语义层当作共享知识库建设
Section titled “把语义层当作共享知识库建设”语义层不只是访问表的管道。它是智能体在分析之前读取的知识库。为每个对象补充
ms.ai_context(...):
business_definition—— 这个指标或维度在业务上意味着什么。guardrails—— 智能体必须遵守的规则:必需的过滤、排除项、范围限制。synonyms与examples—— 帮助智能体把自然语言问题解析到正确对象,而不是靠猜。
上下文足够完整时,对象本身就能回答智能体的两个基本问题:“我能不能用它?”“应该怎么用?”
就绪检查负责守住底线:缺失 business_definition 会阻塞分析,缺失 guardrails 会发出警告。
完整的 ms.ai_context(...) 契约参见 语义层。
用 git 管理项目
Section titled “用 git 管理项目”一个 Marivo 项目本质上是纯文本:marivo.toml 加上 models/ 下的 Python 文件。因此语义层
可以像应用代码一样评审、共享和回滚。
- 对契约做版本控制。 提交
marivo.toml和models/。对指标定义或 guardrail 的每一次 改动都会以 diff 的形式呈现。 - 像评审代码一样评审语义改动。 通过 pull 请求合入定义改动,让领域负责人在 智能体使用之前确认指标的含义。
- 通过仓库共享。 clone 该项目的人,以及在其中运行的智能体,都会读取同一份可信目录。
- 把状态与密钥排除在 git 之外。 把
.marivo/加入.gitignore:它保存的是项目 本地的会话与证据状态,不是契约。凭据以*_env引用的形式编写,从环境 (或 user-global 的~/.marivo/secrets.toml缓存)解析,不写入项目。
一个典型的 .gitignore:
.marivo/交接前先做就绪检查
Section titled “交接前先做就绪检查”加载后运行 ms.readiness(),并在任何分析会话之前解决阻塞项。项目可以在就绪检查
仍为 blocked 时成功加载,因此不要把 blocked 目录交给智能体。参见
就绪检查。