系统设计面试:如何构建能自动发现实验质量问题的 A/B 平台?
题干与适用场景
产品团队每天运行数百个 A/B 实验,平台负责分配用户、记录触发事件、计算指标并监控实验质量。历史上出现过分流不均、样本比例失配和反复查看导致的错误结论。请设计从实验配置到结论审核的系统,并说明数据延迟、统计方法、告警和权限边界。
面试官考察点
- 是否先澄清实验单位、随机化层级、互斥平面和指标口径。
- 是否把 assignment、trigger、exposure 和 outcome 事件分开。
- 是否能设计随机性校验、SRM 检测和数据质量告警。
- 是否知道固定样本量方法不能随意 peeking,能提出 sequential 或 anytime-valid 方法。
- 是否能把告警、审计、重跑和发布闸门接入完整工作流。
回答前需要澄清的问题
- 实验按用户、设备、会话还是请求随机化?是否允许跨实验正交运行?
- 实验每天数量、单实验流量、指标延迟和保留窗口是多少?
- 主要指标、护栏指标和最小可检测差异如何声明?
- 发现 SRM 或埋点缺失后,是暂停流量、标记无效还是自动重跑?
- 谁能查看原始分流、修改停止规则和批准发布?
30 秒回答框架
“我会把平台分成配置与随机化服务、事件采集管道、实验分析服务和结论闸门。分流服务用稳定的哈希种子把用户映射到固定桶,并区分互斥与正交实验;事件链路分别记录 assigned、triggered、exposure 和 outcome。质量服务持续检查桶分布和 SRM,分析服务用支持连续监控的 sequential 或 anytime-valid 方法处理早停。所有结论带数据版本、代码版本和审计记录,质量告警会阻止发布,而不是只发一条聊天通知。”
分步骤深入解答
1. 先定义实验与随机化边界
实验配置包括实验 ID、版本、随机化单位、流量比例、互斥平面、目标指标、护栏、最小可检测差异和停止规则。分流哈希必须使用稳定的用户键和实验种子,避免请求级随机导致同一用户跨变体。互斥实验共享平面,正交实验使用不同平面并记录碰撞策略。
2. 拆分 assignment 到 outcome 事件
仅记录最终转化无法判断用户是否真的看到变体。事件应至少包含分配、触发、曝光和结果,并携带实验版本、变体、时间、匿名用户键哈希和来源。事件模式版本化,迟到事件进入可重算窗口,重复事件用幂等键去重。
{
"experiment": "checkout-copy-v3",
"experimentVersion": 7,
"unitHash": "u_8f2c",
"variant": "treatment",
"event": "exposure",
"eventTime": "2026-08-01T12:00:03Z",
"schemaVersion": 2,
"idempotencyKey": "u_8f2c:checkout-copy-v3:7:exposure"
}分配服务与分析管道之间通过不可变事件和版本号连接,避免配置修改后历史数据被重新解释。
3. 做随机性与 SRM 监控
随机性校验比较分流桶与预期分布,SRM 检查实际触发样本与配置比例是否一致。监控 assigned 和 triggered 两个层级,因为埋点、资格条件或客户端版本可能只在触发后造成偏差。告警需要区分暂时数据延迟、真实分流错误和外部流量变化,并保存诊断切片。
4. 处理连续查看与早停
固定样本量检验若每天查看并在显著时停止,会放大第一类错误。平台可以采用 group sequential、SPRT 或 anytime-valid confidence sequence,并把停止边界、alpha、beta、MDE 和查看时间写入实验版本。产品方看到“领先”不代表可以绕过统计闸门;护栏失败或置信区间跨越安全边界时应优先停止流量。
5. 设计实时与批处理路径
实时路径消费 Kafka 等事件流,分钟级更新分流质量和数据延迟告警;批处理路径负责去重、迟到修正、分层指标和最终报告。两条路径共享事件 schema、实验版本和指标定义,实时结果标记为 provisional,只有批处理水位达到要求才能成为发布依据。
6. 把结论接入审计和发布闸门
实验状态包含 draft、running、paused、invalid、concluded 和 archived。任何修改随机种子、指标定义或停止规则都产生新版本并冻结旧结果。结论服务输出数据水位、统计方法、样本量、SRM 状态、护栏状态和审计链接;发布系统只接受状态为 concluded 且所有质量检查通过的版本。
高质量示范回答
“我会先固定随机化单位和实验版本,再拆分分流、触发、曝光与结果事件。随机化服务用稳定哈希和互斥/正交平面管理冲突,事件管道用 schema 版本和幂等键处理重复、迟到和重放。质量服务在 assigned 与 triggered 层级检查桶分布和 SRM,并提供根因切片。统计服务不能让固定样本量检验被任意 peeking 破坏,因此采用 sequential 或 anytime-valid 方法,记录停止边界和查看时间。实时结果只做告警,批处理水位达标后才产生报告。结论带配置、代码、数据版本和审计记录,SRM、埋点缺失或护栏失败会阻止发布。”
常见错误
- 只存最终指标 → 无法定位分流或曝光缺失 → 保存 assignment、trigger、exposure、outcome 链路。
- 用请求随机化替代用户随机化 → 同一用户看到多个变体 → 固定单位键和实验种子。
- 每天看 p 值并提前停止 → 固定样本量假设被破坏 → 使用 sequential 或 anytime-valid 方法。
- 把 SRM 告警当作统计显著 → 样本比例异常说明实验可能无效 → 先暂停结论并诊断分流与资格条件。
- 实时结果直接驱动发布 → 迟到数据和重复事件会改写结论 → 设置批处理水位和发布闸门。
追问及应对
为什么要同时检查 assigned 和 triggered?
分配可能完全均匀,但只有满足资格并真正进入页面的用户才触发实验。资格逻辑、客户端版本、拦截器或埋点缺失会让 triggered 比例失真;两个层级一起看才能区分随机化错误和曝光链路问题。
如何支持互斥与正交实验?
互斥实验共享同一流量平面和种子,用户在该平面只进入一个实验。正交实验使用不同平面,允许独立组合,但必须记录碰撞矩阵和高风险组合的禁用规则。
anytime-valid 方法解决了什么?
它允许持续监控并在数据依赖的时点停止,同时提供时间均匀的误差控制。平台仍需声明目标效应、功效、护栏和业务损失,不能把任意指标或任意停止理由包装成统计保证。
发现 SRM 后是否自动重跑?
先冻结实验结论并保留原始数据,按时间、客户端、国家、资格条件和实验平面切片定位根因。只有确认分流或埋点修复且产品同意重新定义分析窗口后才重跑;自动重跑不能掩盖一次无效实验。