跳转到内容

分析流程

每次 Marivo 分析都从一个 指标 开始,并以写-运行-读循环运行:智能体写出一个 意图(一次操作调用加上它的字段),运行它,读取一个类型化结果,再决定下一步。

各组成部分:

  • 会话 持有指导问题、语义目录,以及每一步的持久化结果。
  • 操作调用 是一次确定性的分析步骤 —— observecompareattributediscover.<objective> 以及其他核心操作 —— 及其参数。这些参数就是分析规格。
  • 产物 是操作的类型化结果。产物是步骤之间的边界:每个操作消费 特定产物家族,并产出另一个。
import marivo.analysis as mv
import marivo.semantic as ms
session = mv.session.get_or_create(name="revenue-investigation", question="Why did Q4 drop?")
catalog = session.catalog
revenue = catalog.get("sales.revenue") # a metric object
region = catalog.get("sales.orders.region") # a dimension object

get_or_create 是幂等的:它附着到同名的已有会话,或创建一个,并设为当前会话。 会话的精简 API 为 get_or_createcurrent()list()delete(name)

操作接受目录对象和若干共享的值对象。几乎每个意图都会复用它们:

形态含义
指标输入catalog.get("sales.revenue")一个目录指标对象或其 SemanticRef 子类(如 MetricRef)。来自 ms.aggregate(...) 的编写引用也可用。裸字符串会被拒绝。
维度输入catalog.get("sales.orders.region")一个目录维度对象,或其 DimensionRef / TimeDimensionRef(见 语义引用)。用于 dimensionswhere 的键和 axes
timescope{"start": "2026-10-01", "end": "2027-01-01"}半开时间区间 —— start 含、end 不含。
grain"day" | "week" | "month" | "quarter" | "year" | "hour" | …时间桶大小。存在 ⇒ 时间序列或面板。
dimensions[region, country]分段轴。v1 中全部必须解析到指标所属实体。
where{region: "US"}{amount: {"op": ">", "value": 100}}聚合前的行过滤(见下方运算符)。
AlignmentPolicymv.window_bucket()compare / correlate 时两个窗口如何配对。

结果的 语义类型graindimensions 决定:scalar(都没有)、 time_series(仅粒度)、segmented(仅维度)或 panel(两者皆有)。

键是目录维度;值为标量(==)、列表(in),或结构化的 {"op": ..., "value": ...} 形式:

形式含义
"US"==(相等)
["US", "CA"]in(成员)
{"op": "!=", "value": "US"}不等
{"op": ">", "value": 100}>=<<= 同理)数值比较
{"op": "between", "value": ["2026-07-01", "2026-09-30"]}闭区间(恰好两个值)

任何分析的起点:在某个时间范围和/或分段上物化一个指标。

参数类型必填默认含义
metric指标对象 / 引用要物化的指标。
timescopedictNone半开 {"start", "end"} 窗口。
grain粒度None时间桶;存在 ⇒ 时间序列或面板。
dimensionslist[ref]None分段轴。
wheredictNone聚合前的行过滤。
time_dimension引用实体默认当实体声明多个时间轴时选择其一。
expect_shape形状None守卫;若预测形状不符,在访问后端前抛错。
current = session.observe(
revenue,
timescope={"start": "2026-10-01", "end": "2027-01-01"},
grain="month",
dimensions=[region],
)

量化两个 observe 结果之间的变化(当前减 baseline)。两个 frame 必须共享指标与 语义类型。

参数类型必填默认含义
currentMetricFrame当前期 frame。
baselineMetricFrame基线期 frame。
alignmentAlignmentPolicywindow_bucket桶/分段如何配对。
baseline = session.observe(
revenue,
timescope={"start": "2025-10-01", "end": "2026-01-01"},
grain="month",
dimensions=[region],
)
delta = session.compare(current, baseline)

compare 默认用 window_bucket 配对桶。传入 alignment= 可覆盖 —— mv.dow_aligned()mv.holiday_aligned()mv.holiday_and_dow_aligned();calendar 支持的几种还接受 calendar=mv.CalendarRef(...)

把差值的变动归因到显式轴上。这是“为什么变了?”分析的默认公共入口。 如果请求的轴在差值中缺失,且源 observe/比较的血缘可重放,Marivo 会在 分解之前先物化扩展后的差值。

参数类型必填默认含义
frameDeltaFrame要归因的差值。
axeslist[dimension]进行归因的分段轴或时间轴。
attribution = session.attribute(delta, axes=[region])
attribution.show()

在对齐的桶上度量两个指标之间的关联。

参数类型必填默认含义
abMetricFrame要关联的两个 frame。
measure_ameasure_bstrframe 度量各 frame 上的数值列。
alignmentAlignmentPolicywindow_bucket桶配对。
method"pearson""pearson"关联方法(v1:Pearson,零滞后)。

将一个时间序列或面板向前投影。

参数类型必填默认含义
historyMetricFrame(time_series/面板)连续历史,无 NaN。
horizonint要投影的桶数(≥ 1)。
model"naive" | "seasonal_naive" | "drift""seasonal_naive"预测策略。
seasonality_periodint按粒度覆盖季节周期(day=7、week=52、month=12、quarter=4)。
interval_levelfloat0.95预测区间的置信水平。
measure_columnstrframe 度量要预测的列。
history = session.observe(revenue, timescope={"start": "2026-01-01", "end": "2026-04-01"}, grain="day")
projection = session.forecast(history, horizon=30)

对一个产物运行质量检查,返回一个独立的 QualityReportartifact.quality_summary 只是 cheap、已持久化的元数据投影;它不等同于执行 session.assess_quality(artifact)

参数类型必填默认含义
frameMetricFrame要检查的 frame。

对一个指标在两期之间均值是否变化做配对检验。

参数类型必填默认含义
abMetricFrame当前期与基线期 frame。
hypothesis"mean_changed""mean_changed"检验类型(v1)。
value_avalue_bstrframe 度量各 frame 上的数值列。
alignmentAlignmentPolicywindow_bucket检验的配对方式。
samplingSamplingPolicy推断配对/最小样本规则。
alphafloat0.05显著性水平。

发现 —— session.discover.*CandidateSet

Section titled “发现 —— session.discover.* → CandidateSet”

发现操作在一个产物中搜索确定性候选行,并返回 CandidateSet。候选行顺序 是确定性 score order,不是 Marivo 的推荐。

辅助函数源形状必填关键选项
point_anomaliesMetricFrame time_series/面板valuethreshold=3.0
period_shiftsDeltaFrame time_series/面板≥ 4 个桶valuethreshold=2.0
driver_axesDeltaFramesearch_spacevaluelimit
interesting_slicesMetricFrameDeltaFramesearch_spacevaluethreshold=2.0limit
interesting_windowstime_series/面板 framevaluethreshold=2.0
cross_sectional_outliersMetricFrame segmented/面板peer_scopevaluethreshold=3.0
series = session.observe(revenue, timescope={"start": "2026-01-01", "end": "2026-04-01"}, grain="day")
candidates = session.discover.point_anomalies(series, threshold=2.0)
candidates.show()

Advanced 引用 —— session.transform.*

Section titled “Advanced 引用 —— session.transform.*”

变换在保持 frame 家族(MetricFrameMetricFrameDeltaFrameDeltaFrame)的前提下重塑 frame。

变换关键参数效果
filterpredicate(callable)保留谓词为真的行。
slicewhere(轴 → 值/列表/区间)保留匹配精确轴值的行。
rollupdrop_axes删除轴并对度量重新聚合。
topkbylimitorder按某个度量取前 N 行(默认 order="decrease")。
bottomkbylimit取后 N 行。
rankbymethodrank_column按某个度量排序并加一列 rank。
normalizemodebaselineindex / share / pct_change / per_unit / z_score(仅 MetricFrame)。
windowwindow限制到一个时间窗口。

受治理的 derive —— session.derive_metric_frame(...)

Section titled “受治理的 derive —— session.derive_metric_frame(...)”

当自定义 Ibis 计算结果必须回到类型化指标流程时,使用 derive_metric_frame。它总是返回 MetricFrame。语义引用标识指标、时间和维度绑定;查询输出列是普通字符串。

import marivo.datasource as md
warehouse = md.ref("datasource.warehouse")
custom = session.derive_metric_frame(
metric=session.catalog.get("sales.revenue"),
query=mv.ibis_query(
datasource=warehouse,
build=lambda db, ctx: db.table("orders"),
),
columns=mv.metric_columns(
value="value",
time=mv.time_column(
column="order_date",
ref=session.catalog.get("sales.orders.order_date"),
),
dimensions=[
mv.dimension_column(
column="region",
ref=session.catalog.get("sales.orders.region"),
),
],
),
timescope={"start": "2026-06-18", "end": "2026-06-25"},
grain="day",
label="custom_revenue_by_region",
)
custom.show()

需要做终端本地 pandas 工作、且不必回到类型化 Marivo 操作时,使用 artifact.to_pandas()

智能体读取产物时按层下钻,以降低跨 loop 成本:

repr(delta)
delta.summary()
delta.schema()
delta.contract()
delta.preview(limit=10)

artifact.contract().affordances 查看机械兼容性。它只说明哪些公共操作 在机械上可以消费该产物、缺哪些输入;它不排序、不推荐,也不决定下一步。

后续脚本需要前序结果时,读取持久化事实,而不是重跑上游查询:

summaries = session.frame_summaries()
jobs = session.recent_jobs(limit=5)
previous = session.get_frame(ref)

每个操作都会把证据记录到会话,使结论保持可审计。

  • session.knowledge() —— 整个会话的既定事实、驱动因素事实、未决异常和建议的后续。
  • session.evidence.findings(...).propositions(...).assessments(...).proposition(id).latest_assessment(id).trace(id) —— 查找证据对象, 并把一个命题追溯回支持它的证据项。

完整模型见 证据

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 你可以分支:用 session.discover.period_shifts(delta) 找出它何时移动,或用 session.forecast(current, horizon=3) 向前投影。

Frame由谁产出
MetricFrameobservederive_metric_frame
DeltaFramecompare
AttributionFrameattribute
AssociationResultcorrelate
ForecastFrameforecast
QualityReportassess_quality
HypothesisTestResulthypothesis_test
CandidateSetdiscover.*