一句话总结:用一个「先拷问对齐 → 落设计文档 → 垂直切片成 100 个可验收任务 → 每任务三端同步 → 逐像素比对 UI」的协作流程,把 webfunny 埋点平台的编程实验(A/B 测试)能力从零做到了端到端可用——四菜单、九态状态机、SDK 分流引擎、指标显著性分析、发布计划闭环全部落地。
一、交付了什么
webfunny 是监控/埋点/APM平台,本次在顶部导航「A/B测试」下拉内新增了四个菜单,构成一个完整的编程实验闭环:
| 菜单 | 能力 |
|---|---|
| 实验列表 | 创建/复制/编辑实验、状态机流转、变更操作集、发布入口、操作记录、示例代码、下载报告 |
| 流量层管理 | 流量层与分组的增删改、分流主体、剩余流量计算、删除占用保护 |
| 用户测试白名单 | 白名单分组、手动粘贴(逗号/回车,≤1000 个)、扫码录入、创建/编辑/删除 |
| 实验指标管理 | 指标/指标分组的增删改、六类指标口径、事件数据源配置 |
配套的核心能力(不在菜单里,但贯穿全流程):
- 实验九态状态机:调试中 / 准备中 / 运行中 / 运行中(暂停)/ 已发布 / 已发布(暂停)/ 待发布(已回滚)/ 已结束 / 上线失败,配合「上线 / 暂停 / 继续运行 / 发布 / 下线 / 回滚 / 重发」动态操作集。
- SDK 分流引擎:纯内存快照 + 一致性哈希,裁决优先级「白名单 > 进组锁定 > 受众筛选 > 发布策略/哈希分流 > 默认值」,支持进组粘性锁定、受众筛选、发布计划放量。
- 指标统计分析:转化率 / 漏斗 / 留存 / 人均值 / 人均事件均值 / 人均事件比值六类指标,两比例 z 检验 + 泊松近似的 p-value、置信区间、显著性判定,漏斗两两分组对比。
- 发布计划:按比例逐步放量、只升不降、到期自动收口。
功能模块总览与状态机:
二、沟通与协作方式(本次最想分享的部分)
这次开发最大的方法论收获是:“没有靠”一口气写完再改",而是把沟通前置、把决策沉淀、把交付切成可独立验收的薄片。
1. 术语先行,一次说清
开工第一步不是写代码,而是产出一份 `CONTEXT.md` 术语表:把「流量层」「分流主体」「对照组/实验组」「核心指标/关注指标」「进组」「空白域」等词的定义钉死。任何一方再提「流量」,都能立刻对齐到同一个意思,而不是各说各话。
- 术语一旦敲定**当场写入**术语表,不攒批;
- 后续需求变更(比如"空白域本期不做""分流优先级调整")都会在术语表里标注日期与原因,避免文档腐烂。
2. 不可逆决策落 ADR
凡满足「事后难改、无上下文会困惑、有真实取舍」的决策,单独记一份 ADR。本次沉淀了 4 条:
- ADR-0001:发布计划到期自动收口;
- ADR-0002:实验状态机扩展为九态;
- ADR-0003:存储全量 ClickHouse(ReplacingMergeTree + 软删除 + 乐观锁);
- ADR-0004:指标分母数据源从「服务端进组明细」切到「SDK 实验点位」。
这些决策被反复回看,避免了"当时为什么这么定"的失忆。
3. 拷问式需求对齐
需求模糊时不直接动手,而是用一次一问的方式逐条拷问:状态列怎么定?白名单一个实验能不能跨分组?流量层要不要区分类型?…… 直到所有分支都收敛,才开始落笔。设计稿对齐结论、二轮反馈修订结论,都被逐条写进文档。
4. 垂直切片成 100 个任务
规格确定后,按「垂直切片」而非「水平切片」拆任务——每个任务切穿数据层 + 逻辑层 + UI 层 + 测试,完成即可 demo。最终拆出 100 个任务(ticket 001–019 及子任务),每个都声明阻塞关系,可以顺序执行、也可以并行推进。
开发计划甘特图(四个里程碑):
5. 每任务「代码 + 文档 + 勾选」三同步
每个 ticket 收尾不是只提代码,而是同步三件事:
1. 代码提交(后端 + 前端 ,都在 `ABTest` 分支);
2. 设计文档同步(Markdown 版 + Word 版 `docx` 都要更新,docx 里插入灰色斜体"本期实现说明"段);
3. 勾选对应 ticket。
这样文档永远不会落后于代码,任何人随时能从文档看到"实际做了什么、为什么"。
6. UI 逐像素对齐设计稿
前端不只是"差不多像",而是拿设计图做 PIL 像素解码取色,再在浏览器里量坐标 + 截图逐处比对。实验数据页的漏斗区前前后后迭代了 9 轮(018d–018k:斜边渐隐、滴落尾巴、淡色对齐段、闭合五边形价签气泡……),指标分析区全量两位小数、置信区间浮层、解读小课堂,都是照着设计稿一处处抠出来的。
7. 回归造数 + 验收手册
收尾时专门做「大数据量 + 多分组」整体回归:直接往 ClickHouse 直插进组/事件表造数,钉死时间锚点跑日聚合;同时产出一份 `ABTest_测试验收操作手册.md`,把"从新建实验 → 数据上报 → 准确性校验 → 指标怎么算"的每一步操作都写清楚,可直接交给测试人员。
8. 记忆与知识沉淀
跨会话的决策(环境维度、短编号方案、CH 无事务约束、数据页两位小数标准……)都进了持久化记忆,下次对话不用重新交代背景。
三、关键技术决策
| 决策 | 结论 |
|---|---|
| 存储 | 全部 ClickHouse(18 张表):配置表 ReplacingMergeTree(updated_at) + 软删除 + 乐观锁;行为域 MergeTree/SummingMergeTree;分流引擎走内存快照不直连查表 |
| 主键 | 主键与外键统一 UUID,对外另发短编号(expCode 全局自增、groupCode 实验内 1..N),方便 SDK 对接 |
| 分流 | 项目级内存快照,30s 定时刷新 + 变更即时失效;一致性哈希 md5(experimentId|userKey) → % 10000 |
| 环境隔离 | 每实验一个 env(dev/sit/stag/pro),多环境项目按 env 隔离;老项目取 projectId 后缀兼容 |
| 分母口径 | 指标分母 = SDK 全埋点实验点位去重用户数(对齐神策 $ABTestTrigger 模型),进组明细退出指标计算 |
分流引擎与神策的算法对比:
四、数据是怎么算出来的(一张图看懂)
所有比率类数值本质都是一句话:当日进组的那批用户里,达到条件的用户数 ÷ 当日进组用户数。实验组与对照组各自算比值,再围绕"两个比值的差"做统计检验(差异相对值、p-value、置信区间)。每天为每个实验生成日聚合表,每行只存 4 个数:分母 d、分子用户数 u、分子事件次数 e、分子数值求和 v。
五、截图巡礼(实际运行界面)
试验概述卡:运行信息 + 自动提升摘要 + 实验备注
提升摘要自动计算——每个实验组取与对照组差异最大的 2 个指标(如"次日留存 提升 +47.32%")。
指标分析卡:指标值 + 差异 + p-value + 置信区间
对照组 74.51%、实验组1 81.31%、差异 +9.12%、p-value 0.24、置信区间 −5.95% ~ 24.20%,每个数字都能追到一个"分子 ÷ 分母"的算式。
漏斗指标卡:分步转化 + 双分组对比
按顺序完成全部步骤的人数 ÷ 进组人数,条形宽度等比缩放,置信区间按"最后一步转化率"做两两分组 z 检验。
累计流量卡:各分组进组人数
六、复盘心得
1. 沟通成本前置:术语表 + ADR + 拷问式对齐,把"理解偏差"消灭在写代码之前,后期返工显著减少。
2. 薄片交付:100 个垂直切片任务让进度全程可见、每步可验证,比"三层同时写完才可用"的水平切片安全得多。
3. 文档与代码同频:三同步纪律让文档始终可信,Word 版与 Markdown 版并行维护,兼顾评审与阅读。
4. 像素级较真:UI 对齐是最容易被"差不多"糊弄的地方,PIL 解码 + 浏览器量坐标把它变成了可验证的硬指标。
5. 回归与验收工具化:造数脚本 + 验收手册,让"完成了"有客观证据,而不是口头宣称
项目规模:2 后端 + 1 前端,7 周,4 个里程碑,18 张 ClickHouse 表,100 个任务,15 端 SDK 示例代码。