mcpField
D
diagnosing-experiment-health

diagnosing-experiment-health

github.com/posthog数据与数据库9522 次安装今天更新
代码仓库

关于 diagnosing-experiment-health

用于诊断 PostHog 实验结果异常的技能,涵盖偏差、数据为空等情况。它指导 Agent 定位实验、检查配置与数据,并依据症状查阅对应诊断资料。

主要功能

  1. 01将实验名称解析为 ID
  2. 02检查实验配置与诊断快照
  3. 03按症状匹配诊断类别
  4. 04区分已验证结论与假设

适用场景

  1. 01调查变体曝光比例不均
  2. 02排查实验结果缺失或为空
  3. 03分析显著性变化与指标差异

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/posthog/ai-plugin --skill diagnosing-experiment-health

安装后在 Claude Code 中输入/diagnosing-experiment-health确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
bias-and-skew.md
diagnostic-snapshot.md
empty-experiment.md
interpretation.md
mid-run-changes.md
numbers-vs-sql.md
qualitative-feedback.md

详细介绍

诊断实验健康状况

此技能解答:我的 PostHog 实验结果看起来不对、有偏差或为空——这是怎么回事? 它用于诊断和检查单个实验的健康状况:包括实验设置、曝光、结果,以及实验运行期间发生的变化。

在分派表中找到与用户问题相符的条目,然后阅读对应的参考文件以进行诊断。

参考文件中的每项诊断都会标记为 [HIGH]、[MEDIUM] 或 [LOW],表示其验证程度:[HIGH] 表示已直接通过 PostHog 代码验证,[MEDIUM] 表示已部分验证或通过团队来源验证,[LOW] 表示描述的是此处未经验证的 SDK/外部行为。将 [LOW] 项视为需要测试的假设,而不是可以直接断言的事实。

步骤 1 — 确认实验

如果用户通过名称或描述提及某个实验,请先加载 finding-experiments 技能,将其解析为具体 ID。

调用 experiment-get 并提取以下字段。它们几乎是所有诊断的输入:

  • status(draft / running / paused / exposure_frozen / stopped)、start_date、end_date、is_legacy
  • feature_flag.active 和 feature_flag.filters.multivariate.variants[] — 变体键和拆分比例(rollout_percentage)。 这是标志当前的状态。发布或编辑后,本次运行的拆分比例会记录在变更历史中(步骤 1.5)。
  • feature_flag.filters.aggregation_group_type_index — 如果已设置,实验单位是群组,而不是个人
  • feature_flag.filters.groups[] — 对每个群组,读取 variant、properties 和 rollout_percentage(该群组的发布比例,即符合条件并进入实验的分桶单位——个人,或当标志或群组按群组类型聚合时的群组——所占的百分比;每个群组都有自己的发布比例,因此除非标志只有一个无条件群组,否则不存在单一的总体发布比例)。非空的 variant 若属于标志的某个变体键,则表示对符合条件的队列强制覆盖变体(按发布条件分配,而非随机分配)——对应问题 A7。留意严重情形(A7b):绑定了变体的群组具有宽泛或空的 properties,且发布比例很高;或者没有任何群组仍进行随机分配(variant: null),也没有通往某一臂的发布路径——这会导致另一变体样本不足(其中一臂的可分析曝光量约为 0)。参见 references/bias-and-skew.md。
  • feature_flag.bucketing_identifier 和 feature_flag.ensure_experience_continuity — 标志用于哈希的内容(A3、A6、A8、A10)
  • holdout 和 excluded_variants — 有意排除在分析之外的人员和实验臂
  • exposure_criteria.multiple_variant_handling — 若缺失,默认为 "exclude"
  • exposure_criteria.exposure_config — 曝光事件及其属性筛选条件。 若未设置,或指定了 $feature_flag_called,则使用默认曝光事件:从 resolved_exposure_event 中读取具体事件。 若其为 $feature_flag_called,还要读取 $experiment_exposure(event IN ('$feature_flag_called', '$experiment_exposure')),并统计人数,而不是事件行数。 若配置指定 $experiment_exposure,则统计该事件,无论 resolved_exposure_event 的值是什么。 任何其他事件或操作都属于_自定义曝光事件_。 配置中的属性筛选条件适用于上述任一情况(B12)。 references/diagnostic-snapshot.md 中的表格说明了哪个属性携带变体信息。
  • exposure_criteria.activation_config — 在默认曝光之外的激活事件或操作。 设置后,只有在某人首次标志曝光时或之后发生的首次激活事件,才会将其计为已曝光;该事件的时间即为曝光时间。 它不能与自定义曝光事件同时使用。
  • exposure_criteria.filterTestAccounts — 默认为 true
  • metrics 和 metrics_secondary,以及共享指标 — 对每项指标,读取其名称、类型和定义。 根据指标定义描述指标,而不是根据其名称(D13)。
  • stats_config — method(Bayesian 或 Frequentist)、置信水平(bayesian.ci_level、frequentist.alpha)、frequentist.sequential_testing_enabled、cuped、baseline_variant_key。 若缺少 method,则按 Bayesian 处理;若缺少置信水平,则默认为 95%。序贯检验和 CUPED 使用项目默认值(C13)。
  • running_time_calculation — 目标样本量(所有变体的总量)、达到该目标还需的天数,以及最小可检测效应。 如果估算值来自用户输入的数字,或是在创建时写入且页面从未刷新过,那么天数就是估算的总时长(C12)。 复制的实验在页面刷新数据之前,会沿用来源实验的数值。
  • only_count_matured_users — E11

步骤 1.5 — 获取诊断快照(先验证,再提问)

在向用户提出澄清问题之前,先获取 references/diagnostic-snapshot.md 中的诊断快照。本技能中的大多数诊断 都可以通过这些数据确认或排除,无需访谈。

每次诊断时,都先读取成本低的数据源:先查看已存储的结果,再查看变更历史。 当用户报告了意料之外的变化时,先查看变更历史,再查看已存储的结果。 然后,在诊断需要获取只有曝光数据才能提供的信息时,再查看曝光数据。 仅当这些数据无法说明情况时,才查询原始事件。

步骤 2 — 将症状与诊断相匹配

用户说……诊断类别
“较小的变体看起来有偏差”/横幅提示有偏差A — 偏差与倾斜
“变体比例与我的分流不符”/不匹配警告/“58/42 正常吗?”A — 偏差与倾斜
“为什么不是 50/50?”/“每天都有一个变体分到更少的用户”A — 偏差与倾斜
“用户同时出现在对照组和测试组中”/$multiple 占比高A — 偏差与倾斜
“我们的自有分析显示分流均匀,但 PostHog 却不是”A — 偏差与倾斜
“标记的响应大多为 false”/“用户看到新界面一秒钟,然后就消失了”A — 偏差与倾斜
服务端渲染应用中的多变体曝光A — 偏差与倾斜
关于功能标记/实验状态不匹配的横幅A — 偏差与倾斜
“正在迁移 distinct_id”/运行中从匿名 ID 切换到 user_idA — 偏差与倾斜
指标计数远小于曝光量(例如相差 10× 或 100×)A — 偏差与倾斜(先转到这里,再看 D)
“实验显示为 0/数据不足”/为空B — 空实验
“变体始终为 undefined/false”B — 空实验
“$feature_flag_called 已触发,但没有曝光记录”B — 空实验
“添加筛选条件后,曝光量降为零”/“复制的实验为空”B — 空实验
“曝光量充足,但转化量为零”B — 空实验(然后看 D11)
“实验显示正在运行,但曝光量数周/数月都没有变化”B — 空实验
“实验运行时间越长,显著性结果越反复”C — 解读误区
“之前判定为显著,后来又变得不显著了”C — 解读误区
“实验才运行一天,可以看结果吗?”C — 解读误区
“46 次曝光中分流比例为 30/16,这是出问题了吗?”C — 解读误区
“显示已完成/已达到目标,但没有任何指标显著”C — 解读误区
“A/A 测试显示结果显著”C — 解读误区
“指标很多——有些显著,有些不显著”C — 解读误区
“测试变体表现更差,设置正确吗?”/“能帮我检查这个实验吗?”第 3 步——先做两项检查,然后看 C 和 D12
“贝叶斯分析显示获胜概率为 96%——我们该发布吗?”C — 解读误区
“置信区间有重叠——这是否意味着不显著?”C — 解读误区
“p 值恰好为 1”/“对照组显示有提升”C — 解读误区
“外部工具(显著性计算器或 AI Agent)的结果与 PostHog 不一致”C — 解读误区
“该发布吗?主要指标上升了,但次要指标下降了”C — 解读误区
“PostHog 数字 ≠ 我的 SQL 计数”D — 数字与 SQL 不一致
“漏斗显示 X%,但原始事件计数显示 Y”D — 数字与 SQL 不一致
“实验结果显示持平,但我们的仪表板显示下降了”D — 数字与 SQL 不一致
“收入总和不对”/“细分结果显示 ‘none’”D — 数字与 SQL 不一致
“指标名称表达的意思和数字不一致”D — 数字与 SQL 不一致
“录屏与统计数据不符”/“没有已曝光用户的录屏”D — 数字与 SQL 不一致
“我应用了筛选条件,但用户数没有变化”D — 数字与 SQL 不一致
“我想按当前用户属性(此时的属性,而非曝光时的属性)细分结果”D — 数字与 SQL 不一致
“结果没有更新”/“刷新后没有变化”D — 数字与 SQL 不一致
“运行中更改了分流/发布比例/指标/条件,现在结果很奇怪”E — 运行中更改
“数字一夜之间变了,但没人动过它”E — 运行中更改,然后看 D 中的 D8
“我们暂停了几天,现在还能相信结果吗?”E — 运行中更改
“冻结了实验”/“冻结后用户失去了该变体”/“冻结请求被拒绝”E — 运行中更改
“实验已结束/已发布——标记现在意外地变成了 0/100”E — 运行中更改
“我们发布了该变体,但有些用户仍然看不到”E — 运行中更改
“长期指标的变化方向与主要指标相反”E — 运行中更改
“留存指标统计了我意料之外的用户”E — 运行中更改
“实验结束后,无法将功能标记恢复为简单的(布尔值)标记”E — 运行中更改
“如何使用新变体重新启动实验?”E — 运行中更改
“显示这是一个旧版实验”/无法编辑指标E — 运行中更改(E13 旧版实验)
“结果无法加载”/许多指标行显示 data: null(并非旧版实验)第 1.5 步——诊断快照(空值行)
“用户如何看待新的流程?”/想了解实验的定性反馈F — 定性反馈
“用户为什么更喜欢对照组?”/“他们不喜欢测试变体的什么地方?”F — 定性反馈
如果症状不明确,请先提出一个澄清问题,再选择诊断。大多数诊断的修复方式各不相同
——不要猜测。
如果某个问题符合多个组中的条目,请逐一阅读这些组(步骤 3)。

如果报告来自侦察工具或其他自动化检查,它会指出发现的问题:根据该发现确定路径,并在重新获取数据前沿用报告中的数字。

步骤 3 — 列出证据支持的所有诊断

在步骤 2 中匹配症状并阅读相关参考文件后,请先列出所有适用的诊断,再建议采取行动。

分别列出同时出现的机制——即使其中一种更显著,也不要将它们合并成单一的“等待”或“修复”建议。不同机制有不同的修复方式:_系统性_偏差(例如,不均匀分流 + Exclude)不会因等待而消除;_统计性_模式(例如,小样本方差)则会。将它们合并给出建议,会导致用户照做后偏差仍然存在。

只列出在项目状态中有验证途径的机制——配置(来自 experiment-get)、快照数据、活动日志,或仓库源码(当 Agent 拥有该仓库时)。配置衍生的机制也要计入:80/20 分流且默认 multiple_variant_handling="exclude",可在 experiment-get 中查看,因此可以列出。没有来源的机制不要列出(例如,快照显示变体比例正常时却指出 SRM)。

无论问题是什么,每项诊断都必须包含以下两项检查:

  • 实验开始多久了? 在解读结果前,说明实验已运行时长(start_date)以及当前样本占目标样本的比例(已曝光总人数与 running_time_calculation.recommended_sample_size 的对比)(参见 references/interpretation.md 中的 C1)。 页面使用的已曝光总人数取自第一个主要指标:存储结果中所有变体的 number_of_samples 之和,而不是 exposures.total_exposures。 recommended_sample_size 是页面上次计算估算值时保存的目标样本量。 如果没有该值,表示未保存目标样本量:请明确说明。
  • 哪些人获得了曝光? 在称设置合理之前,请将已曝光人群(exposure_criteria 和标志的发布条件)与决策所涉及的人群进行比较(参见 references/numbers-vs-sql.md 中的 D12)。 默认曝光设置并不能证明实验覆盖了正确的人群。 如果没有信息说明决策针对哪些人,请提出询问。

诊断组

A — 偏差与倾斜

变体看起来不均衡、某个变体似乎存在偏差、应用内警告横幅出现,或用户出现在多个变体中。涵盖不均匀分流与 Exclude 的交互、样本比例不匹配及其成因、实验组之间曝光事件丢失或发送不均、标志对部分受众不返回任何变体、身份碎片化、bootstrap 与 /flags 不匹配、实验中途编辑标志、强制指定变体,以及标志/实验状态不一致。

→ 参见 references/bias-and-skew.md

B — 实验为空 / 曝光数为 0 /“数据不足”

这是常见的痛点。涵盖 SDK 调用(评估方法错误、identify() 时机、去重)、曝光捕获(自定义事件缺少变体属性、必需属性、广告拦截器),以及曝光条件匹配(测试账户筛选器、无法匹配的筛选器、资格判定顺序、曝光前触发的事件)。

→ 参见 references/empty-experiment.md

C — 显著性与结果解读陷阱

显著性反复变化、A/A 测试显示显著性、贝叶斯与频率学派混淆、多重比较、低流量方差、窥视数据 / 提前停止。包括运行时长估算(“已达到目标”不代表结果已出炉),以及会改变结果解读方式的统计设置:序贯检验、CUPED、置信水平和基线变体。

→ 参见 references/interpretation.md

D — 数字对不上(PostHog 与用户的 SQL / 原始计数)

实验页面会应用曝光范围、$multiple 排除、测试账户筛选条件和日期范围,而临时编写的 SQL 几乎从不会复现这些条件。还涉及漏斗归因(统计时只计算第一步 → 最后一步)、细分(从曝光事件而非指标事件读取)、“收入总和”的人均值混淆、过时的存储结果、与统计数据不一致的 Recordings 标签页、统计的人群范围比实验更窄的洞察,以及标题与定义不符的指标。

→ 查看 references/numbers-vs-sql.md

E — 运行期间变更后的意外情况(包括生命周期和留存方面的问题)

提高发布比例是安全的;降低时要谨慎;更改变体分配比例属于反模式;运行期间添加指标属于 p-hacking;ship-variant 会重写标志,而仅仅结束实验不会;重置会清除结果,但不会清除标志(移除曝光冻结除外);暂停、冻结和解除冻结都可能使结果产生偏差;更改开始日期会移动整个分析范围。还涵盖留存指标的特殊情况、“成熟用户”筛选,以及长期与短期指标的差异。

→ 查看 references/mid-run-changes.md

F — 定性反馈:变更带来的感受,而非数字变化幅度

A–E 组用于找出作用机制。F 则用于回答它们无法解决的问题:实验中的人如何看待这项变更。在用户完成实验流程时展示一份简短问卷,即可补充定性反馈——用户可以评分并选填评论,还能按变体查看;目前可通过 MCP 使用。

它适用于部分实验,不适用于其他实验。判断标准是:如果不同时展示两个版本,用户能否描述这项变更?重新设计的流程、布局或过程适用;阈值或排名调整则不适用,无论其测得的影响有多大。机械性诊断问题尚未解决时,不要提供问卷——标志门控故障时附加问卷,收集到的只是关于某项功能的意见,而一半受众根本没有体验到该功能——并且在提出新问卷之前,应检查现有或近期的问卷是否已涵盖该时间范围。

创建问卷前要处理好两件事:只向单个变体展示的问卷本身就会造成变体之间的差异;与标志关联的 运行中 问卷可能会生成曝光事件。

→ 查看 references/qualitative-feedback.md

第 4 步 — 根据实验状态校准建议

先呈现诊断结果(第 3 步)。然后再提出建议,但建议的范围应符合实验当前状态所允许的范围。

  • 草稿 — 配置更改不受限制;可以提出建议并应用更改。 草稿标记仍可能为用户提供服务:通过重置创建的草稿,或基于现有标记创建的草稿,其 feature_flag.active 可以为 true;编辑该标记会立即影响这些用户。
  • 运行中(以及已启动但尚未结束的 paused 或 exposure_frozen)——每项更改都有取舍。提出建议前,先说明对运行中实验的影响(反模式?安全吗? 用户能看到吗?)。关于运行中实验的规则,请参阅 configuring-experiment-rollout 及其参考文件 references/changing-distribution-after-launch.md。 暂停、冻结、解除冻结和重置也都是更改:每项都会中断运行,并可能导致结果偏差(参见 references/mid-run-changes.md 中的 E8、E9 和 E16)。
  • 已停止 / 已归档 — 实验和其实验标记共同代表本次运行的记录结果。建议仅限于:(a) 解读现有数据;(b) 为 下一次 实验采取行动;或 (c) 解释发生了什么。

诊断应以发现和建议收尾。 对运行中的实验或其标记进行更改(新增指标、新增曝光条件、重置、重新启动、编辑标记),由用户决定:说明更改对迄今收集的数据有何影响,并且只有在用户明确指示时才执行。

对于已停止或已归档的实验,不要主动提出撤销状态变更(将 ship-variant 标记改写、手动编辑标记、重置、归档)。如果用户问“为什么发生了 X?”,就解释 X——不要附加“以下是撤销方法”。这种做法会假定用户有未表达的意图。像 “如果这不是你的本意,可以……” 或 “要我帮你撤销吗?” 这样的条件式提议也属于主动提出;只有用户明确提到撤销操作(“如何撤销?”、“可以回滚 ship-variant 吗?”、“怎样才能恢复 50/50 分流?”)时,才应说明撤销方法。

术语保持一致:变体之间的 分流(split)不同于 推出比例(rollout,即进入某个发布条件的受众占比);默认曝光事件(resolved_exposure_event)不同于_自定义曝光事件_;多变体处理(exposure_criteria.multiple_variant_handling)中的 从分析中排除 / 使用首次看到的变体 选项,决定的是如何统计接触过多个变体的人,而不是哪个事件算作曝光。

相关技能

  • configuring-experiment-analytics — 修正诊断指出的曝光或指标配置
  • configuring-experiment-rollout — 分流更改的反模式和安全的推出调整
  • managing-experiment-lifecycle — 当实验无法在原位挽救时,重置、结束或重启实验
  • analyzing-experiment-session-replays — 当数据看起来正常,但你需要了解数据背后的行为时
  • debugging-experiments — 当问题是关于他人实验的支持请求,且需要以书面回复时

评论

支持 Markdown