下载研究报告
DEEP DIVE / ANALYSIS MODULE

AB 分析模块:自定义分析、下钻与高级分析

实验分析模块不是一张固定报表,而是一套受控的语义层:把人群、指标、维度、窗口和统计方法变成可组合、可复现、可审计的对象。本文横向拆解公开竞品的分析工作台,并给出一套类似 Libra AB Insight 的产品与架构设计。

25,733 字 51 分钟 70 条引用
ab-insight / experiment / EXP-2481 INTERACTIVE SPEC
数据为虚构
怎么读这个演示:它不是一个真实产品截图,而是一份可点击的界面规格。切换左侧的五个分析面,观察「结论 → 指标 → 人群 → 下钻 → 方法」如何共享同一套口径;下钻面板底部的查询检查器展示每次交互对应的请求。
EXP-2481 / CLIENT
首页推荐卡改版
运行中 · D6 / 14
A 40% · B 40% · C 20%
SRM p=0.42
指标 18 · 人群 4
实验 / 首页推荐卡改版 / 总览

结论与证据

固定样本 · 频率派 · 双侧 α=0.05
DECISION / 建议
B 组可扩量至 50%,但增量集中在应用商店渠道;C 组样本不足,暂不结论。建议保留 10% holdout 观察 14 天后的留存。
+2.41%核心指标 · 相对提升
95% CI +1.10% ~ +3.72%
7 日人均有效停留
13.15min / +2.41%
p=0.002 · 显著 · n=497,552
内容举报率(护栏)
0.41%-2.38%
p=0.44 · 不显著 · 未恶化
样本 / SRM
1.24M进组用户
SRM p=0.42 · 通过
核心指标:7 日人均有效停留(min)相对对照 A
A 对照12.84 · base
B 新卡片13.15 · +2.41%
C 卡片+文案12.91 · +0.55%
SRM 通过 护栏 未恶化 探索性 渠道拆分未校正 口径 曝光后 7 个自然日 更新 T-1 日级
三种读法

产品 / 设计:0 → 3 → 4 → 7,先看十个判断,再看自定义分析与人群,最后看页面解剖。数据 / 统计:4 → 5 → 6,重点看因果边界、下钻护栏与方法选择。架构 / 工程:2 → 8,重点看对象模型、查询契约与存储选型。只想汇报:0 与 10.4,两页就够。

0. 先看结论:十个设计判断#

分析模块的竞争力,不在于能画多少张图,而在于同一个问题被两个人问,能得到同一个答案;以及这个答案能不能被追溯到指标版本、人群版本、数据截止时间和统计方法。
5个分析面:总览、指标、人群、下钻、高级分析SURFACES
14种指标算子,覆盖 PV/UV/AU、比率、人均、去重与组合指标OPERATORS
3道默认护栏:SRM、必看指标、多重比较提示GUARDRAILS

分析模块卖的是口径,不是图表

图表可以被复制,口径不能。指标的分母、去重键、归因窗口、排除规则一旦漂移,所有漂亮的置信区间都失去意义。

结论先行,但证据必须同屏

首屏给结论,同时给样本量、置信区间、方法与数据截止时间。只给「+2.4%」而不给区间的产品,会把统计问题变成文案问题。

自定义的边界是语义层

让用户组合指标、人群、维度、窗口与方法,而不是把 SQL 输入框丢给业务。自由 SQL 可以存在,但必须走沙箱、血缘与成本配额。

人群分「进组前」与「进组后」

进组前是分配问题,进组后是分析问题。前者改变随机化与外部有效性,后者容易引入 post-treatment bias。UI 必须在用户选错之前解释代价。

下钻是受控探索,不是无限 group by

每下一层都要保留对照、样本量、置信区间与多重比较状态。没有这些,下钻只是把噪声切得更细。

高级方法默认严谨

CUPED、序贯、FDR 应该默认开启并解释;Uplift、CATE 应该默认标注「探索性」。把论文菜单直接暴露给业务,是平台最昂贵的偷懒。

指标要有 owner、版本与血缘

指标不是字段的别名。一个可用的指标定义至少包含:事件、聚合、分母、过滤、时间窗、归因、去重键、负责人、上线状态。

性能就是产品能力

下钻超过 2 秒,用户就会退回 Excel;人群预览超过 10 秒,运营就不会用。查询延迟直接决定分析深度。

信任来自可见的失败

SRM 异常、护栏恶化、样本不足、数据延迟、口径变更,都要在结论旁边显式出现。隐藏失败比失败本身更伤信任。

分析要沉淀为决策资产

保存视图、评论、决策记录、复盘模板,让一次分析可被复用、被挑战、被审计。否则平台只是「一次性报表工厂」。

本文的证据边界

Libra 是字节跳动的内部实验平台,DataTester 是其对外商业化版本。两者同源,但不能把 DataTester 的公开文档当成 Libra 内部版的全部。本文把材料分成三类:官方 官方文档/论文/演讲;推断 由公开材料反推;建议 我们的产品设计判断。内部版的 CUPED/ITR、LLM 分析、图聚类等能力,公开材料只能证明「存在实践」,不能证明「对外产品已具备」。

1. 拆解:Libra 的 AB Insight 做对了什么#

先澄清一个命名问题:用户口中的「AB Insight」在公开材料里找不到对应的正式产品名。可查证的是 Libra(字节内部平台)与 DataTester(对外商业化版本)的 Experiment Report 与 Advanced Analysis。本文用「AB Insight」指代这套分析工作台,不指某一个具体菜单。字节在 2012 年引入 A/B 体系,2016 年产品化,2021 年通过火山引擎对外开放;官方在 AICon 2025 的口径是累计 340 万+ 次实验、同时运行 7 万+ 来源。这套规模决定了它的分析模块不可能是一张固定报表:它必须把「看结论」拆成一组可复用的分析面,并让不同角色在同一套口径上协作。

从公开的 DataTester 文档可以还原出六个稳定的分析面。它们不是六个菜单,而是六种决策问题:

分析面 用户真正的问题 公开实现要点 值得抄的部分
实验总览 这版能不能上? 核心指标、必看指标、置信区间、MDE、日级趋势、概率分布、箱线图;支持时间/维度筛选 结论与证据同屏;MDE 用来解释「不显著」
指标分析 哪个指标动了?动了多少? 指标组/指标视图;事件、留存、漏斗三类;相对/绝对差异、p 值、CI;指标级下钻 指标组按业务问题组织,不按数据表组织
人群分析 对谁有效?谁被伤害? 用户分群(规则/文件)、自定义筛选模板、差异分析与分组对比、客群实验 人群是分析的一等对象,不是临时 filter
下钻 为什么动?动在哪? 维度拆分、时间趋势、用户明细、TopN;即席 OLAP 每层保留对照与样本量;用户级下钻脱敏
高级分析 效应可信吗?对谁最大? 差异分析、Cohort、Uplift/敏感人群、ANOVA、Monte Carlo 方法以「问题」命名,不以「算法」命名
诊断 数据是不是错了? SRM/分流诊断、数据延迟、指标口径、告警 把失败状态做成产品的一等公民

报告页的阅读顺序也值得抄:左侧指标导航按「关注指标组」组织,默认展开核心指标所在组;表格先给相对差异、置信区间、指标值,显著性用底色标出;只有切到单指标视图,才展开进组人数、日级趋势、概率分布与箱线图 来源。这个「组 → 单指标 → 证据图」的阶梯,把 PM、DA、运营三类读者分开了:PM 看第一屏拍板,DA 看第二屏复核,运营看筛选后的切片执行。

两个容易被忽略的细节,恰恰是设计精髓。其一,日级趋势是「截至当日已进组全部用户」的累计口径逐日切片,所以区间随时间收窄是设计使然,不是「越跑越显著」的证据;想看新进组人群的质量变化,必须用 cohort 分析。其二,概率分布是模型视角,箱线图是原始数据视角,同屏并列是为了交叉验证:如果正态曲线说「差不多」而箱线图的长尾明显不同,真正该信的是后者。代价是口径变多:日级不含今天、留存按首次进组归因、漏斗把实验曝光当作第一步之前的过滤事件 来源——每一条都能让两个人在同一张图上吵起来。DataTester 的兜底方式是把限制写进 UI:不能画就不给入口(例如属性分组后禁用分布图、CVR 不提供箱线图)来源。这比写在文档里有效,但也削掉了探索空间。

1.1 客群实验:把「人群 × 策略」做成双因素设计#

DataTester 的「客群实验」是一个很值得研究的设计:它不是「先开实验,再按人群切一刀」,而是在实验配置阶段就声明两个客群(如 test / test 1),报告页同时给出三个层次的结论 来源:

  • 每个实验版本下,各客群的获胜概率;
  • 每个客群下,各实验版本的获胜概率;
  • 双因素方差分析(ANOVA)表:客群(行因子)× 策略(列因子),输出交互效应、主效应、简单主效应,以及 SS、df、MS、F、p、F critical。

获胜概率用 Monte Carlo 近似:对每个组拟合正态分布,重复抽样 10 万次,统计「谁最大」的频率 来源。这套设计的产品价值在于:它把「策略对不同人群是否不同」从分析师的临时探索,变成了实验发起时就可以声明的研究问题。

但它也有明确的代价:

  1. 样本量按客群 × 版本切分,交互效应的功效远低于主效应;小客群很容易「看起来有差异」。
  2. ANOVA 假设方差齐性与近似正态,对重尾、比率型指标并不稳健;产品需要提示或提供 bootstrap。
  3. 获胜概率不是 p 值,不能按频率派显著性解释;多客群、多版本比较仍需多重比较校正。
  4. 客群必须在进组前定义,否则就是 post-treatment 分层,不能做因果解释。

建议 如果我们要做类似能力,不要把「客群实验」做成一个独立的实验类型,而应把它做成分析配置:实验仍然只有一套随机化,客群作为「预注册的分析维度」挂在实验上;报告默认展示交互效应的功效与 FDR 校正结果。

1.2 敏感人群洞察:Uplift 的产品化样本#

DataTester 的「敏感人群洞察」是公开文档里少见地把 Uplift 做成完整工作流的产品 来源:

  • 任务粒度是「一个指标、一个实验组、一个对照组」;
  • 挖掘方向分正向/负向(找提升最大的人,或找下降最小的人);
  • 用户属性作为特征,模型输出 ITE(Individual Treatment Effect),按 ITE 分 10 个 bins;
  • 报告给出 TOP 敏感人群、特征重要性、TOP 3 特征的二维交叉子群,以及子群的人数占比、绝对/相对差异、相对差异贡献、p 值;
  • 支持下载人群明细(treatment、uid、ite、bins、业务 ID),用于后续定向运营。

这套产品的聪明之处,是把「因果模型」翻译成了运营能用的三个东西:一群人、一个方向、一个可执行的名单。但它也暴露了 Uplift 的典型风险:

  • 推荐入组人数 > 2 万、维度 > 4 个,否则模型不稳定 来源;
  • 子群是「TOP 特征交叉」选出来的,存在选择偏倚;报告里的 p 值没有做多重比较校正;
  • ITE 是模型预测,不是个体真实因果效应;下载名单用于全量投放前,应该做 holdout 验证;
  • 「负向挖掘」找到的人群,可能只是回归到均值,不等于策略真的伤害了他们。

建议 产品上必须同时给「模型置信度 / 子群样本量 / 是否经过 FDR / 是否有 holdout 验证」四个状态;否则 Uplift 会变成「用机器学习包装的细分」。更稳妥的做法是把 Uplift 放在「探索」层,把验证放在一个新的 confirmatory 实验里。

1.3 用户分群:先 hash 再过滤,这个顺序很关键#

DataTester 的用户分群支持两种创建方式:规则圈选与文件上传;规则支持「做过 / 没做过 / 依次做过 / 用户是 / 用户不是」,支持 AND/OR 与嵌套,支持日更或手动更新;分群可以作为实验的受众规则,也可以作为 Feature 的定向人群 来源。

更重要的一句话藏在文档里:分流时,非白名单用户先做 hash 分桶,再做人群过滤 来源。这意味着:

  • 人群规则影响的是「谁有资格进入分析」,而不是「谁被分到哪个组」;
  • 只要人群定义与实验分配独立,按人群切子群不会破坏随机性;
  • 但如果人群定义使用了实验期行为(例如「点击过新卡片的人」),它就成了 post-treatment 变量,按它切子群会产生 collider/selection bias。

推断 这个顺序是字节系产品在因果设计上最值得学的一处:它把「定向」和「分析」解耦,让同一个分群既能用于投放,也能用于分析,但不会悄悄改变随机化。很多自建平台把人群过滤放在分桶之前,结果实验组和对照组的入组概率随人群变化,SRM 和结论一起失效。

1.4 公开材料能看到什么、看不到什么#

能力 公开证据 判断
报告总览、指标组、趋势、分布、箱线图 DataTester 官方文档 官方 对外版具备
自定义筛选模板(实验级 10 个、应用级 50 个) 官方文档 官方 可复用、可共享
差异分析 / 分组对比 / 客群实验 / ANOVA 官方文档 官方 已产品化
Uplift / 敏感人群 / 人群下载 官方文档 官方 已产品化,但统计校正有限
Cohort / 漏斗 / 热图 官方文档 官方 分析面完整
CUPED / ITR 2024 内部演讲、论文 推断 内部实践强,对外文档未提
LLM 实验分析 / 归因 2024 AICon 演讲 推断 有内部落地,产品化程度未知
图聚类 / DQ 估计量 论文、演讲 推断 服务特定场景,不是通用分析模块

这张表最重要的不是「谁有谁没有」,而是提醒我们:对外文档的完整度不等于内部能力的完整度,反之亦然。做竞品分析时,必须把「产品能力」「工程能力」「统计能力」分开评估;否则很容易把一次演讲里的方法,当成采购后立刻可用的功能。

1.5 横向看:五种分析范式#

把 Libra/DataTester 放回市场里,会发现「分析模块」并没有统一形态。公开文档与产品定位大致可以分成五种范式,每种范式的强项与盲区几乎互补:

范式 代表产品 分析入口 自定义能力 人群/下钻 高级统计 主要盲区
报表型 Optimizely、VWO、AB Tasty、Convert 实验结果页 指标 + 受众筛选,少量自定义 分段筛选为主,探索有限 内置 Stats Engine / Bayesian / 序贯 灵活探索弱;离开预设报表就回到 SQL
探索型 Amplitude、PostHog、Mixpanel 事件分析 / 漏斗 / 留存 事件、属性、公式、 cohort 强:任意事件、路径、cohort 有实验统计,但深度与治理弱于专业平台 治理弱;指标口径容易散落
仓库原生 Eppo、GrowthBook 实验分析 + 数仓指标 SQL/指标即代码,认证指标 强:维度、切片、cohort CUPED、序贯、贝叶斯、多重比较 延迟与成本取决于数仓;需要数据工程能力
统计工作台 Statsig 实验 + 指标 + Pulse 自定义指标、指标源 中:维度、holdout、分层 强:CUPED、序贯、贝叶斯、SRM 产品分析深度不如探索型;上下文弱
人群/增长型 DataTester、神策 实验报告 + 人群 + 营销 事件指标、人群包、Uplift 强:人群圈选、差异分析、名单下载 中:频率派为主,Uplift 有产品化 容易把「人群运营」当成「因果结论」

推断 这张表是「公开文档 + 产品定位」的归纳,不是逐项功能验收。比如「仓库原生」的延迟取决于客户数仓,不能一概而论;「探索型」的实验统计也在补课。真正稳定的差异是数据放在哪里、口径由谁定义、分析面向谁。

三个结论:

  1. 报表型强在结论,弱在探索;探索型相反。 前者适合 PM 快速拍板,后者适合分析师找假设;把两者做成同一个页面,往往两边都不满意。
  2. 仓库原生强在口径,弱在交互。 指标留在数仓、SQL 可审计,代价是每次下钻都可能等数仓;它最适合「指标治理成熟、分析频率不高」的组织。
  3. 统计工作台强在方法,弱在业务上下文。 CUPED、序贯、贝叶斯做得再细,如果用户不知道「这个指标对应哪个业务动作」,方法只会增加解释成本。

所以产品设计的第一步不是列功能,而是选主范式:我们到底要服务「拍板」「找假设」还是「治理口径」?选完之后,再用另外两种范式补短板。五种都想要,结果通常是五种都不像。

2025–2026 的所有权变化也要计入选型:Statsig 2025 年被 OpenAI 收购、2026 年由 Amplitude 接手品牌与客户;Eppo 自 2025 年起以 Eppo by Datadog 运营;VWO 与 AB Tasty 于 2026 年合并为 Wingify,但官方明确两边产品目前仍各自运行 来源 来源 来源。这意味着你看到的路线图,可能已经换了一个主人;选型时要问「收购后的产品归属、数据迁移与合同主体」,而不只是功能清单。

1.6 中国平台的三种分工#

把镜头拉远,中国大厂的分析模块大致有三种分工,各自解决不同的问题 来源 来源 来源:

分工 代表 分析模块的重心 代价 适合
运营工作台 字节 DataTester 报告、模板、人群、Uplift、名单下载 统计深度让位于可用性;高级方法默认值不透明 业务方自助、运营驱动
统计底座 腾讯/美团 CUPED、FDR、SRM、HTE、AA 验证、方法库 使用门槛高;需要 DS 解释 实验密集、决策风险高
数仓共生 阿里通天塔、得物 指标语义层、实时/离线链路、即席 OLAP 强依赖数据团队;交互受预计算粒度限制 已有成熟数仓、指标治理

得物的三级查询是一个很务实的产品契约:ClickHouse 存预计算指标,承接大多数页面数字;StarRocks 承接复杂分析与明细聚合,秒级到分钟级;StarRocks 跑不动的查询自动降级到 ODPS,10 分钟到 1 小时;查询过程做并发限制与 Redis 缓存,避免拖垮 OLAP 集群 来源。这等于把「哪些秒回、哪些要等」写进了产品,而不是让用户在一个转圈页面里猜。

推断 三种分工没有高下,只有匹配:业务方自助强的组织,先学运营工作台;实验密度高、决策风险大的组织,先学统计底座;数仓成熟、指标统一的组织,先学数仓共生。最怕的是三种都想要,最后做成一个「有 Uplift 按钮、但没有指标 owner」的平台。

1.7 如果只能抄五件事#

  1. 指标组按业务问题组织,而不是按事件表组织;默认展示核心指标组,其他折叠。
  2. 筛选模板:把「一线城市 + 版本 ≥ 14 + 新用户」这种反复使用的口径保存成模板,实验级与应用级分层复用。
  3. 差异分析:属性过滤 + 用户分群 + 多组对比,让「对谁有效」成为标准动作,而不是分析师写 SQL。
  4. 人群下载:把分析结果变成可执行的名单,但必须带 ITE、bins、treatment 与业务 ID,方便运营验证。
  5. 诊断工具:把「为什么没命中/为什么数据不对」做成可查询的日志,而不是让用户猜。

2. 分析对象模型:让一次分析可复现#

大部分分析平台的数据模型只建模「实验」和「指标」,然后把人群、维度、时间窗、统计方法塞进查询参数。结果是:同一张报表,昨天和今天可能不是同一个问题;同一个人分享链接,另一个人打开看到的是另一套口径。

更稳的做法是把「一次分析」本身建模成对象。最小对象集是七个:

ANALYSIS OBJECT MODEL / 最小对象集v1.0
Experimentexperiment_idversionvariantsassignment_unitexposure_ruleowner
Analysisanalysis_idquestionmetric_setaudiencedimensionswindowmethod
Metricmetric_idversionnumeratordenominatorfilterwindowdedup_keyowner
Audiencecohort_idversionrule_treesnapshot_timerefreshestimated_reach
Dimensiondimension_idhierarchyvalue_dicttime_semanticscardinality
Methodestimatorcimultiplicitycupedsequentialmin_sample
Resultrun_idquery_fingerprintdata_cutoffwarningssnapshot

这七个对象里,最容易被漏掉的是 Method 和 Result。没有 Method,用户无法知道这个区间是固定样本还是序贯、是原始方差还是 CUPED、有没有做 FDR;没有 Result,用户无法复现「上周五看到的那张图」,也无法在指标定义变更后判断结论是否还成立。

一个可执行的契约

任何分析请求都必须携带六个版本号:experiment_version、metric_version、cohort_version、dimension_snapshot、method_version、data_cutoff。少一个,结果就不可复现;多一个,存储成本可控。把六个版本号拼成的哈希写进结果表,就是「口径指纹」。报表页可以把它折叠在「证据」里,但当两个数字打架时,它是唯一能仲裁的东西。

2.1 信息架构:五个分析面,一条证据链#

分析页不是五个并列的 tab,而是一条从「要不要信」到「为什么」的链:

01 / VERDICT
结论
能不能上?证据够不够?
02 / METRICS
指标
哪个动了?动了多少?
03 / AUDIENCE
人群
对谁有效?谁被伤害?
04 / DRILL
下钻
动在哪?为什么?
05 / METHOD
高级分析
可信吗?能不能行动?

这条链的顺序不能反。先看人群再看指标,会把「找人群」变成「找显著」;先看高级分析再看总览,会把方法当成结论。产品上可以用 tab 呈现,但默认落地页必须是结论,且每个 tab 的顶部保留「当前实验 / 当前指标 / 当前人群 / 数据截止」的上下文条。

2.2 分析画布:六个槽位,三种保存#

把「自定义分析」做成一个画布,而不是一堆筛选器。画布只有六个槽位:

SLOT 01

对象

哪个实验、哪个版本、哪个对比组。对象决定随机化单元与曝光口径,后续所有计算都继承它。

SLOT 02

指标

一个核心指标 + 一组必看指标 + 若干探索指标。指标来自注册表,不能现场拼字段。

SLOT 03

人群

全体、预定义分群、规则圈选或导入名单。必须显示人群版本、快照时间与预估人数。

SLOT 04

维度

用于拆分或过滤的属性。维度有层级、有时间语义(进组时 / 当前),不能混用。

SLOT 05

窗口

事件时间、进组时间、观察窗、归因窗。四个轴必须分别显示,不能只写「近 7 天」。

SLOT 06

方法

估计量、区间、CUPED、序贯、多重比较、最小样本。默认值即产品观点。

同一个画布可以保存成三种资产:

  1. 视图(View):个人或团队的默认布局与筛选,轻量、可改。
  2. 模板(Template):跨实验复用的口径组合,例如「一线城市 + 版本 ≥ 14 + 新用户」。DataTester 的自定义筛选模板就是这一层,实验级最多 10 个、应用级最多 50 个 来源。
  3. 决策记录(Decision Record):不可变快照 + 结论 + owner + 评论 + 后续动作。它不属于「视图」,而属于组织资产。

三者混在一起,是分析平台最常见的信息架构错误:用户以为自己在保存视图,其实在修改团队口径;或者以为自己在分享结论,其实分享的是一个会随数据更新的链接。

3. 自定义分析:从「选指标」到「定义分析」#

「自定义分析」通常被理解成「让用户自己选指标和筛选条件」。这只是一层。完整的能力应该分四级,每级对应不同的治理成本:

层级 用户可以自定义什么 典型交互 治理要求 适合谁
L1 过滤 时间、维度值、对比组 筛选 chips 口径不变,只变切片 所有业务用户
L2 人群 规则圈选、导入名单、分群复用 人群构建器 版本、快照、权限、样本量 运营、PM
L3 指标 事件、算子、分母、过滤、组合公式 指标构建器 owner、版本、血缘、置信度支持 数据/分析团队
L4 分析 维度组合、窗口、估计量、多重比较 分析画布 / DSL 方法白名单、成本配额、审计 DS、数据工程

多数平台只做到 L1-L2,然后把 L3-L4 留给 SQL。这看起来灵活,实际上把治理成本转嫁给了分析师:口径散落在 notebook 里,结论无法复现,指标无法跨实验复用。更好的做法是:L3 用注册表 + 构建器,L4 用受控 DSL,SQL 只作为逃生舱。

3.1 指标构建器:14 种算子,三个原子#

DataTester 的事件指标把「计算方式」产品化成了 14 种算子 来源。拆开看,它们其实是三个原子(count / sum / distinct)和四个分母(进组人数 AU、触发人数 UV、次数 PV、活跃天数 SUM(DAU))的组合:

算子 公式 回答的问题 是否支持置信度
人均次数 PV / AU 进组的人平均触发几次 是
转化率 UV / AU 进组的人里有多少人触发过 是
人均求和 SUM / AU 进组的人平均贡献多少金额/时长 是
人均日均 SUM / SUM(DAU) 活跃日均贡献 是
日均次数 PV / SUM(DAU) 每人每天平均几次 是
每次平均 SUM / PV 单次事件平均金额 是
人均触发人数 PV / UV 触发者平均触发几次 是
每次人均 SUM / UV 触发者平均贡献 是
总次数 PV 总量 否
总人数 UV 去重人数 否
求和 SUM 金额/时长总量 否
按属性去重 COUNT(DISTINCT prop) 例如按 session_id 去重 否
最新值人均 SUM(最新值) / AU 积分、等级等快照型指标 视实现
最早值人均 SUM(首非空值) / AU 首单金额、首充金额 视实现

「是否支持置信度」这一列比算子本身更重要。DataTester 明确说,PV、UV、SUM、按属性去重四类单指标不能计算置信水平;组合指标也只对特定分子/分母类型开放 来源。这不是产品缺陷,而是统计引擎的真实边界:方差必须从「每个用户一个值」的样本里估计,纯总量没有用户级分布。

建议 产品上不要把这些指标藏起来,而要显式标成「不可检验」。用户看到「总量 12.4 万,不可检验」比看到「总量 12.4 万,p=—」更不容易误读。更进一步,报告里应默认把「可检验指标」和「仅描述指标」分成两组,避免用户把不可检验的总量当成结论。

组合指标(CTR、CVR、PV/SUM)支持括号与四则运算,但同样有白名单 来源。比率指标最容易出错的地方是方差:设每人贡献 (y_i, x_i),比率 r = ȳ / x̄,Delta Method 的一阶近似是:

Var(r) ≈ (1 / (n · x̄²)) · [ Var(y) − 2r · Cov(y, x) + r² · Var(x) ]

分子分母相关时丢掉协方差项,会系统性低估方差;如果随机化单元是用户、分母是 session,必须先在用户级把分子分母各自求和,再套公式;如果是 cluster 随机化,要先在 cluster 级聚合。这些不是实现细节,而是「为什么两个平台对同一个指标给出不同 p 值」的常见原因。

3.2 指标治理:被引用之后不能改口径#

DataTester 的规则很硬:指标一旦被实验关注,只能改名称和描述,不能改口径,也不能删除 来源。这是一个正确的默认值:指标是实验结论的「法律条文」,不能在判决之后改法条。

但仅有「不能改」不够。一个完整的指标治理至少要有:

  • owner:谁对口径负责,出问题找谁;
  • 版本:每次变更生成新版本,旧实验继续引用旧版本;
  • 血缘:这个指标依赖哪些事件、属性、维表、上游指标;
  • 认证:哪些指标经过数据质量与统计校验,可以用于决策;
  • 下线状态:原表下线、事件废弃时,指标要自动标灰并通知引用方;
  • 迁移工具:新建指标后,如何把历史实验的引用迁过去,而不是让用户手工重跑。

Eppo 把「认证」与「可计算」分开:认证指标只读,且 funnel 类型不可认证 来源。这个设计值得借鉴:认证不是「算得对」,而是「可以被用于决策」。两者之间隔着数据质量、口径评审与 owner 签字。

3.3 筛选模板:口径复用的最小单位#

DataTester 的自定义筛选模板支持把一组筛选条件保存下来,在实验内或应用内复用;实验级最多 10 个、应用级最多 50 个 来源。这个功能看起来小,但它解决的是分析平台最普遍的问题:同一个人每次看报表都要重新点一遍相同的筛选;不同的人对「高价值用户」有不同定义。

模板的产品设计要注意三点:

  1. 模板必须带 owner、描述、创建时间与使用次数。没有 owner 的模板,半年后就是「祖传口径」。
  2. 模板只保存筛选条件,不保存结论。结论应该进决策记录,而不是模板。
  3. 模板要有作用域:个人 → 实验 → 应用 → 组织。作用域越大,审批越重。DataTester 用「实验级 / 应用级」两级,是一个务实的起点。

3.4 自由 SQL:要有,但不能是主入口#

DataTester 提供 SQL 自定义查询,范围限定在近一年,前端展示 1000 行、下载上限 100 万行 来源。这些限制不是产品小气,而是把「扫描分区数、返回行数、内存、超时」四个维度写成了可执行的闸门。

自由 SQL 的正确位置是「逃生舱」,不是「主入口」:

  • 必须走沙箱:只读、限库、限表、限分区、限并发;
  • 必须写回分析对象:SQL 查询的结果要能保存成受控指标或一次性分析,而不是散落在聊天窗口;
  • 必须显示成本:扫描量、预计耗时、结果行数,在提交前给用户看;
  • 必须审计:谁查了哪些用户明细、导出了多少行、是否包含敏感字段。

建议 把「自定义 SQL」放在高级分析的最后,而不是指标页的第一个按钮。默认路径应该是「选注册指标 → 选人群 → 选维度 → 看结果」,只有当用户明确需要新指标时才进入 SQL。

3.5 过滤器挂在哪一层,决定结论是不是同一个问题#

竞品拆解里最有价值的一条,不是「谁支持自定义指标」,而是过滤器挂在哪一层。同一个「只看 iOS」的筛选,挂错层会得到三个不同的数 来源 来源:

挂载层 改了什么 随机化还在吗 典型入口 风险
分配层 / 人群层 改分母:谁进入比较 在(只要用进组前变量) 实验受众、Segment、Variants Performed By 人群太小、覆盖率下降
指标事件层 只改分子:哪些事件算指标 在,但分子分母不是同一批人 指标事件的 Where / 属性过滤 比率指标分母不变,口径错位
指标定义层 改语义:指标怎么定义 取决于定义 指标构建器、metric slice 口径漂移,历史不可比
分析切片层 改分组/下钻 在,但比较次数膨胀 维度拆解、子群分析 多重比较、选择偏倚

Amplitude 的文档明确警告:给指标事件加国家过滤,分母仍然是全部曝光用户;正确做法是把过滤放到「Variants Performed By」 来源。GrowthBook 则把「用户属性」叫 dimension、「指标属性」叫 slice,并举例:同一用户跨国消费,dimension 会把全部消费算给首次国家,slice 只算该国部分 来源。两者都在说同一件事:「筛选」不是一个动作,而是四个不同的语义。

这也解释了为什么 Eppo 明确不对 segment 与 ad-hoc filter 计算 CUPED 来源:CUPED 的协变量与比较次数会随切片变化,平台宁愿不算,也不愿给一个看起来精确的错数。产品上应该把「这个筛选是否改变分母 / 是否参与校正 / 是否影响 CUPED」做成实时提示,而不是写在帮助文档里。

4. 圈定人群:最难的不是「圈」,而是「圈完之后」#

「圈定指定人群,看这批人的实验指标」听起来是一个筛选功能。实际上它同时踩在三个系统的交界处:标签/画像系统(这批人是谁)、分流系统(他们怎么进组)、统计引擎(这批人的差异是不是真的)。任何一处口径不一致,结论都会失真。

4.1 人群的五种来源#

来源 怎么定义 更新方式 ID 口径 最适合 主要风险
规则圈选 事件做过/没做过/依次做过 + 用户属性 + 时间窗 日更或手动 平台 uid / device_id 运营定向、子群分析 规则随时间漂移;事件回补导致人群变化
文件上传 CSV 名单(uid、ssid、device_id) 静态快照 上传文件指定 大客户名单、线下人群、holdout ID 映射丢失;名单过期;隐私合规
标签/画像 标签平台或 CDP 的预计算标签 标签平台调度 标签平台 uid 高价值、生命周期、兴趣偏好 标签定义不可见;更新延迟;跨平台 ID 不一致
行为序列 按事件顺序/次数/天数定义 日更 平台 uid 流失预警、路径人群 序列窗口与实验期重叠导致后处理
实验命中人群 某实验某版本的进组用户 实时/日更 实验 uid 父子实验、组合策略、holdout 父实验变更导致基准人群变化

DataTester 的用户分群支持规则圈选与文件上传,规则覆盖「做过 / 没做过 / 依次做过 / 用户是 / 用户不是」,支持 AND/OR 与嵌套;日更在每天 6 点计算前一天数据、8 点前完成,纯静态时间窗只能手动更新;单条规则的时间窗最长 365 天 来源。这些限制看起来是工程细节,实际上决定了人群能不能用于长周期实验。

4.2 规则模型:一棵树,而不是一行 SQL#

一个可维护的人群规则应该是一棵树:

{
  "cohort_id": "c_new_tier1_v3",
  "version": 3,
  "snapshot_at": "2026-10-20T06:00:00+08:00",
  "refresh": "daily",
  "root": {
    "op": "AND",
    "children": [
      { "type": "user_attr", "field": "is_new_user", "op": "=", "value": true },
      { "type": "user_attr", "field": "city_tier", "op": "in", "value": ["T1", "new_T1"] },
      {
        "op": "OR",
        "children": [
          { "type": "event", "event": "app_launch", "agg": "count", "window": "7d", "op": ">=", "value": 3 },
          { "type": "event", "event": "pay_success", "agg": "sum", "prop": "amount", "window": "30d", "op": ">=", "value": 100 }
        ]
      }
    ]
  }
}

这棵树要能编译成三种执行计划:SQL(明细扫描)、Bitmap(集合交并差)、标签查询(调用外部标签服务)。三种计划的结果必须一致,否则同一个分群在实验配置页和报告页会显示不同人数。

B 站的公开实践是把北极星、标签画像、AB 实验人群包都建在 ClickHouse 的 Roaring Bitmap 上 来源。好处是人群圈选、标签、行为分析共用一套编码与属性字典;代价是实验平台对上游依赖很重,字典服务或 ClickHouse 抖动会同时影响配置与人群包。腾讯微信的 BSI(Bit-Sliced Index)则把曝光、指标、维度统一编码成「分析单元 ID + 值」,让同一用户在所有 BSI 中位置一致,天然完成 Join 来源。两种路线都说明:人群不是一张名单,而是一种可复用的集合编码。

4.3 关键设计:先 hash 再过滤#

DataTester 文档里有一句非常关键的话:分流时,非白名单用户先做 hash 分桶,再做人群过滤 来源。更准确地说,是「层桶判定 → 人群过滤 → 实验桶/版本命中」:人群夹在层与实验之间,既不影响层内随机化,也不影响版本分配 来源。这意味着人群规则影响的是「谁有资格进入实验」,而不是「谁被分到哪个组」。

这个顺序带来四个后果:

  1. 处理分配仍然随机(在人群条件可测且实验前固定的前提下),人群内比较有效。
  2. 报告里的「进组人数」是过滤后的人数,不是桶内人数;圈了 10 万、报告只有 3 万是正常的,流量被浪费在人群外。
  3. 日更人群会让同一用户在实验期间进出人群;「进组不出组」要求一旦进组就保持版本,但用户被人群规则踢出后是否还算进组,公开文档没写,属于未知。
  4. 如果人群规则用了实验后的行为(例如「近 7 天未购买」),人群本身就被处理影响了,这是后处理偏倚,随机化救不了。

建议 产品上必须把「人群作用位置」做成一个显式选择,而不是藏在高级设置里:

AUDIENCE MODE / 两种作用位置必须在创建时锁定
实验人群 / 分流前改变谁进入实验影响 SRM 与外部有效性创建后不可改适合定向实验
分析人群 / 分流后不改变随机化只改变统计对象必须标探索性适合子群分析

很多自建平台把这两个概念混成一个「人群」字段,结果运营想定向、分析师想分层,用的是同一个入口。正确的做法是:实验人群在创建实验时锁定,分析人群在报告页随时可换,但换了之后必须重新做样本量与多重比较检查。

4.4 四个象限:什么时候人群分析是可信的#

把「人群定义时点」和「是否随机化」交叉,可以得到四个象限:

进组前定义(pre-treatment) 进组后定义(post-treatment)
随机化分配 ✅ 确证性子群:可以做交互检验、分层报告 ⚠️ 选择偏倚:只能做探索,不能做因果结论
非随机化 / 观察性 ⚠️ 观察性比较:需要倾向得分、DiD、敏感性分析 ❌ 基本不可解释:处理与选择同时作用

如果人群变量 B 在「处理 T → 结果 Y」的路径上(T→B→Y),条件化 B 估到的是直接效应,不是总效应;如果 B 同时受 T 和 Y 影响(T→B←Y),条件化 B 会打开一条非因果路径,这就是 collider/selection bias。此时即使 T 原本随机,B=1 的子群里也不再有交换性。最危险的是右下角,但业务上最常见的是右上角。比如:

  • 「圈出实验期点击过新卡片的用户,看他们的 7 日留存」——点击是处理的下游,点击组和未点击组的差异混合了处理效应与自选择。
  • 「圈出实验期停留超过 60 秒的用户,看转化率」——停留受处理影响,且与转化互为因果。
  • 「圈出完成下单的用户,看客单价」——这是条件于结果(collider),不是实验结论。
  • 「圈出近 7 天未活跃的用户,看召回效果」——如果实验本身影响活跃,人群被处理污染。

建议 产品上给人群规则加一个「时点校验」:凡是规则中引用的事件/属性时间窗与实验期重叠,就弹出提示「该人群可能受实验影响,结果将标记为探索性」。这不是阻止用户,而是让用户知道自己在做什么。

4.5 多重比较:20 次切片,64% 至少一个假阳性#

这是最需要产品化、却最常被忽略的一层。按独立检验粗算:

  • 5 个指标 × 4 个人群 = 20 次检验,至少一次 p<0.05 的概率约 64%;
  • 10 个指标 × 10 个人群 = 100 次检验,概率约 99.4%;
  • 如果再叠加 5 个变体,检验次数轻松上百。

还有一个常被忽略的陷阱:一个子群显著、另一个不显著,不能推出「两个子群的效应有差异」。正确做法是预注册少量子群,看处理 × 子群的交互项,而不是在每个子群里各跑一次检验 来源。这不是平台算错,而是「看得越多,越容易看到显著」。更麻烦的是事后定义:先看结果,再圈一个「高价值、低活跃、近 30 天没下单」的人群,等于把选择藏进了分析;校正只能覆盖登记过的检验,覆盖不了用户脑子里那条还没说出口的假设。

产品化的正确顺序是:

  1. 预注册:创建实验时声明主指标、预期方向、目标 MDE、分析窗口、预定义子群;任何修改生成新版本并标 post-hoc。
  2. 家族定义:主指标拿较宽的 α,次要指标用 BH 控 FDR,护栏用 Holm 控 FWER,子群先做交互检验而不是逐格检验。
  3. 默认校正:页面同时显示 raw p 与 adjusted p,默认按 adjusted 排序;当 adjusted 跨 0 而 raw 显著时,文案必须写「校正后不显著」,不能写「有趋势」。
  4. 探索降级:没有预注册的子群,结论只能写成「下一轮实验的假设」,不能写成「对某人群有效」。
  5. 复验:确证要靠新的实验——把人群放进分流,让「人群」成为随机化因子,而不是事后切片。

推断 DataTester 的差异分析与敏感人群文档没有说明多重比较校正口径。不能据此断言产品没有校正,但产品设计必须假设用户不会自己校正。GrowthBook 的做法可以作为参考:校正家族是 goals × variations × dimensions,维度切片单独校正 来源;它的结果页还会直接插入 SRM 与多重曝光警告 来源。

4.6 样本量:子群越小,结论越贵#

子群分析的第一道门槛不是显著性,而是样本量是否撑得起你想要的 MDE。一个粗略的直觉:

n per arm ≈ 16 · σ² / Δ²        (均值指标,α=0.05,power=80%)
n per arm ≈ 16 · p(1−p) / Δ²    (比例指标)

当子群只有几千人时,能检测到的效应往往比业务关心的阈值大一个数量级;此时「不显著」几乎不提供信息,「显著」则更容易是噪声。DataTester 的敏感人群文档建议进组人数大于 2 万、分析维度大于 4 个,并明确说样本不足时模型会不稳定 来源。这不是保守,而是经验阈值。

一条可落地的红线(建议,不是平台规则):每组 <100 人不读效应,只查埋点/bug;100–500 人只报方向与 CI;500–1,000 人可做探索性检验,必须标「未校正」;≥1,000 人且每格 ≥5 个事件,才做正式检验,并仍需 SRM + 多重比较。Uplift/敏感人群按官方建议 >2 万人、>4 维 来源。

产品上应该给每个子群自动算三件事:

  • 当前样本量 / 目标样本量;
  • 当前可检测的 MDE;
  • 置信区间宽度。

如果 MDE 大于业务目标提升,页面应该直接写「证据不足」,而不是「不显著」。这两句话对决策的含义完全不同:前者是「再等等/再扩样本」,后者是「大概率没效果」。

4.7 人群分析的八条准入检查#

时点

人群规则的时间窗是否完全落在实验开始之前?如果与实验期重叠,是否已标记为 post-treatment?

随机化

人群是在分流前还是分流后生效?分流后过滤是否保持了处理分配的随机性?

版本

人群是否有版本号与快照时间?报告是否显示「这批人是什么时候算的」?

样本

每个子群的样本量、MDE、CI 宽度是否足够?是否低于产品规定的最小样本?

多重比较

本次分析一共做了多少次检验?家族如何定义?adjusted p 是多少?

SRM

子群内的实际分配比例是否与设计一致?分维度 SRM 是否通过?

外部有效性

子群效应能否外推到全量?是否存在 SUTVA/溢出/组成变化?

行动

结论是「可以定向投放」还是「需要新实验复验」?是否已经写进决策记录?

4.8 数据模型与隐私#

人群服务的核心表至少要有:

表 关键字段 作用
cohort_def cohort_id, version, rule_json, owner, created_at, status 规则定义与版本
cohort_snapshot cohort_id, version, snapshot_at, uid_hash, segment_id 某次计算的成员快照
cohort_stats cohort_id, version, estimated_reach, overlap_json, refreshed_at 人数、重叠、刷新状态
cohort_audit cohort_id, action, actor, reason, ts 创建、修改、导出、删除的审计
experiment_cohort_binding experiment_id, cohort_version, stage(assignment/analysis), applied_at 明确人群在哪一步生效;stage=analysis 且规则含实验期事件时应拒绝或强制标探索

隐私上,人群包是最容易出事的资产:它可能包含敏感标签(未成年人、金融状况、健康状况)、可识别 ID、跨实验行为。至少要做到:

  • 敏感标签分级:高敏标签不进入人群构建器,或必须审批;
  • 导出审批:用户明细导出走审批流,默认脱敏、默认采样、默认限额;
  • 行级权限:只有被授权的人能看到某个人群包的成员列表,而不是只有聚合人数;
  • 用途绑定:人群包绑定用途(分析/投放/导出),跨用途需要重新授权;
  • 留存期限:静态人群包设置过期时间,避免「两年前的名单」被反复使用。

5. 下钻:从「知道」到「知道为什么」#

下钻是分析模块最容易被低估的部分。很多平台把它实现成「加一个 group by」,结果用户点开一个维度,看到 200 个值、每个值都没有样本量、显著性颜色乱跳,最后关掉页面。真正的下钻不是「拆得更细」,而是在保持对照与统计有效性的前提下,把结论定位到一个可行动的切片。

5.1 下钻的五个层级#

层级 用户的问题 典型交互 查询形态 必须保留的护栏
L1 指标 哪个指标动了? 指标表、指标卡 多指标聚合 指标版本、样本量、CI
L2 维度 动在哪个渠道/城市/机型? 维度切换、排序、TopN GROUP BY dimension 每切片 N、CI、多重比较状态
L3 维度值 这个渠道里,哪个城市在动? 点击柱状图、面包屑 带 filter 的 GROUP BY 上一层人数、当前层人数、占比
L4 人群 是某一类人吗? 人群叠加、交集、对比 cohort join + group by 人群时点、版本、重叠
L5 用户/事件 具体是谁?发生了什么? 用户列表、行为流、事件详情 明细查询 脱敏、采样、权限、审计

DataTester 的用户详情页提供了 L5 的样本:可以按 UUID/SSID 查用户,查看基础信息、设备、画像、按时间排序的行为流,支持按 App/设备/事件/属性过滤、重要事件高亮、CSV 下载(最长 30 天)来源。这是一个正确的方向:从聚合到个体,但个体视图是「诊断工具」,不是「结论工具」。用户列表不能用来证明效应,只能用来解释异常、复现问题、构造假设。

5.2 交互规范:下钻不是跳页#

一个可用的下钻交互,至少要满足八条:

  1. 面包屑可回退:全部用户 / 渠道=应用商店 / 城市=一线,每一级可点击,可清除。
  2. 对照锁定:无论下钻到哪一层,A/B 对照关系不变;不能出现「这一层只剩实验组」。
  3. 样本量常驻:每一层显示当前切片 N、基准 N、占比;N 低于阈值时灰显或折叠。
  4. 统计状态常驻:CI、p、校正状态、是否探索性,跟着切片走,而不是只在顶层显示。
  5. URL 可分享:当前实验、指标、人群、维度路径、时间窗、方法全部编码进 URL;分享给同事打开是同一个问题。
  6. 返回不丢上下文:从用户列表返回,仍停留在原来的切片,而不是回到顶层。
  7. 跨图联动可控:点击趋势图某一天、分布图某个区间,应该变成「时间/数值过滤」,而不是悄悄换指标。
  8. 「解释这个数」入口:每个数字旁边有口径、样本、查询耗时、数据截止时间,而不是只有 tooltip。

建议 把下钻做成「行内展开 + 右侧抽屉」的组合:维度拆解在指标行下方展开,用户明细在右侧抽屉打开。这样既保留上下文,又不需要在页面之间来回跳。

5.3 维度层级与高基数#

维度不是一堆字符串,而是有层级、有语义的对象:

  • 地理:国家 → 省 → 城市 → 区县;
  • 渠道:一级渠道 → 二级渠道 → 投放计划;
  • 版本:App 大版本 → 小版本 → 构建号;
  • 用户:新/老 → 活跃分层 → 生命周期阶段;
  • 设备:平台 → 机型 → 屏幕尺寸。

产品上要区分两种下钻:

  • 层级下钻(hierarchical):沿预定义层级逐级展开,适合地理、渠道、版本;每级自动带上父级过滤。
  • 任意拆分(ad hoc):用户任选维度组合,适合探索;必须限制维度数量与组合爆炸。

高基数维度是下钻的性能杀手。一个机型维度可能有 10 万值,一个 URL 维度可能上百万。可行的策略是:

  • TopN + 其他:默认展示 Top 20,其余聚合为「其他」,并明确标注;
  • 搜索 + 选择:不默认全量渲染,用户搜索后再查;
  • 最小样本阈值:低于阈值(如 100 人/组)的值折叠或灰显;
  • 预聚合:高频维度做 cube,低频维度走明细;
  • 近似:UV 可用 HyperLogLog/Bitmap 近似,但要在 UI 标注「近似值」。

DataTester 有一条很诚实的限制:属性分组之后,不支持切换 preAA 数据、查看数据分布和箱线图 来源。这大概率是因为分组查询走预聚合/cube 路径,原始用户分布不在 cube 里。这就是「预聚合换性能」的真实代价:产品文档比架构图更诚实。与其假装什么都能下钻,不如在 UI 上明确「这个视图在当前粒度不可用」,并给一个替代入口。

5.4 用户级下钻:能看到人,但不能带走人#

从聚合到用户,是分析模块最敏感的一步。产品上要默认「三不」:

  • 不默认展示全量:先给样本(如 100 条),需要更多再申请;
  • 不默认展示原始 ID:脱敏为 u_8f3a•••,需要原始 ID 走审批;
  • 不默认允许导出:导出是独立权限,带水印、限额、审计。

DataTester 的报告支持下载进组用户 ID(上限 500 万)来源,用户详情支持行为流 CSV 下载(最长 30 天)来源。这些能力对分析很重要,但必须与权限、审计、脱敏一起设计。否则「下钻」会变成「拖库」。

5.5 查询实现:预聚合、即席与混合#

下钻的性能取决于三个选择:

方案 怎么工作 优点 缺点 适合
全预聚合 提前算好所有维度组合的 cube 亚秒级、稳定 维度组合爆炸、无法回答临时问题 固定报表、核心指标
全即席 每次查询扫明细/宽表 灵活、口径统一 慢、贵、并发差 探索、长尾维度
混合 高频 cube + 低频即席 + 结果缓存 平衡 实现复杂、口径需对齐 大多数生产平台

一个务实的做法是「三级查询」:

  1. L1 缓存/预计算:固定报表、核心指标、常用切片,命中直接返回;
  2. L2 同步即席:单指标 + 单维度 + 有限时间窗,走 ClickHouse/Doris,目标 P95 < 2 秒;
  3. L3 异步任务:多指标 × 多维度 × 长窗口、用户明细导出,进队列,给进度与取消。

腾讯微信的公开论文给了一个极端的工程样本:Spark 例行预计算 + ClickHouse 即席下钻,BSI 运算经 JNI 调 SIMD;预计算负责 scorecard 与 CUPED,即席负责下钻 来源。这不是每个团队都能复制的,但它说明了一个原则:预计算与即席不是二选一,而是按查询模式分工。

缓存 key 必须包含所有影响结果的版本:hash(experiment_version, metric_version, cohort_version, dim_set, time_range, granularity, filter_hash, engine_version)。少一项,就会出现「改了定义但报表没变」的幽灵。

5.6 性能预算:下钻的速度决定分析的深度#

动作 目标 P50 目标 P95 超时策略
首屏结论 < 800ms < 1.5s 骨架屏 + 上次快照
指标切换 < 500ms < 1s 预取相邻指标
维度切换 < 800ms < 2s 缓存 + 取消旧请求
二级下钻 < 1.2s < 2.5s 异步 + 进度
用户列表 < 1s < 3s 采样 + 分页
导出 立即受理 异步 队列 + 通知 + 限额

这些数字不是拍脑袋:超过 2 秒,用户就会失去「连续探索」的感觉,退回「先想好问题再查」的模式;而分析的价值恰恰来自连续追问。性能预算应该写进 PRD,和功能一起验收。

5.7 六个下钻反模式#

  1. 把子群当结论:在 20 个切片里挑一个显著的,写成「对某人群有效」。→ 必须标探索性 + FDR。
  2. 下钻后对照组消失:某切片只剩实验组,仍然显示「提升」。→ 必须显示两组 N,缺一组就禁用结论。
  3. 维度值洪水:一次渲染 500 个机型,用户找不到重点。→ TopN + 搜索 + 最小样本。
  4. 口径漂移:下钻时换了指标定义/时间窗,用户不知道。→ 上下文条常驻 + 版本号。
  5. 缓存串租户:A 租户的查询结果被 B 租户命中。→ 缓存 key 带 tenant_id + 权限校验。
  6. 导出泄露:用户列表导出包含敏感字段/全量 ID。→ 脱敏、审批、水印、审计。

6. 高级分析:默认严谨,逐项解释#

高级分析的功能清单很容易做:CUPED、Uplift、序贯、贝叶斯、DiD、合成控制,每个名字都能变成一个菜单项。难的是另一件事:当用户点下这个菜单项时,平台是否替他承担了假设检查、多重比较、失败解释和决策责任。

6.1 产品化的四层接口#

LAYER 01

入口即契约

选方法前先问:随机化单元是什么、指标是比例/均值/比率/分位数、有没有可信的 pre-period、有没有 interference。不满足条件,方法不出现在可选列表里,而不是选完再报错。

LAYER 02

默认值即观点

CUPED 默认开、SRM 默认拦、多重比较默认按家族校正、序贯默认只用于监控。这些默认值直接决定用户看到的数字。

LAYER 03

结果即解释

每个数字带口径、窗口、样本量、CI、校正后的 p;每个失败态给出下一步动作,而不是一句「无显著差异」。

LAYER 04

成本可见

CI 会变宽多少、样本要膨胀多少、实验会慢几天,在选方法时就预估;不要等上线后才发现「高级方法」的代价。

6.2 方法菜单:每个方法回答什么问题#

方法 业务问题 关键假设 产品如何暴露 什么时候不该用
CUPED / 方差缩减 同样流量下更早看见小效应 pre 期协变量未被处理污染、与结果线性相关、同随机化单元 默认开;结果页并列「调整前/后」;显示实际方差缩减;新用户/分位数灰显 新用户无 pre 数据;pre 期被上一实验污染;分位数直接套用
CATE / HTE 对谁效果更大,能不能做定向 预注册子群;causal forest 需 honest splitting 先给交互检验 p,不逐格标星;默认收缩 + 区间;标「探索性」 整体不显著却扫 20 个子群;子群只有几百人
Uplift 给谁发券、推内容,增量最大 随机 T/C;特征在处理前;无 interference 独立任务向导;输出 TOP 敏感人群、特征重要度、ITE 分箱下载;要求样本外验证 进组 < 2 万;无随机对照;用 post-treatment 行为做特征
序贯 / always-valid 天天看报告,想早停又不想膨胀假阳性 alpha spending 或 mSPRT;看点/参数揭盲前固定 监控区间与「宣布胜利」分开;CI 变宽时解释「为随时可停付费」;早停提示效应高估 事后改看点;拿早停效应量做收益预测
贝叶斯 小样本、决策者要概率和损失 先验 + 似然;同随机化单元的 i.i.d. 或已聚合 先验卡片写清来源/尺度;CTW 与期望损失双读数;先验敏感性三档 没有历史先验却拍强先验;把贝叶斯当 peeking 免死金牌
多重比较 多指标、多变体、多切片下控制假阳性 检验家族在揭盲前定义 自动登记家族;显示「本页 N 次检验」;raw p 与 adjusted p 并列 把探索性切片当确认性结论;家族事后扩大
SRM 分流、埋点、管道是不是坏了 卡方检验;低 α(0.001/0.0005) 每次刷新自动跑;红条 + 隐藏 treatment effect;按端/版本/国家下钻 用重加权「修复」样本;只看 p 不看绝对偏差
Cohort / Retention 策略是否改变长期留存 按首次进组日分 cohort;观察窗成熟 热力图 + 按进组日拆分;未成熟 cohort 灰显 7 日留存只看 3 天;跨 cohort 直接比
Funnel 哪一步流失,策略改善了哪一层 UV 口径;曝光作为第 0 步;转化窗口 漏斗图 + 每层转化率/流失;版本对比给 CI 步骤可跳过/无序;逐层各做一次检验却不校正
DiD 无法随机化时,用 pre-trend 构造反事实 平行趋势、无同期冲击、处理外生、多期 pre 强制画 pre-trend 与 placebo;输出 ATT 而非 ATE 平行趋势不成立;只有 1 期 pre
Synthetic Control 单个城市/市场的长期效应 donor 池足够、pre 期拟合好、无同期政策 权重表 + 拟合图 + placebo 分布 donor 太少或被污染
MAB 多版本动态分配流量,最大化累计收益 Thompson/UCB;自适应分配破坏 i.i.d. 与 A/B 分开的实验类型;显示「优化」而非「因果」;不提供 p 值 需要无偏 ATE;看长期效应;护栏指标

这张表最重要的不是「支持多少方法」,而是「什么时候不该用」。一个方法如果只能在满足假设时使用,产品就必须在入口处做检查,而不是在结果页写一行免责声明。

6.3 CUPED:默认开,但要说清代价#

CUPED 的逻辑很简单:用实验前的协变量 X 解释实验期的 Y,把「本来就会不同」的部分减掉:

Y_adj = Y − θ · (X − X̄)
θ = Cov(Y, X) / Var(X)
方差缩减 ≈ ρ²

产品上最容易犯的错,是只给一个「CUPED 已开启」的开关,不给用户看:

  • 用了哪段 pre 期?pre 期是否被上一个实验污染?
  • 协变量与当前指标的相关性是多少?实际方差缩减了多少?
  • 新用户没有 pre 数据,是否被排除?排除后样本量变化多少?
  • 分位数/比率指标是否直接套用了均值 CUPED?

建议 结果页并列显示「原始」与「CUPED」两套数字,并给出方差缩减比例;当 CUPED 改变结论方向时,强制提示「结论对协变量调整敏感」,而不是只展示调整后的漂亮区间。Eppo 的文档把 CUPED 的假设、协变量选择与实现讲得比较清楚 来源,可以作为产品文案的参考。

6.4 Uplift / CATE:从「找人群」到「验证人群」#

Uplift 的产品价值不在模型,而在交付:一群人、一个方向、一个可执行的名单。DataTester 的敏感人群洞察把这件事做成了完整工作流 来源:

  • 任务粒度是「一个指标、一个实验组、一个对照组」;
  • 挖掘方向分正向/负向;
  • 输出 TOP 敏感人群、特征重要性、TOP 3 特征的二维交叉子群;
  • 支持下载人群明细(treatment、uid、ite、bins、业务 ID)。

但它也暴露了 Uplift 的典型风险:

  • 推荐入组人数 > 2 万、维度 > 4 个,否则模型不稳定;
  • 子群是「TOP 特征交叉」选出来的,存在选择偏倚;
  • 公开文档没有说明子群 p 值是否做多重比较校正,产品上应按「未校正」处理;
  • ITE 是模型预测,不是个体真实因果效应;
  • 下载名单用于全量投放前,应该做 holdout 验证。

建议 产品上把 Uplift 放进「探索」层,把验证放进一个新的 confirmatory 实验:用 Uplift 选出人群 → 设计一个只看这批人的 A/B → 用 holdout 验证增量 → 再决定是否全量。这个闭环比「模型 AUC 很高」更有说服力。

6.5 序贯与贝叶斯:让「随时看」不再等于「假阳性」#

实验平台最常见的用户行为是「每天打开报告看一眼」。在固定样本频率派框架下,这会让一类错误膨胀;序贯检验/always-valid 就是为这个场景设计的。产品上要区分两件事:

  • 监控:每天看趋势、护栏、SRM,不宣布胜负;
  • 决策:达到预定义样本/时间后,用固定样本或序贯的正式区间做结论。

如果平台支持「随时可停」,就必须同时支持:

  • alpha spending 或 confidence sequence;
  • 预定义看点与参数锁定;
  • 早停时的效应量高估提示;
  • 多指标/多版本的额外校正。

贝叶斯则是另一条路:给决策者「获胜概率/期望损失」,而不是 p 值。它的产品难点在先验:没有历史数据却拍一个强先验,比不做贝叶斯更危险。Eppo 对贝叶斯与频率派方法的对比写得比较克制 来源,可以作为术语与文案的参考。

6.6 多重比较:先定义家族,再谈显著性#

多重比较不是「把 p 值乘一个数」那么简单。产品必须先帮用户定义「家族」:

  • 一个实验里的所有变体 × 所有指标,是一个家族;
  • 一个指标下的所有维度切片,是另一个家族;
  • 护栏指标应该单独一个家族,用更严的 FWER;
  • 子群应该先做交互检验,而不是逐格检验。

常见方法:

  • Bonferroni:α/m,保守但简单;
  • Holm:逐步法,比 Bonferroni 有更高功效;
  • BH:控制 FDR,适合探索性指标多、但可以接受少量假阳性的场景。

建议 默认策略:主指标 preferential α,次要指标 BH,护栏 Holm,子群先交互。界面同时显示 raw p 与 adjusted p,默认按 adjusted 排序;当 adjusted 跨 0 而 raw 显著时,文案必须写「校正后不显著」,不能写「有趋势」。

6.7 为什么「自定义人群 + 高级方法」最容易产生假阳性#

三个乘数叠在一起:

  1. 人群定义的自由度:年龄、城市、活跃度、价格敏感、生命周期……可以切出无数个子群;
  2. 指标的自由度:5 个指标 × 4 个人群 = 20 次检验,至少一次假阳性的概率约 64%;
  3. 方法的自由度:CUPED 开/关、贝叶斯先验、序贯看点、异常值处理,每一种都能改变结论。

更麻烦的是事后定义:先看结果,再圈一个「高价值、低活跃、近 30 天没下单」的人群,等于把选择藏进了分析。校正只能覆盖登记过的检验,覆盖不了用户脑子里那条还没说出口的假设。

LLM 会把这条乘法器再放大一次:让模型扫描所有切片、挑出「最值得讲」的三个,再写一段原因,等于把数据挖掘自动化。每一句听起来合理的解释,背后都可能是一个未登记的检验。

6.8 方法选择决策表#

实验场景 样本量 指标类型 有 pre-period 有 interference 首选 不要用
用户级 A/B,常规迭代 充足 比例/均值 有 无 CUPED + 固定样本/序贯监控 + Holm/BH + SRM 门禁 无 pre 硬开 CUPED;多指标不校正
用户级 A/B,小流量 不足 比例 无 无 贝叶斯弱先验 + 预注册 + 延长实验;先算 MDE 扫子群找显著;强先验
多版本/多指标 充足 混合 有 无 主指标 preferential α,次要 BH,序贯只做监控 每个变体各做一次 5% 检验
子群/个性化 视子群而定 均值/比例 有 无 预注册子群 + 交互检验;样本足够才上 causal forest 整体不显著后扫 20 个子群
长期留存/LTV 充足 留存/金额 有 可能 Cohort + Holdout;看成熟窗口 用首日/3 日数据下结论
无法随机化(城市/市场) 少 均值 有多期 可能 DiD(平行趋势成立)或 Synthetic Control 平行趋势不成立还硬做 DiD
双边市场/社交网络 充足 均值/比例 有 有 Cluster randomization 或 Switchback 用户级 A/B + 普通方差
排序/推荐 中等 偏好/点击 无 同用户内 Interleaving 预筛,再接 A/B 确认 直接用 interleaving 做 ship 决策
短活动/高机会成本 中等 单目标 无 无 MAB 做流量优化 用 MAB 要无偏 ATE 或护栏结论

6.9 LLM 在分析模块里的可信边界#

LLM 在实验分析里能做三层,可信度依次下降:

  • 叙述层:把已经算好的结果翻译成业务语言。安全,前提是数字只能来自结果对象。
  • 诊断层:提示 SRM、MDE 不足、cohort 未成熟、样本低于门槛。较安全,因为规则可审计。
  • 归因层:解释「为什么涨」。不安全。实验识别的是效应,不是机制;机制要靠埋点、日志、访谈和后续实验去验证。

产品规则可以写得很硬:

  1. 数字白名单:只允许引用结果对象里的字段;每个数字带 cell 链接;没有计算就写「未计算」,不许估。
  2. 拒绝条件:SRM 未过、样本低于门槛、CI 跨 0、校正后不显著时,不允许生成「获胜原因」。
  3. 归因措辞:只能写「可能机制(待验证)」,并列出还需要什么证据;不能写「因为 X 所以 Y」。
  4. LLM 提议的切片就是新的检验:必须登记、校正,或放到 holdout 上验证;否则就是自动化 data dredging。
  5. 评估与审计:用历史实验的已知结论做回归测试;记录模型、提示、上下文、版本;上线决策必须有人签字。

字节在 AICon 2024/2025 的公开演讲里提到,用 LLM 做实验分析提效、实验咨询与分析智能体 来源 来源。这是方向,不是交付证据。对产品团队的含义是:LLM 应该先做「叙述 + 诊断」,不要把「归因」当成默认能力;否则它会用最流畅的语言,放大最脆弱的统计结论。

7. 页面设计:一张分析页的解剖#

分析页不是「数据展示页」,而是「决策证据页」。四类用户不是四种并列视图,而是同一条证据链上的四个检查点:

角色 JTBD 首屏必须回答 最怕的失败
PM 决定是否上线 这版能不能上?大概多多少?有没有踩护栏? 把「不显著」当「无效果」;只看相对提升
DS 为效应背书 效应可信吗?证据够吗?哪个子群在动? 只看 p 值;切片多重比较;口径被改过不知道
数据工程 保障口径与性能 这个数怎么算?何时更新?为什么慢或为空? 同名不同义;漏斗改动回溯影响所有实验
管理者 组合决策 哪些该上、哪些该停、整体风险如何? 单实验视角;没有决策记录;赢家诅咒

7.1 首屏:只回答「要不要动」#

ANALYSIS / WIREFRAME v1
NAV结论
指标
人群
下钻
高级
诊断
CONTEXT实验名
状态
owner
数据截止
指标 v3
VERDICT建议上线 / 证据不足
主指标 +3.2%(CI 1.1~5.4)
N=82,140 / 82,003 · 护栏 4/4
GUARDRAIL STRIP崩溃率 —|支付失败 ↑0.02pp(未越界)|退款率 —
METRIC TABLE核心 1|必看 4|探索 12
指标 · 基准 · 绝对差 · 相对差 · CI · 状态
行内展开:趋势 / 分布 / 箱线 / 维度拆解
FILTER / COHORT[新用户 ×] [iOS ×] [+ 筛选] [模板▾] N −12%
DIAGNOSTICSSRM p=0.42|曝光/进组 98.7%|10-21 06:12 重算
DRILL DRAWER渠道 / 城市 / 机型
面包屑 · 每层 N · CI
用户样本(脱敏)
查询耗时 / 缓存
EVIDENCE口径卡
方法卡
版本历史
评论 / 决策记录
左:导航与上下文|中:结论、指标、筛选、诊断|右:下钻抽屉与证据。首屏不放下钻明细,避免抢结论的注意力。

首屏的权重顺序是:结论 > 护栏 > 核心指标 > 证据入口 > 诊断。图表回答「怎么变」,首屏要回答「做不做」。DataTester 把结论放在实验概览区,并用颜色标显著方向 来源;但「建议」应该由实验 owner 写,系统只给证据。这个分工很重要:平台不能替组织做决策,但必须让决策所需的信息在 5 秒内可见。

7.2 关键组件:每个组件都在回答一个反驳#

组件 要回答的反驳 设计要点 代价 / 边界
结论卡 凭什么这么说? 一句话结论 + 主指标 + 绝对/相对效应 + CI + N + 证据等级 一句话必然压缩信息,必须可展开到证据
指标表 还有哪个指标在动? 一行一指标;核心/必看/探索分组;冻结首列;N/基准/绝对差/相对差/CI/p/MDE 列多,小屏不可用,需卡片降级
CI 条 效应最小可能多少? 0 线、95% 区间、两端数值、N;轴不截断 非统计用户会读成「保证范围」
显著性标记 真显著还是错觉? 颜色 + 图标 + 文字(显著正向/负向/不显著/不可检验) 颜色失效即信息失效
趋势/分布 何时开始变、是否极端值拉动? 累计曲线 + 区间带;标注日级不含今天;箱线显示重叠面积 CVR 不支持箱线;小时/分钟无箱线
维度拆解 对谁有效、对谁有害? 每切片 N/CI/方向;标「探索性/未校正」;限制切片数 切片越多假阳性越多
人群构建器 这批人怎么来的、有多新? 规则/文件、预估人数、更新频率、口径预览 静态群手动更新;属性取最新值
查询/空错态 它在跑吗?下一步做什么? 2 秒内骨架;长任务分阶段进度/取消/保留上次结果;空态给原因 + 入口 异步任务可能 10 分钟–2 小时
证据抽屉 这个数怎么算的? 指标定义、分母、窗口、版本、owner、查询指纹 信息密度高,默认折叠

DataTester 有一个值得警惕的细节:PV、UV、SUM、去重数这类指标不支持置信水平计算 来源。它们可以出现在表里,但必须标「不可检验」,否则用户会把「没有 CI」当成「没有差异」。

7.3 信任设计:让数字可被质疑#

  • 口径卡,而不是 tooltip:指标配置里本来就有「指标描述」字段,要求写清含义、计算逻辑、用途 来源。报告页应把它升级为可引用的定义卡:分母、时间窗、归因、排除规则、版本、owner。
  • 样本量拆三层:进组、曝光、有效样本。只给一个 N,SRM 无法判断。DataTester 的进组数当天实时、次日起 T-1、以 0 点为界 来源。
  • SRM 与护栏:DataTester 公开报告文档没有 SRM 状态(证据缺口)。GrowthBook 在结果页直接插入 SRM 与多重曝光警告,SRM p<0.001,并写明「不应相信结果」来源。建议做成硬 gate:异常时置顶诊断、隐藏效应、只留样本与排查入口。
  • 探索性标记:差异分析用 Monte Carlo 给「获胜概率」来源,敏感人群是 Uplift 挖掘 来源;这些是探索,不是确认。UI 要标「探索性、未校正、需独立复现」。
  • 多重比较提示:页面显示「本页 24 指标 × 6 切片」;提供 BH/Holm 或 adjusted p。GrowthBook 的校正家族是 goals × variations × dimensions,维度切片单独校正 来源。
  • 变更历史:漏斗任何修改都会更新所有使用它的实验报告,且不缓存 来源——这是典型的静默变更。建议版本化 + 「报告已重算」横幅 + 变更 diff。
  • 评论与批注:公开文档未见(证据缺口)。建议锚定到指标/切片,@owner、resolve、写 decision log;评审用不可变快照,而不是实时页。

7.4 空态、加载态与错误态#

分析页的失败,大多不是「算错」,而是「用户不知道发生了什么」。三种状态要写清楚:

状态 不要这样写 应该这样写 下一步
空态:无数据 「暂无数据」 「该人群在所选时间窗内没有曝光;可能原因:人群圈选过窄 / 实验未开始 / 埋点延迟」 放宽时间窗 / 查看分流诊断 / 联系 owner
空态:样本不足 「不显著」 「当前每组 1,240 人,只能检测 ≥ 8.2% 的效应;业务目标是 2%」 延长实验 / 扩大流量 / 降低 MDE 预期
加载:长查询 转圈 「正在扫描 3 个分区,预计 18 秒」+ 取消 + 保留上次结果 等待 / 取消 / 查看缓存版本
错误:查询失败 「系统错误」 「查询超时(>30s);已缩小到近 7 天,可重试或导出异步任务」 重试 / 缩小范围 / 异步
错误:口径变更 「数据已更新」 「指标 v4 于 10-20 变更:分母从 UV 改为 AU;本报告已重算,历史结论可能不可比」 查看 diff / 用旧版本重跑

7.5 可访问性与响应式#

  • 键盘:指标表用 grid 模式,roving tabindex,方向键移动,Enter 展开,Esc 关闭 来源。DataTester 的交互是 hover 出解读、点击出统计卡 来源;hover-only 必须补 focus/click 等价物。
  • 色彩不是唯一编码:DataTester 用绿/红/黑编码显著性 来源,WCAG 1.4.1 要求颜色不能是唯一手段 来源。加箭头、图标、文字,灰度打印仍可辨。
  • 对比与焦点:文本 4.5:1、UI 3:1、焦点可见;触控目标至少 24×24(WCAG 2.2)。
  • 表格小屏降级:≥1280 全列;768–1279 隐藏绝对差/MDE,保留相对差 + CI;<768 一行一卡(指标名、效应、CI、状态),点开底部抽屉;首列 sticky,横向滚动给阴影提示。
  • 图表替代:提供「表格视图」与文字摘要;异步完成用 aria-live 播报,不要只靠 toast。
  • 移动端:只保留「结论 + 核心指标 + 护栏 + 审批」;下钻与高级分析引导到桌面,而不是硬塞进小屏。

7.6 六条可用性验收标准#

  1. 5 秒结论:80% 目标用户不滚动即可说出「上/不上/证据不足 + 主指标方向 + 是否过护栏」。
  2. 三重编码:任一显著性标记在灰度与色盲模拟下仍可区分;颜色、图标、文字同时存在。
  3. 键盘闭环:从实验列表到展开统计卡 ≤ 6 次 Tab/方向键;无 hover-only 信息;焦点始终可见。
  4. 口径可追溯:任一数字 2 次点击内看到定义、分母、时间窗、版本、最后更新;口径变更后出现「已重算」提示。
  5. 状态可解释:查询 > 2 秒有阶段进度与取消;失败保留上次结果并给原因与重试;空态给下一步入口。
  6. 切片不静默:任何筛选/分组后同时显示 N 与基准 N;探索性结果带「未校正」标记;页面显示「指标数 × 切片数」。

8. 技术实现:语义层、查询与统计#

分析模块的工程难点不是「把 SQL 跑快」,而是让同一个业务问题,在实验组与对照组、今天与上周、整体与下钻之间,被编译成同一套可复现的查询。

8.1 逻辑架构:六个平面#

ANALYSIS ARCHITECTURE / 逻辑分层控制面 / 分析面 / 数据面
体验层结论卡指标表人群构建器下钻抽屉高级分析导出/API
分析服务分析编排查询编译统计引擎结果缓存权限/审计
语义层实验元数据指标注册表人群服务维度/属性服务方法注册表
计算层查询队列预聚合任务异步任务资源组/配额
存储层曝光宽表指标明细人群 Bitmap结果快照审计日志
治理层指标认证口径指纹数据质量成本核算合规

这六层的失败模式各不相同:元数据错会串组,指标错会口径漂移,人群错会人口漂移,维度错会把「当前属性」当成「进组时属性」,缓存错会串租户,治理缺失会让错数无法追溯。架构图的价值不是好看,而是让每一层都有明确的 owner 与可观测指标。

8.2 指标 DSL:七个槽位#

一个实验指标 DSL 至少要有七个槽位:事件、聚合算子、分母、过滤、时间窗、归因窗口、去重键。

{
  "metric_id": "gmv_per_entrant_7d",
  "version": 4,
  "entity": "user_id",
  "numerator": {
    "agg": "sum",
    "event": "pay_success",
    "property": "amount",
    "filter": [{ "property": "currency", "op": "=", "value": "CNY" }],
    "dedup": { "key": "order_id" }
  },
  "denominator": { "type": "entrants" },
  "window": { "anchor": "exposure", "length": "7d" },
  "attribution": { "event_time": "server_received_at" },
  "owner": "growth-data",
  "certified": true,
  "stat_support": ["delta_method", "bootstrap"]
}

DataTester 把前三个槽位产品化成了 14 种「计算方式」来源。拆开看,14 种其实是 3 个原子(count / sum / distinct)× 4 个分母(AU、UV、PV、SUM(DAU))× 时间语义。分母才是灵魂:同样是「支付转化」,UV/AU 问的是「进组的人里有多少人付过」,PV/UV 问的是「付过的人平均付几次」,两者不能互相解释。

置信度支持矩阵是 DSL 的一部分,不是 UI 的补丁。DataTester 明确列出,总量(PV)、总人数(UV)、求和(SUM)、按属性去重四类单指标不能计算置信度;组合指标也只对特定分子/分母类型开放 来源。推断:这不是产品偷懒,而是统计引擎的真实接口——方差必须从「每个用户一个值」的样本里估计,纯总量没有用户级分布。所以编译器必须先把任何指标降成「每人一行 (num, den)」,再由统计层聚合。

8.3 查询编译:从请求到充分统计量#

一个分析请求是一个五元组:experiment × metrics × cohort × dimensions × time。编译器做七件事:

  1. 取实验版本与 variant 映射;
  2. 展开指标为 (numerator, denominator, filter, window);
  3. 下推人群(join 快照或 bitmap);
  4. 解析维度(字典表或 argMax 取时点值);
  5. 生成用户级 CTE;
  6. 生成聚合查询;
  7. 交给统计层。

编译后的伪 SQL 大致如下。注意三个细节:variant 只做列不做表、分母恒为 1 且用 LEFT JOIN、结果返回二阶矩而不是一个数。

WITH ent AS (
  SELECT user_id, variant, min(exposure_time) AS t0
  FROM exposure
  WHERE exp_id = 'exp_1024' AND exp_version = 7
    AND dt BETWEEN '2026-09-01' AND '2026-09-30'
    AND user_id IN (
      SELECT uid FROM cohort_snapshot
      WHERE cohort_id = 'c_88' AND cohort_version = 20261018
    )
  GROUP BY user_id, variant
),
per_user AS (
  SELECT e.user_id, e.variant, d.country,
         sumIf(p.amount, p.event = 'pay_success'
               AND p.event_time >= e.t0
               AND p.event_time <  e.t0 + INTERVAL 7 DAY) AS num,
         toUInt8(1) AS den
  FROM ent e
  LEFT JOIN events p
    ON p.user_id = e.user_id
   AND p.dt BETWEEN '2026-09-01' AND '2026-10-07'
  LEFT JOIN dim_user d ON d.user_id = e.user_id
  GROUP BY e.user_id, e.variant, d.country
)
SELECT variant, country,
       sum(num) AS num_sum,
       sum(den) AS den_sum,
       count() AS n,
       sum(num * num) AS yy,
       sum(den * den) AS xx,
       sum(num * den) AS xy
FROM per_user
GROUP BY variant, country;

最后三列是「二阶矩」,它们让统计层不必回表就能算方差与协方差。这是语义层与统计层之间最重要的接口契约:查询结果不是「一个数」,而是一组充分统计量。

保证两组同口径,靠四条硬规则:

  • variant 只做列不做表;
  • 分母固定为进组人数且每人计 1;
  • 归因窗口锚定各自的进组时间 t0;
  • 所有过滤条件同时作用于分子与分母。

DataTester 的漏斗给了正面样本:漏斗不要求单独配置曝光,但计算时会把曝光事件当作第一步之前的过滤事件,且曝光自带实验版本 VID 来源。组的定义与指标同源,避免了 assignment 表 join 的丢失与串组。

8.4 存储选型:三种负载,不可能一个引擎全吃#

引擎 最擅长的「那一刀」 代价与边界 适合 / 不适合
ClickHouse 单表宽表 + 预聚合;Bitmap 精确 UV 增量物化视图只处理新写入块,历史重算要另建链路;JOIN 需宽表/小表广播 曝光宽表、实时护栏、私有化单链路;不适合频繁更新维表与复杂多表即席
Doris 聚合/主键模型,物化视图透明改写,固定模板并发好 改写依赖优化器与 MV 设计;维度组合仍被预聚合锁死 报表模板稳定、租户多的 SaaS;不适合长尾即席
StarRocks 主键模型 + 异步物化视图,多表 JOIN 聚合 内存与运维成本高;MV 刷新有延迟窗口 星型模型、指标多而维度相对固定
BigQuery / Snowflake 存算分离,按扫描量计费,回填/审计/共享友好 交互延迟与成本随扫描量上升;物化视图能力受限 决策口径与历史回填;不适合亚秒拖拽
Druid 摄入即 roll-up + 近似算法,亚秒看板 不支持按主键低延迟更新,不擅长大表 JOIN 实时健康度与 SRM 护栏;不适合财务对账与复杂归因

预聚合有三件套:Bitmap 做 UV(交并差快,但高基数会膨胀,且回答不了「这些人是谁」);BSI 做金额求和与分位数(需 bucket 编码,精度换空间);物化视图做固定维度组合(查询改写依赖优化器)。一条容易犯的错:不要把比率的比值存进 cube,只存分子和分母,查询时再除;否则跨天、跨维度合并时权重就错了。

维度组合是 2^N,全预聚合必然爆炸。现实做法是「高频维度做 cube + 任意维度现算明细」。DataTester 有一条很诚实的限制:属性分组之后,不支持切换 preAA 数据、查看数据分布和箱线图 来源。推断:分组查询走的是预聚合/cube 路径,原始用户分布不在 cube 里,所以分布类视图只能关闭。这就是「预聚合换性能」的真实代价。

8.5 API 与数据模型#

一个最小可用的分析 API 可以只有六个端点:

方法 路径 作用 关键参数
POST /v1/analyses 创建分析(保存画布) experiment_id, metric_set, cohort, dimensions, window, method
POST /v1/analyses/{id}/run 执行分析 mode=sync/async, cache=auto
GET /v1/analyses/{id}/result 取结果 run_id, include=warnings,evidence
POST /v1/analyses/{id}/drill 下钻 path[], filters{}, limit
GET /v1/cohorts/{id} 人群元数据/预估人数 version
POST /v1/exports 导出(异步) analysis_id, format, row_limit, reason

核心表至少要有:

表 关键字段 作用
exp_assignment exp_id, version, uid, variant, bucket, assigned_at 分流事实
exp_exposure exp_id, version, uid, variant, exposure_at, context 曝光事实(归因锚点)
metric_def metric_id, version, dsl_json, owner, status, certified 指标定义
cohort_snapshot cohort_id, version, snapshot_at, uid_hash 人群快照
analysis_run run_id, analysis_id, query_hash, data_cutoff, status 运行记录
analysis_result run_id, cell_key, num, den, n, yy, xx, xy, warnings 充分统计量
analysis_audit run_id, actor, action, reason, ts 审计

8.6 性能、成本与可观测性#

按复杂度分四级:

  • L1 已预计算的固定报表:缓存命中,亚秒;
  • L2 单指标单维度:秒级,同步;
  • L3 多指标多维度/长窗口:十秒到分钟,异步任务;
  • L4 自定义 SQL 与导出:队列 + 配额 + 审批。

只有 L1/L2 值得优化,L3/L4 应该「排队并告知」,而不是让所有人一起拖垮集群。

缓存 key 必须包含所有影响结果的版本:hash(experiment_version, metric_version, cohort_version, dim_set, time_range, granularity, filter_hash, engine_version)。少一项就会出现「改了定义但报表没变」的幽灵。

可观测性要回答的不是「查询慢不慢」,而是「数字为什么变了」。至少四类信号:

  • 查询日志:query_id、SQL 指纹、扫描行数、缓存命中、租户;
  • 慢查询:按模板聚合,而不是按单条 SQL;
  • 口径异常:分母为 0、UV 大于进组人数、比率大于 1、某维度值单日突增;
  • 结果 diff:同 query 重跑、新旧指标版本、实时与离线对账。

建议 把编译后 SQL 的哈希作为「口径指纹」写进结果表,报表页可展示。这样任何数字都能回答「它是用哪版定义、哪版人群算的」。权限上,指标的可见性与行的可见性要分开;共享缓存和导出文件是最容易被忽略的越权泄漏点。

8.7 三个阶段:MVP、规模化、智能化#

MVP / 0–6 个月
能复算
Postgres 元数据 + 单机 ClickHouse + T+1 批处理;不做缓存
规模化 / 6–18 个月
能并发
拆编译/统计服务;队列、缓存、cube、租户资源组、审计
智能化 / 18 个月+
能解释
异常归因、自动下钻、Uplift/HTE、自然语言转 DSL

MVP 的目标不是快,而是「每个数字都能手工复算」。此时最重要的交付物是 DSL 和一张指标契约表,而不是引擎。智能化的底线是:自然语言只能生成 DSL,不能直写 SQL——否则前面所有的版本、权限、口径指纹全部失效。

9. PRD:P0/P1/P2 与验收#

9.1 范围与不做什么#

做:一个实验分析工作台,支持结论、指标、人群、下钻、高级分析五个面;支持自定义指标、人群圈选、筛选模板、维度下钻、CUPED/序贯/多重比较;提供 API 与审计。

不做(至少第一年):不做通用 BI;不做全量 SQL 编辑器;不做自动投放;不做跨实验的因果网络;不做无审批的用户明细导出。

9.2 需求优先级#

P0 · 契约
分析对象与版本契约Experiment / Analysis / Metric / Audience / Dimension / Method / Result 七个对象;六个版本号进请求;口径指纹入结果表。
没有它,后面所有功能都不可复现。
P0 · 结论
结论卡 + 指标表 + 证据带首屏给建议、主指标、绝对/相对效应、95% CI、N、护栏状态、数据截止时间;指标表支持核心/必看/探索分组。
80% 的用户只看首屏;首屏不可信,平台就没有存在感。
P0 · 指标
指标注册表与构建器14 种算子、组合指标、过滤、时间窗、去重键;不可检验指标显式标记;被引用后锁定口径。
指标是分析的法律条文,不能现场拼。
P0 · 人群
人群构建器与两种作用位置规则/文件;AND/OR 嵌套;预估人数;日更/手动;分流前 vs 分流后模式;时点校验。
人群是分析的一等对象,也是因果风险的最高发区。
P0 · 下钻
维度下钻与用户样本维度切换、面包屑、每层 N/CI、TopN + 其他、用户样本脱敏、导出审批。
从「知道」到「知道为什么」的关键一步。
P0 · 护栏
SRM、护栏、口径卡、诊断每次刷新自动 SRM;必看指标继承;数据截止/版本/owner;分流诊断入口。
信任来自可见的失败;隐藏异常比异常本身更伤。
P0 · 工程
查询编排、缓存、权限、审计同步/异步分级;缓存 key 含全部版本;租户隔离;行级权限;导出审计。
没有这些,性能与合规会在规模化时同时爆雷。
P1 · 复用
筛选模板、保存视图、分享链接实验级/应用级模板;owner/描述/使用次数;URL 编码全部上下文。
口径复用的最小单位,也是团队协作的起点。
P1 · 统计
CUPED、序贯、多重比较默认化调整前/后并列;alpha spending;BH/Holm;raw p 与 adjusted p 并列。
高级方法不默认,就等于没有;默认不解释,就等于误导。
P1 · 分析
Cohort / 漏斗 / 差异分析按进组日分 cohort;漏斗每层转化;属性过滤 + 分组对比;探索性标记。
覆盖长期效应与「对谁有效」的高频问题。
P1 · 协作
评论、决策记录、导出/API锚定指标/切片的评论;不可变快照;决策状态;CSV/API 导出。
让分析沉淀为组织资产,而不是一次性报表。
P2 · 智能
Uplift/CATE + holdout 验证独立任务向导;TOP 子群;ITE 分箱;样本外验证;与确证实验联动。
高价值但高风险;没有验证闭环不上主路径。
P2 · 智能
LLM 叙述与诊断只引用结果对象;拒绝条件;归因措辞限制;评估与审计。
能提效,但会把统计脆弱性放大。
P2 · 组合
实验组合视图与自动下钻跨实验台账;holdout 管理;异常自动定位;自然语言转 DSL。
从单实验走向组合决策,需要新的信息架构。

9.3 验收标准#

  1. 可复现:任取一个结论,输入六个版本号,能在 1 次重跑中复现同一数字(误差在浮点范围内)。
  2. 可解释:任一数字 2 次点击内看到指标定义、分母、时间窗、版本、owner、数据截止。
  3. 可拦截:SRM 异常时,效应数字被隐藏,只保留诊断与样本;护栏恶化时,结论卡强制降级。
  4. 可探索:维度下钻 P95 < 2.5 秒;用户样本 P95 < 3 秒;超过 30 秒自动转异步。
  5. 可校正:页面显示「本次分析 N 次检验」;adjusted p 与 raw p 并列;探索性结果带标记。
  6. 可协作:分享链接打开是同一实验、指标、人群、维度路径、时间窗、方法;评论可 @owner。
  7. 可审计:谁在什么时间、用什么理由、导出了多少行、包含哪些字段,全部可查。
  8. 可访问:键盘可完成「进报告 → 切指标 → 展开证据 → 下钻 → 返回」;颜色不是唯一编码。

9.4 成功指标#

指标 定义 目标(上线 6 个月)
Time to insight 从打开报告到做出决策的中位时长 降低 40%
分析复用率 使用模板/保存视图/分享链接的分析占比 > 50%
查询 P95 L2 同步查询的 95 分位 < 2.5s
SRM 覆盖率 有 SRM 状态的核心实验占比 100%
校正覆盖率 多指标/多切片分析中开启校正的占比 > 80%
决策记录完成率 有结论、owner、后续动作的实验占比 > 60%
口径争议数 因口径不一致导致的工单/争议 每月 < 5

9.5 落地节奏#

  • 0–90 天:P0 契约 + 结论卡 + 指标表 + 人群构建器 + SRM/护栏;先接 1 个业务线、20 个核心指标。
  • 90–180 天:下钻 + 模板 + CUPED/序贯/多重比较 + Cohort/漏斗;接 3 个业务线。
  • 180–365 天:差异分析 + Uplift + 决策记录 + API;建立指标认证与 owner 制度。
  • 365 天以后:组合视图、自动下钻、LLM 叙述/诊断;把「分析质量」纳入平台 KPI。

9.6 风险与缓解#

风险 表现 缓解
口径治理跟不上 同名指标多个版本,结论互相打架 指标认证 + owner + 版本锁定 + 口径指纹
性能拖垮采用 下钻 10 秒,用户回到 Excel 分级查询 + 预聚合 + 缓存 + 异步
统计复杂度吓退业务 用户只看 p 值或只看颜色 默认结论 + 渐进披露 + 解释文案
高级分析滥用 子群越切越多,假阳性泛滥 预注册 + FDR + 探索性标记 + 复验
隐私/合规 用户明细导出泄露 脱敏 + 审批 + 行级权限 + 审计
组织不信任 「平台数字和数仓对不上」 对账任务 + 结果 diff + 公开口径

10. 反模式与决策清单#

10.1 十二个反模式#

反模式 症状 根因 修复
图表墙 首屏 20 张图,没人知道看哪张 以「功能多」代替「决策支持」 结论卡 + 三层指标 + 渐进披露
p 值自动售货机 切 20 个切片,挑一个显著的 没有多重比较与探索性标记 预注册 + FDR + 降级文案
人群即切片 把 post-treatment 人群当因果结论 没有时点校验 两种作用位置 + 时点警告 + 复验
指标即字段 同名指标多个口径 没有注册表/版本/owner 指标契约 + 认证 + 血缘
下钻即 group by 200 个维度值、没有 N/CI 把查询能力当分析能力 TopN + 最小样本 + 每层护栏
缓存幽灵 改了定义,报表没变 缓存 key 缺版本 全版本 key + 主动失效
导出即拖库 用户明细随便下载 权限与审计缺失 脱敏 + 审批 + 限额 + 水印
实时崇拜 所有指标都要秒级 没区分摄入/指标/决策实时 分级:实时护栏 + T+1 决策
高级方法堆菜单 18 个方法,没人会用 以算法数量代替产品化 入口契约 + 默认值 + 解释 + 成本
LLM 归因 流畅地解释「为什么涨」 把叙述能力当因果能力 数字白名单 + 拒绝条件 + 待验证措辞
静默变更 漏斗改了,所有实验报告变了 没有版本与通知 版本化 + 重算横幅 + diff
数据湖直连 分析师各写各的 SQL 没有语义层 注册指标 + 受控 DSL + 沙箱 SQL

10.2 自建 vs 采购:分析模块的决策清单#

指标口径是否是我们的核心竞争力?

如果指标定义与业务强耦合、外部产品无法表达,语义层必须自建;否则优先复用。

数据能否出仓?

不能出仓就选 warehouse-native 或私有化;能出仓再考虑 SaaS 的体验与统计能力。

人群与标签是否已存在?

已有 CDP/标签平台时,分析模块应做「消费方」,不要再造一套人群服务。

是否需要自定义统计方法?

需要 CUPED/HTE/序贯等深度定制时,自建统计层;否则用产品默认值 + API。

下钻性能能否达标?

高基数、多维度、秒级,是自建最容易低估的部分;先做 POC 再承诺。

合规与审计是否硬要求?

强监管场景优先私有化/物理隔离;共享 OLAP + 缓存会放大越权风险。

10.3 问供应商的十个问题#

  1. 你们的指标定义是否版本化?被实验引用后还能改口径吗?
  2. 人群是在分流前还是分流后生效?能否分别配置?
  3. 子群分析是否默认做多重比较?用的什么方法?家族怎么定义?
  4. SRM 是自动检测还是手工配置?异常时会不会隐藏效应?
  5. CUPED 用哪段 pre 期?新用户怎么处理?分位数指标支持吗?
  6. 序贯检验支持中途查看吗?alpha spending 参数能否锁定?
  7. 下钻的 P95 是多少?高基数维度怎么处理?缓存 key 包含哪些版本?
  8. 用户明细导出有哪些权限、脱敏、审计与限额?
  9. 指标口径变更后,历史报告会不会重算?如何通知?
  10. 是否提供 API/DSL,让我把分析嵌进自己的 workflow?

10.4 一句话收束#

分析模块的终局,不是「什么都能查」,而是「查到的每个数都能被解释、被复现、被质疑,并且最终能变成一个更好的决策」。Libra/DataTester 值得学的,不是某一个图表,而是它把统计假设、数据口径、能力边界三件事同时放进了界面;代价是重、慢、学习曲线陡,收益是同一个结论能被 PM、DS、运营用同一种语言复述。

如果只能记住一句话:先建契约,再建画布;先保因果,再谈智能。

11. 参考来源#

本页优先使用官方文档、论文与工程博客;厂商营销材料只用于确认产品存在,不作为能力证据。标注「推断」「建议」的内容是我们的产品判断,不代表任何厂商的官方设计。

11.1 一手产品文档#

  • BytePlus DataTester, Experimental Report Overview:链接
  • BytePlus DataTester, How to Interpret the Experiment Report:链接
  • BytePlus DataTester, Metrics Analysis: Event Metrics & Retention Metrics:链接
  • BytePlus DataTester, Create Event Metric:链接
  • BytePlus DataTester, Create Warehouse Metric:链接
  • BytePlus DataTester, User Cohorts:链接
  • BytePlus DataTester, User Details:链接
  • BytePlus DataTester, Report Page Custom Filter Template:链接
  • BytePlus DataTester, Advanced Analysis: Difference Analysis and Group Comparison:链接
  • BytePlus DataTester, Advanced Analysis: Cohort Analysis:链接
  • BytePlus DataTester, Metric Analysis: Funnel Metric Analysis:链接
  • BytePlus DataTester, Report Interpretation: Customer Group Experiment:链接
  • BytePlus DataTester, Sensitive Population Insights:链接
  • BytePlus DataTester, SQL Custom Query:链接

11.2 统计、方法与工程#

  • Eppo, CUPED:链接

  • Eppo, Analysis Methods:链接

  • Eppo, Sample Ratio Mismatch:链接

  • Eppo, Multiple Testing:链接

  • Eppo, Certified Metrics:链接

  • GrowthBook, Sequential Testing:链接

  • GrowthBook, Multiple Corrections:链接

  • GrowthBook, Experiment Results:链接

  • Statsig, CUPED:链接

  • Wager & Athey, Estimation and Inference of Heterogeneous Treatment Effects using Random Forests:链接

  • Deng et al., Applying the Delta Method in Metric Analytics(KDD 2018):链接

  • Netflix, It's About Time: Practical Considerations for Measuring Long-Term Treatment Effects:链接

  • Instacart, Geo-based A/B Testing and Difference-in-Difference Analysis:链接

  • ByteDance, DQ Estimator for Two-sided Markets:链接

  • 腾讯微信实验平台, VLDB 2024 论文:链接

  • Statsig, Interpreting Results / Custom Queries:链接

  • Statsig, Differential Impact Detection:链接

  • Eppo, Segments:链接

  • Eppo, Copy SQL:链接

  • Eppo, Property Analysis:链接

  • GrowthBook, Dimensions:链接

  • GrowthBook, Metrics:链接

  • Amplitude, Advanced Metric Use Cases:链接

  • Amplitude, Sequential Testing:链接

  • Optimizely, Experiment Results Page:链接

  • VWO, Campaign Report Components:链接

  • AB Tasty, Data Explorer:链接

  • Convert, Experiment Report:链接

  • PostHog, Experiments / CUPED:链接

11.3 中国平台公开材料#

  • 字节跳动 AICon 2025 演讲者简介(Libra/DataTester):链接
  • 《AI 时代实验平台演进之路》InfoQ 报道:链接
  • 字节 AICon 2024《LLM 在 A/B 实验平台的应用探索》:链接
  • 字节 CUPED/ITR 内部实践报道(IT168,2024-10):链接
  • 淘天通天塔 Fluss 实践(阿里云开发者社区,2025-07):链接
  • 美团 BETA 分析引擎(2024-09):链接
  • 美团可信实验白皮书(2025-05):链接
  • B 站北极星与 ClickHouse RBM:链接
  • 知乎 AB2.0 从 ClickHouse 预计算迁 Doris 的公开分享:链接

11.4 交互、可访问性与设计#

  • W3C, ARIA Authoring Practices: Grid Pattern:链接
  • W3C, WCAG 2.2: Use of Color:链接
  • W3C, WCAG 2.2: Reflow:链接
  • Nielsen Norman Group, Progressive Disclosure:链接

11.5 引擎与存储#

  • ClickHouse, Incremental Materialized Views:链接
  • ClickHouse, Bitmap Functions:链接
  • Apache Doris, Materialized View Overview:链接
  • StarRocks, Asynchronous Materialized Views:链接
  • BigQuery, Materialized Views:链接
  • Snowflake, Materialized Views:链接
  • Apache Druid, Design:链接

关于本页

本页是《AB 测试平台全网竞品与方案调研》2026-10 版的独立专题,基于 8 路并行调研、20 份 DataTester 官方文档、公开论文与工程博客整理。界面演示中的数据全部虚构,仅用于说明信息架构与交互,不代表任何厂商的真实产品。厂商功能、默认参数与价格以其最新文档为准;涉及内部平台的部分已标注「推断」,不应作为采购或架构决策的唯一依据。

NOTE本页是独立专题,基于公开产品文档、工程博客与论文整理;不包含任何非公开内部资料。厂商功能与默认参数以其最新文档为准。可 下载本专题 Markdown。