diagnosing-experiment-results
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDiagnosing experiment results
实验结果诊断
This skill answers: My PostHog experiment results look wrong, biased, or empty — what's going on?
Match the user's complaint in the dispatch table, then read the matching reference file for the
diagnostic.
Each diagnostic in the reference files is tagged , , or based on how
strongly it's verified — is verified directly in PostHog code, is partially or
team-source verified, describes SDK/external behavior that wasn't verified here. Treat
items as hypotheses to test, not facts to assert.
[HIGH][MEDIUM][LOW][HIGH][MEDIUM][LOW][LOW]本技能用于解答:我的PostHog实验结果看起来有误、存在偏差或为空——这是怎么回事?
将用户的问题与调度表匹配,然后阅读对应的参考文件获取诊断方案。
参考文件中的每个诊断都标记为、或,标记依据为验证强度:表示已在PostHog代码中直接验证,表示已部分验证或由团队来源验证,描述的是SDK/外部行为,未在此处验证。请将项视为待测试的假设,而非既定事实。
[HIGH][MEDIUM][LOW][HIGH][MEDIUM][LOW][LOW]Step 1 — Resolve the experiment
步骤1 — 确认实验信息
If the user refers to an experiment by name or description, load the skill first to
resolve it to a concrete ID.
finding-experimentsCall and pull these fields. They are inputs for almost every diagnostic:
experiment-get- — the variant split
parameters.feature_flag_variants[].rollout_percentage - — the overall rollout (% of users entering the experiment)
parameters.rollout_percentage - — defaults to
exposure_criteria.multiple_variant_handlingif absent"exclude" - —
exposure_criteria.exposure_eventmeans defaultnull$feature_flag_called - — defaults to
exposure_criteria.filterTestAccountstrue - , status (
feature_flag.active/draft/running/paused),stopped,start_dateend_date - — any non-null value is a forced-variant override on the matched cohort (release-condition assignment, not randomized). Surfaces A7 by default.
feature_flag.filters.groups[].variant - — Bayesian (default) or Frequentist
stats_config
如果用户通过名称或描述提及实验,请先调用技能,将其解析为具体ID。
finding-experiments调用接口并获取以下字段,这些字段是几乎所有诊断的输入信息:
experiment-get- — 变体拆分比例
parameters.feature_flag_variants[].rollout_percentage - — 整体发布比例(进入实验的用户占比)
parameters.rollout_percentage - — 若未设置则默认为
exposure_criteria.multiple_variant_handling"exclude" - —
exposure_criteria.exposure_event表示默认使用null$feature_flag_called - — 默认值为
exposure_criteria.filterTestAccountstrue - 、状态(
feature_flag.active/draft/running/paused)、stopped、start_dateend_date - — 任何非空值均表示对匹配群体的强制变体覆盖(基于发布条件分配,而非随机分配),默认对应A7诊断
feature_flag.filters.groups[].variant - — 统计方法(默认Bayesian或Frequentist)
stats_config
Step 1.5 — Pull a diagnostic snapshot (verify before asking)
步骤1.5 — 获取诊断快照(询问前先验证)
Before asking the user clarifying questions, pull the diagnostic snapshot in
references/diagnostic-snapshot.md. Most diagnostics in this skill
can be confirmed or ruled out from that data without an interview.
在向用户询问澄清问题之前,先获取references/diagnostic-snapshot.md中的诊断快照。本技能中的大多数诊断无需与用户沟通,即可通过该数据确认或排除。
Step 2 — Match symptom to diagnostic
步骤2 — 匹配症状与诊断方案
| User says... | Diagnostic group |
|---|---|
| "Smaller variant looks biased" / banner says bias | A — bias & skew |
| "Variant ratio doesn't match my split" / SRM warning | A — bias & skew |
| "Why isn't it 50/50?" / "users in both groups" | A — bias & skew |
"Users in both control and test" / high | A — bias & skew |
| Multi-variant exposure on a server-rendered app | A — bias & skew |
| Banner about feature-flag/experiment state mismatch | A — bias & skew |
| "Migrating distinct_id" / "switching from anonymous to user_id" mid-run | A — bias & skew |
| Metric count is much smaller than exposures (e.g. 10× or 100× gap) | A — bias & skew (route here before D) |
| "Experiment shows 0 / not enough data" / empty | B — empty experiment |
| "Variant always undefined / false" | B — empty experiment |
| "$feature_flag_called fires but no exposures show up" | B — empty experiment |
| "Experiment says running but exposures haven't moved in weeks/months" | B — empty experiment |
| "Significance keeps flipping as we run longer" | C — interpretation traps |
| "Significance was declared, then it wasn't significant anymore" | C — interpretation traps |
| "30/16 split at 46 exposures, is this broken?" | C — interpretation traps |
| "A/A test is showing significant results" | C — interpretation traps |
| "Many metrics — some significant, some not" | C — interpretation traps |
| "Bayesian says 96% chance to win — should we ship?" | C — interpretation traps |
| "Confidence intervals overlap — does that mean not significant?" | C — interpretation traps |
| "An external tool (significance calculator or AI agent) disagrees with PostHog" | C — interpretation traps |
| "Should I ship? Primary is up but a secondary is down" | C — interpretation traps |
| "PostHog numbers ≠ my SQL count" | D — numbers vs SQL |
| "Funnel says X% but my raw event count says Y" | D — numbers vs SQL |
| "Sum of revenue looks wrong" / "breakdown shows 'none'" | D — numbers vs SQL |
| "Recordings panel doesn't match the stats" | D — numbers vs SQL |
| "I applied a filter but the user count didn't change" | D — numbers vs SQL |
| "I want to slice results by current person properties (as of now, not as of exposure)" | D — numbers vs SQL |
| "Changed split / rollout / metric / criteria mid-run, now odd" | E — mid-run changes |
| "Ended/shipped — flag now flipped to 0/100 unexpectedly" | E — mid-run changes |
| "Long-term metric moves opposite from primary" | E — mid-run changes |
| "Retention metric counts users I didn't expect" | E — mid-run changes |
| "Can't convert the feature flag back to a simple (boolean) flag after the experiment ends" | E — mid-run changes |
| "How do I restart an experiment with new variants?" | E — mid-run changes |
| Metric line is rendered but the result block is empty / no chance-to-win or significance | E — mid-run changes (E13 legacy methodology) |
If the symptom is unclear, ask one clarifying question before picking. Most diagnostics have different fixes
— do not guess.
| 用户表述... | 诊断组别 |
|---|---|
| "较小的变体看起来存在偏差" / 横幅提示偏差 | A — 偏差与偏斜 |
| "变体比例与我的拆分设置不符" / SRM警告 | A — 偏差与偏斜 |
| "为什么不是50/50?" / "用户同时在两个组中" | A — 偏差与偏斜 |
"用户同时在对照组和测试组中" / | A — 偏差与偏斜 |
| 服务端渲染应用中出现多变体曝光 | A — 偏差与偏斜 |
| 横幅提示功能标志/实验状态不匹配 | A — 偏差与偏斜 |
| "迁移distinct_id" / "实验中途从匿名ID切换为user_id" | A — 偏差与偏斜 |
| 指标计数远低于曝光量(例如相差10倍或100倍) | A — 偏差与偏斜(优先转至此组别,而非D组) |
| "实验显示0数据/数据不足" / 结果为空 | B — 空实验 |
| "变体始终为undefined / false" | B — 空实验 |
| "$feature_flag_called事件已触发,但未显示曝光量" | B — 空实验 |
| "实验显示正在运行,但曝光量数周/数月未变化" | B — 空实验 |
| "随着实验推进,显著性结果反复变化" | C — 解读陷阱 |
| "之前已判定有显著性,现在又没有了" | C — 解读陷阱 |
| "46次曝光下呈现30/16的拆分比例,这是出问题了吗?" | C — 解读陷阱 |
| "A/A测试显示有显著性结果" | C — 解读陷阱 |
| "多个指标中,部分有显著性,部分没有" | C — 解读陷阱 |
| "Bayesian显示96%的获胜概率——我们应该发布吗?" | C — 解读陷阱 |
| "置信区间重叠——这意味着没有显著性吗?" | C — 解读陷阱 |
| "外部工具(显著性计算器或AI Agent)与PostHog结果不一致" | C — 解读陷阱 |
| "我们应该发布吗?主指标上升但次要指标下降" | C — 解读陷阱 |
| "PostHog数据 ≠ 我的SQL统计结果" | D — 数据与SQL对比 |
| "漏斗分析显示X%,但我的原始事件计数显示Y" | D — 数据与SQL对比 |
| "收入总和看起来不对" / "细分结果显示'无'" | D — 数据与SQL对比 |
| "录屏面板数据与统计结果不符" | D — 数据与SQL对比 |
| "我应用了筛选条件,但用户计数没有变化" | D — 数据与SQL对比 |
| "我想按当前用户属性(截至现在,而非曝光时)拆分结果" | D — 数据与SQL对比 |
| "实验中途修改了拆分/发布/指标/规则,现在结果异常" | E — 中途变更 |
| "实验已结束/发布——标志意外切换为0/100" | E — 中途变更 |
| "长期指标与主指标走势相反" | E — 中途变更 |
| "留存指标统计的用户不符合预期" | E — 中途变更 |
| "实验结束后无法将功能标志转换回简单(布尔型)标志" | E — 中途变更 |
| "如何重新启动带有新变体的实验?" | E — 中途变更 |
| 指标线已渲染,但结果块为空 / 无获胜概率或显著性结果 | E — 中途变更(E13旧版方法论) |
如果症状不明确,先询问一个澄清问题再选择诊断组别。大多数诊断有不同的解决方案——请勿猜测。
Step 3 — Surface every diagnostic the evidence supports
步骤3 — 列出所有证据支持的诊断方案
After matching the symptom in Step 2 and reading the relevant reference file(s), list each diagnostic
that applies before recommending an action.
Surface co-occurring mechanisms independently — even when one is more salient, don't collapse them
into a single "wait" or "fix" recommendation. Different mechanisms have different fixes: a
systematic bias (e.g. uneven-split + Exclude) doesn't resolve by waiting; a statistical pattern
(e.g. small-sample variance) does. Bundling them leaves the bias in place after the user follows the
bundled advice.
Only list mechanisms that have a path to verification in the project state — config (from
), snapshot data, activity log, or repo source. Config-derived mechanisms count: an
80/20 split with default is visible in and is
therefore enumerable. Naming a mechanism with no source (e.g. SRM when the snapshot shows a clean
variant ratio) is not.
experiment-getmultiple_variant_handling="exclude"experiment-get在步骤2中匹配症状并阅读相关参考文件后,列出所有适用的诊断方案,再给出行动建议。
分别列出同时存在的问题机制——即使其中一个更明显,也不要将它们合并为单一的“等待”或“修复”建议。不同的机制有不同的解决方案:系统性偏差(例如非均匀拆分+排除设置)无法通过等待解决;而统计模式(例如小样本方差)可以通过等待解决。合并建议会导致用户遵循建议后仍存在偏差问题。
仅列出可通过项目状态验证的机制——配置信息(来自)、快照数据、活动日志或代码库来源。基于配置的机制有效:例如80/20的拆分比例搭配默认可在中查看,因此可列举。无来源依据的机制(例如快照显示变体比例正常却提及SRM)则不可列举。
experiment-getmultiple_variant_handling="exclude"experiment-getDiagnostic groups
诊断组别
A — Bias & skew
A — 偏差与偏斜
Variants don't look balanced, one variant looks biased, the in-app warning banner appeared, or users are
showing up under multiple variants. Covers the uneven-split + Exclude interaction, SRM, identity
fragmentation, bootstrap × mismatch, and flag/experiment state inconsistency.
/decide→ See references/bias-and-skew.md
变体看起来不平衡、某个变体存在偏差、应用内出现警告横幅,或用户出现在多个变体中。涵盖非均匀拆分+排除设置的交互问题、SRM、身份碎片化、bootstrap与不匹配,以及标志/实验状态不一致问题。
/decide→ 查看references/bias-and-skew.md
B — Empty experiment / 0 exposures / "not enough data"
B — 空实验 / 零曝光 / "数据不足"
A frequent pain point. Covers SDK call (wrong evaluation method, timing, dedup),
exposure capture (custom event missing variant property, required properties, ad-blockers), and
exposure-criteria match (test-account filter, eligibility ordering, events firing before exposure).
identify()→ See references/empty-experiment.md
常见痛点。涵盖SDK调用(错误的评估方法、调用时机、去重)、曝光捕获(自定义事件缺少变体属性、必填属性缺失、广告拦截器影响),以及曝光规则匹配(测试账户筛选、资格排序、事件在曝光前触发)。
identify()→ 查看references/empty-experiment.md
C — Significance / interpretation traps
C — 显著性 / 解读陷阱
Significance flipping, A/A test showing significance, Bayesian vs Frequentist confusion, multiple
comparisons, low-volume variance, peeking / early stopping. Includes the legacy stats issue (A/A tests
historically over-fired before the new Bayesian module) and how the win-probability methodology changed in
Jan 2025 (single test vs control, not control vs all variants).
→ See references/interpretation.md
显著性结果反复变化、A/A测试显示显著性、Bayesian与Frequentist混淆、多重比较、低流量方差、偷看/提前终止。包括旧版统计问题(在新Bayesian模块推出前,A/A测试历史上频繁误报显著性),以及2025年1月获胜概率方法论的变化(单测试组vs对照组,而非对照组vs所有变体)。
→ 查看references/interpretation.md
D — Numbers don't match (PostHog vs the user's SQL / raw count)
D — 数据不一致(PostHog vs 用户的SQL/原始计数)
The experiment page applies an exposure scope, exclusion, test-account filter, and date range
that ad-hoc SQL almost never replicates. Covers funnel attribution (only first→last step counts for stats),
breakdowns (read from the exposure event, not the metric event), the "sum of revenue" mean-of-per-user
confusion, and the recordings-panel-vs-stats divergence.
$multiple→ See references/numbers-vs-sql.md
实验页面应用了曝光范围、排除、测试账户筛选和时间范围,而临时SQL几乎无法复制这些条件。涵盖漏斗归因(统计仅计算第一步→最后一步)、细分分析(从曝光事件读取数据,而非指标事件)、“收入总和”的用户均值混淆,以及录屏面板与统计结果的差异。
$multiple→ 查看references/numbers-vs-sql.md
E — Surprises after mid-run changes (incl. lifecycle and retention quirks)
E — 中途变更后的意外情况(包括生命周期和留存异常)
Increasing rollout is safe; decreasing is caution; changing the variant split is an anti-pattern; adding
metrics mid-run is p-hacking; ship-variant can rewrite the flag in surprising ways; reset clears
results not the flag. Also covers retention-metric quirks (first-event-must-be-after-exposure design),
"matured users" filtering, and long-term vs short-term metric divergence.
→ See references/mid-run-changes.md
提高发布比例是安全的;降低发布比例需谨慎;修改变体拆分是反模式;中途添加指标属于p-hacking;发布变体可能会以意外方式改写标志;重置操作会清除结果但不会重置标志。还涵盖留存指标异常(设计要求首次事件必须在曝光后)、“成熟用户”筛选,以及长期与短期指标的差异。
→ 查看references/mid-run-changes.md
Step 4 — Calibrate recommendations to experiment state
步骤4 — 根据实验状态调整建议
Surface diagnostics first (Step 3). Then recommend — but scope what you recommend to what the
experiment's current state permits.
- Draft — config changes are free; recommend and apply.
- Running — every change has a tradeoff. Explain the mid-run impact (anti-pattern? safe?
user-visible?) before recommending. See and its reference file
configuring-experiment-rolloutfor the mid-run rules.references/changing-distribution-after-launch.md - Stopped / archived — the experiment AND its feature flag represent the documented outcome of the run. Recommendations are scoped to (a) interpretation of the existing data, (b) what to do for the next experiment, or (c) explaining what happened.
On a stopped or archived experiment, don't preemptively offer reversal of a state mutation
(ship-variant flag rewrite, manual flag edit, reset, archive). If the user asks "why did X happen?",
explain X — don't append a "here's how to undo it" coda. That pattern assumes intent the user didn't
signal. Conditional offers like "if this wasn't intended, you could…" or "want me to revert it?"
count as preemptive too — only the user explicitly naming the reversal action ("how do I undo this?",
"can I roll back ship-variant?", "how do I get the 50/50 split back?") is a request to surface
reversal mechanics.
Use consistent terminology: variant split (between variants) is distinct from rollout (overall %
entering); the exposure event is distinct from a custom exposure event; the
Exclude / First seen options control multivariate handling, not exposure.
$feature_flag_called先列出诊断方案(步骤3)。然后给出建议,但建议范围需符合实验当前状态的限制。
- 草稿状态 — 可自由修改配置;直接给出并应用建议。
- 运行状态 — 任何修改都有取舍。给出建议前需说明中途修改的影响(反模式?安全?对用户可见?)。查看及其参考文件
configuring-experiment-rollout获取中途修改规则。references/changing-distribution-after-launch.md - 已停止 / 已归档 — 实验及其功能标志代表本次运行的既定结果。建议范围限于(a) 现有数据的解读,(b) 下一次实验的操作建议,或(c) 解释已发生的情况。
对于已停止或已归档的实验,请勿主动提供状态变更的撤销方案(发布变体后的标志改写、手动编辑标志、重置、归档)。如果用户询问“为什么会发生X?”,只需解释X——不要附加“以下是撤销方法”的内容。这种模式会假设用户有未明确表达的意图。类似“如果这并非有意操作,你可以……”或“需要我帮你撤销吗?”的条件性提议也属于主动提供,只有当用户明确提及撤销操作(“如何撤销?”、“能否回滚发布变体的操作?”、“如何恢复50/50的拆分比例?”)时,才需提供撤销机制。
使用统一术语:变体拆分(变体之间的比例)与发布比例(进入实验的整体用户占比)是不同的;曝光事件与自定义曝光事件是不同的;Exclude / First seen选项控制多变量处理,而非曝光。
$feature_flag_called