ab-test
Skill9 starsChanged 6 months agoMITView on GitHub
USE when you have A/B test results and need rigorous statistical analysis. Validates experiment integrity (SRM at 3 levels, novelty effect, peeking), computes two-proportion z-test with CI (+ Fisher exact for low counts), checks MCID (practical significance ≠ statistical), multiple comparisons correction, and gives a Ship/Extend/Stop/Investigate verdict with evidence markers. Integrates with rules/estimand-ops.md — MCID required before analysis. Triggers: /ab-test, a/b test, проанализируй эксперимент, результаты теста, split test, experiment results, A/B анализ, significance, конверсия. [STATUS: review] [CONFIDENCE: high] [REVIEWED: 2026-08-13]
6 other projects use a version of this.
Adopted by
Most recently taken up by
- ali-demirbas/ab-test-playbooktheir own version, first seen Oct 21, 2026
- m-binimran/marketing-packtheir own version, first seen Oct 15, 2026
- akachandan1/proofstacktheir own version, first seen Oct 11, 2026
- sidchaudhary/gtm-skillstheir own version, first seen Aug 21, 2026
- Aetheria-Labs1/storefront-skillstheir own version, first seen Aug 7, 2026
- BlackBlazeXXX/claude-skills-marketingtheir own version, first seen Mar 31, 2026
Used with
Projects with it also use email-sequence.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
AnthropicSkillemail-sequence
Design and draft multi-email sequences with full copy, timing, branching logic, exit conditions, and performance benchmarks. Use when building onboarding, lead nurture, re-engagement, win-back, or product launch flows, when you need a complete drip campaign with A/B test suggestions, or when mapping a sequence end-to-end with a flow diagram.
Also in 3 projects that use this
Other versions6 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 6
- Aetheria-Labs1/storefront-skills★ 8same name
- BlackBlazeXXX/claude-skills-marketing★ 1same name
- m-binimran/marketing-pack★ 1same name
- sidchaudhary/gtm-skills★ 1same name
- akachandan1/proofstack★ 0same name
- ali-demirbas/ab-test-playbook★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository164 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .codex/AGENTS.mdAGENTS.md
- agents/CLAUDE.mdCLAUDE.md
- CLAUDE.mdCLAUDE.md
- claude-md/CLAUDE.mdCLAUDE.md
- hooks/CLAUDE.mdCLAUDE.md
- insight-architectSkill
- agent-teamsSkill
- brainstormingSkill
- claim-decomposerSkill
- context-engineeringSkill
- dispatcherSkill
- git-worktreesSkill
- hd-mavp-routerSkill
- mentor-modeSkill
- reference-registrySkill
- routing-policySkill
- skill-self-updateSkill
- tdd-workflowSkill
- academic-researchSkill
- advanced-methodology-extensionsSkill
- agent-governanceSkill
- ai-hyp-gateSkill
- algorithm-designSkill
- analystSkill
- archcode-genomicsSkill
- arm-cortex-microcontrollersSkill
- atomizeSkill
- backward-traceabilitySkill
- boyko-constraint-engineSkill
- boyko-epistemic-auditSkill
- boyko-goal-expansion-100Skill
- boyko-knowledge-architectureSkill
- boyko-leverage-mapSkill
- boyko-methodSkill
- boyko-preflightSkill
- boyko-project-radarSkill
- boyko-rippleSkill
- boyko-scientific-consortiumSkill
- boyko-specialistSkill
- boyko-toolcheckSkill
- boyko-triangle-auditSkill
- boyko-why-ladderSkill
- browser-actSkill
- build-autoSkill
- c4-architectureSkill
- career-prepSkill
- changelog-genSkill
- citation-managementSkill
- code-debuggingSkill
- code-materialitySkill
- codex-skepticSkill
- codex-solverSkill
- codex-tracySkill
- combinatorial-creativitySkill
- common-groundSkill
- conductorSkill
- consilienceSkill
- construct-measurement-gateSkill
- convertSkill
- The first 60 shown.
The file
Files
<!-- BSV — Brief Skill View | поиск: BSV
Скил : ab-test
TL;DR : Статистически строгий анализ A/B теста с MCID, peeking guard и evidence markers
Вызов : `/ab-test`, 'проанализируй эксперимент', 'результаты A/B теста'
НЕ для : Дизайна теста до запуска (→ /experiment-design), causality без рандомизации
-->/ab-test — A/B Test Analysis
No integrity, no inference. Если рандомизация или логирование сломаны — статистический вывод запрещён независимо от p-value.
Когда использовать
- Есть результаты рандомизированного эксперимента (A/B, A/A, multivariate)
- Нужно решение: пускать в прод / продлить / остановить
- Требуется доказуемость с evidence markers ([VERIFIED-REAL])
НЕ использовать:
- Для дизайна теста до запуска →
/experiment-design - Для observational data без рандомизации → добавить causal layer (rules/estimand-ops.md)
- Для последовательного анализа без pre-registration → секция "peeking guard" ниже
Step 0 — Estimand (до любых расчётов)
Из rules/estimand-ops.md — заполнить до просмотра данных:
Population: [кто именно, inclusion/exclusion criteria]
Intervention: [variant — точное описание изменения]
Comparator: [control]
Endpoint: [primary metric — конкретная, с единицами]
MCID: [минимальное практически значимое изменение, напр. +0.5% conversion]
ICE: [intercurrent events — что делать с drop-outs, технические сбои]
Secondary metrics: [явно перечислить + пометить exploratory если не pre-specified]Жёсткое правило: MCID должен быть задан ДО просмотра результатов. Если MCID неизвестен → остановись, договорись с командой, только потом анализируй.
Step 1 — Integrity Gate
Пройти все три уровня SRM и оба поведенческих check. Если хоть одна проверка провалена — STOP, вердикт = INVALID.
1a. Sample Ratio Mismatch (SRM) — три уровня
SRM нужно проверять на каждом уровне отдельно: баг может быть не в рандомизации, а в логировании событий.
from scipy.stats import chisquare
def check_srm(observed_c, observed_v, expected_split=0.5, label=""):
total = observed_c + observed_v
exp_c = total * expected_split
exp_v = total * (1 - expected_split)
chi2, p = chisquare([observed_c, observed_v], f_exp=[exp_c, exp_v])
status = "⚠️ SRM DETECTED — STOP" if p < 0.01 else "OK"
print(f"SRM [{label}]: χ²={chi2:.3f}, p={p:.4f} → {status}")
return p
# Уровень 1: Assignment (рандомизация при попадании в тест)
p_srm_assign = check_srm(n_assigned_c, n_assigned_v, label="assignment")
# Уровень 2: Exposure (пользователи которые реально увидели вариант)
p_srm_exposure = check_srm(n_exposed_c, n_exposed_v, label="exposure")
# Уровень 3: Analysis population (после фильтров inclusion criteria)
p_srm_analysis = check_srm(n_analysis_c, n_analysis_v, label="analysis")Интерпретация:
- SRM на уровне assignment → баг в рандомизации или assignment логике
- SRM на уровне exposure → баг в feature flag / rollout системе
- SRM только на уровне analysis → баг в event logging или post-hoc фильтрации
Любой SRM p < 0.01 → STOP. Найти уровень, найти причину, починить до анализа.
1b. Novelty Effect Check
- Тест шёл менее 2 полных business cycles (обычно 2 недели)?
- Первые 3 дня показывают аномальный spike в variant?
Если да → разбить данные по неделям. Если week1 >> week2 → novelty effect, нужно продлить.
1c. Peeking Guard
Смотрел ли кто-то на p-value до окончания теста и принял решение остановить?
Если ДА и тест остановлен при p < 0.05:
Uncontrolled repeated peeking inflates Type I error well above 0.05 —
potentially toward ~0.30 depending on monitoring frequency,
stopping behavior, and total sample size.
(Точная инфляция зависит от числа просмотров и stopping rule.)
Решение:
(a) применить sequential correction (mSPRT / alpha-spending function)
(b) зафиксировать как "exploratory only", не production decisionStep 2 — Statistical Test
2a. Low-count check (сначала)
# Если ожидаемых событий мало — z-test ненадёжен
# ВАЖНО: n_c, conv_c, n_v, conv_v — введи свои данные здесь
n_c = <n control>
conv_c = <conversions control>
n_v = <n variant>
conv_v = <conversions variant>
rate_c = conv_c / n_c
rate_v = conv_v / n_v
p_pool = (conv_c + conv_v) / (n_c + n_v) # определяем здесь — нужен и в 2b и в 2d
expected_c_pos = n_c * p_pool
expected_c_neg = n_c * (1 - p_pool)
expected_v_pos = n_v * p_pool
expected_v_neg = n_v * (1 - p_pool)
if min(expected_c_pos, expected_c_neg, expected_v_pos, expected_v_neg) < 5:
print("⚠️ Low expected counts (<5 per cell) — use Fisher exact or Bayesian")
USE_FISHER = True
else:
USE_FISHER = False2b. Two-proportion z-test (если USE_FISHER = False)
import numpy as np
from scipy import stats
# n_c, conv_c, n_v, conv_v, rate_c, rate_v, p_pool — определены в 2a
lift_rel = (rate_v - rate_c) / rate_c
lift_abs = rate_v - rate_c
# Two-proportion z-test (pooled SE для p-value)
se = np.sqrt(p_pool * (1 - p_pool) * (1/n_c + 1/n_v))
z = (rate_v - rate_c) / se
p_value = 2 * (1 - stats.norm.cdf(abs(z))) # two-tailed
# 95% CI (unpooled SE для интервала)
se_ci = np.sqrt(rate_c*(1-rate_c)/n_c + rate_v*(1-rate_v)/n_v)
ci_low = lift_abs - 1.96 * se_ci
ci_high = lift_abs + 1.96 * se_ci
print(f"Control: {rate_c:.4f} ({conv_c}/{n_c})")
print(f"Variant: {rate_v:.4f} ({conv_v}/{n_v})")
print(f"Lift: {lift_rel:+.2%} rel ({lift_abs:+.4f} abs)")
print(f"p-value: {p_value:.4f}")
print(f"95% CI: [{ci_low:+.4f}, {ci_high:+.4f}]")CI vs p-value (не баг — корректно): p-value считается на pooled SE (под H₀: p₁=p₂), а 95% CI — на unpooled SE (оценка реальной разности). У границы значимости они могут слегка расходиться (CI включает 0 при p чуть < 0.05, или наоборот). Это ожидаемо: p-value — для решения о H₀, CI — для величины эффекта. Не «подгонять» один под другой.
2c. Fisher exact (если USE_FISHER = True)
from scipy.stats import fisher_exact
from statsmodels.stats.proportion import proportion_confint
odds_ratio, p_fisher = fisher_exact([[conv_c, n_c - conv_c],
[conv_v, n_v - conv_v]])
ci_c = proportion_confint(conv_c, n_c, method='wilson')
ci_v = proportion_confint(conv_v, n_v, method='wilson')
print(f"Fisher p: {p_fisher:.4f}")
print(f"Wilson CI control: {ci_c}")
print(f"Wilson CI variant: {ci_v}")2d. Power Check (если p ≥ α)
from statsmodels.stats.power import NormalIndPower
from statsmodels.stats.proportion import proportion_effectsize
mcid = <твой MCID как абсолютная разница>
# Cohen's h — корректный effect size для двух пропорций
# (точнее приближения mcid/√(p(1−p)); h = 2·arcsin√p1 − 2·arcsin√p2)
effect_size = proportion_effectsize(rate_c + mcid, rate_c)
# ВАЖНО: параметр называется nobs1 (не n_obs) — иначе TypeError
power = NormalIndPower().power(effect_size, nobs1=min(n_c, n_v), alpha=0.05)
print(f"Power для MCID={mcid}: {power:.2f}")
# power < 0.80 → тест был underpowered, нельзя делать вывод о null
# Null bound (rules/estimand-ops.md, Design Detectability): numeric MDE in both directions,
# computed on the analysed n and the observed baseline; power 0.80, alpha 0.05 two-sided
import numpy as np
n_arm = min(n_c, n_v)
h_mde = NormalIndPower().solve_power(nobs1=n_arm, alpha=0.05, power=0.80, ratio=1.0) # Cohen's h at 80% power
phi = np.arcsin(np.sqrt(rate_c))
mde_up = np.sin(phi + h_mde / 2) ** 2 - rate_c if phi + h_mde / 2 <= np.pi / 2 else None # None = undetectable
mde_down = rate_c - np.sin(phi - h_mde / 2) ** 2 if phi - h_mde / 2 >= 0 else None # None = undetectable2e. Multiple Comparisons Correction
Если тестировались несколько метрик или несколько вариантов:
Проблема: при 10 метриках вероятность хотя бы одного ложно-позитивного результата ≈ 1 − 0.95¹⁰ = 40% при α=0.05.
Правило:
- Primary metric: pre-specified, без коррекции.
- Secondary metrics (pre-specified): применить Holm-Bonferroni.
- Secondary metrics (post-hoc): пометить
[EXPLORATORY], не для production decisions. - Multiple variants (k вариантов): скорректировать α = 0.05 / (k − 1).
from statsmodels.stats.multitest import multipletests
# p_values — список p-value для pre-specified secondary метрик
p_values = [p_metric1, p_metric2, p_metric3]
reject, p_corrected, _, _ = multipletests(p_values, method='holm')
for i, (r, pc) in enumerate(zip(reject, p_corrected)):
print(f"Metric {i+1}: p_corrected={pc:.4f} → {'REJECT H0' if r else 'FAIL TO REJECT'}")Step 3 — Guardrail Metrics
Для каждой guardrail metric (revenue, latency, retention, error rate):
| Metric | Control | Variant | Δ | Статус |
| Primary metric | X | Y | +Z% | ✅/❌ |
| Revenue per user | X | Y | Δ | ✅/⚠️/❌ |
| Page load time | X | Y | Δ | ✅/⚠️/❌ |
| Error rate | X | Y | Δ | ✅/⚠️/❌ |
⚠️ = деградация ≥ MCID guardrail → флаг для Investigate
Step 4 — Verdict
| Условие | Вердикт |
| p < α AND lift_abs ≥ MCID AND все guardrails OK | ✅ SHIP |
| p < α AND lift_abs < MCID (статистически значимо но не практически) | ⚠️ STOP — ниже MCID |
| p ≥ α AND power ≥ 0.80 | ⛔ STOP — не обнаружено при MDE из Null bound (рост и падение, n и baseline указаны); «эффекта нет» не утверждается |
| p ≥ α AND power < 0.80 | ⏳ EXTEND — underpowered, продолжить |
| p < α AND guardrail деградировал | 🔍 INVESTIGATE — трейдофф требует решения |
| SRM detected (любой уровень) | 🚫 INVALID — устранить до решения |
| Peeking без коррекции | 🚫 INVALID — пометить exploratory или применить mSPRT |
Step 5 — Отчёт с Evidence Markers
## A/B Test: [название]
Период: [дата старт — дата конец]
Данные: [источник — [VERIFIED-REAL] с URL/путём к данным]
### Integrity
- SRM assignment: p=X → OK / ⚠️ DETECTED [VERIFIED-REAL]
- SRM exposure: p=X → OK / ⚠️ DETECTED [VERIFIED-REAL]
- SRM analysis: p=X → OK / ⚠️ DETECTED [VERIFIED-REAL]
- Novelty effect: [проверен / не применимо]
- Peeking: [не было / был → скорректирован mSPRT / помечен exploratory]
- Low counts: [N/A / Fisher exact использован]
### Results
- Control: {rate_c:.4f} (n={n_c})
- Variant: {rate_v:.4f} (n={n_v})
- Lift: {lift_rel:+.2%} | 95% CI: [{ci_low:+.4f}, {ci_high:+.4f}]
- p-value: {p_value:.4f} (α=0.05) [VERIFIED-REAL]
- MCID: {mcid} → EXCEEDED / NOT REACHED
- Null bound: [не обнаружено при MDE: рост = {mde_up}, падение = {mde_down} (абс.; None = undetectable, неинформативно при этом n); n={n_arm}, baseline={rate_c:.4f}, alpha=0.05 two-sided, power=0.80] / [N/A — результат не нулевой]
- Multiple comparisons: [N/A / Holm corrected / secondary marked exploratory]
### Guardrails
[таблица из Step 3]
### Verdict: [SHIP / EXTEND / STOP / INVESTIGATE / INVALID]
Reason: [одно предложение]
### What This Does NOT Mean
1. Не доказывает причинно-следственную связь если A/B не был полностью рандомизирован
2. Не гарантирует результат на 100% трафика (Simpson's paradox по сегментам)
3. Не применимо для пользователей вне inclusion criteria теста
4. Secondary / post-hoc метрики помечены [EXPLORATORY] — не для production decisionsИнтеграция с нашим стеком
- Estimand →
rules/estimand-ops.md(MCID, ICE, population definition) - Evidence markers →
rules/evidence-markers.md([VERIFIED-REAL] обязателен) - Skeptic trigger: если lift = round number (50%, 100%) → auto-trigger rule 4
- Causal layer: если данные не из рандомизированного эксперимента → остановись,
требуется DAG + identifiability check (
rules/estimand-ops.md§Causal Layer)
Принцип всего скилла:
No integrity, no inference.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

