关于 managing-experiment-lifecycle
该技能说明实验生命周期各操作的状态变化,以及它们对变体分配和分析数据的影响,面向管理 PostHog 实验的 Agent。涵盖冻结曝光、发布变体、复制和清理等操作的前置条件与注意事项。
主要功能
- 01说明实验状态转换
- 02解释变体分配与数据分析影响
- 03列出各操作的前置条件
- 04涵盖冻结与恢复曝光
- 05介绍复制、归档和清理流程
适用场景
- 01判断何时暂停或结束实验
- 02在持续测量时停止新用户加入
- 03发布胜出变体前确认影响
- 04将实验复制到其他项目
MCP 相关
提供 PostHog 实验生命周期工具的操作指导,包括 launch、pause、end、ship variant 等操作;本身不声明 MCP 服务端能力。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ posthog/ skills --skill managing-experiment-lifecycle安装后在 Claude Code 中输入/managing-experiment-lifecycle确认已加载。
详细介绍
管理实验生命周期
本技能介绍实验状态转换——每项操作的作用、适用时机,以及对变体分配和分析的影响。
状态图
draft ──launch──▶ running ──end──▶ stopped ──archive──▶ archived
│ │ ▲ │
│ pause resume ship_variant
│ │ │ (also ends if running)
│ ▼ │
│ paused (flag inactive, still "running" status)
│
├─freeze_exposure──▶ exposure_frozen ──unfreeze_exposure──▶ running
│ (enrollment closed, metrics keep flowing)
Any non-draft state ──reset──▶ draft
操作及其影响
对于每项操作,有两个关键问题:
- 谁会看到哪个变体?(用户视角)
- 谁会纳入我的分析?(统计视角)
启动(experiment-launch)
将状态从草稿转换为运行中。启用功能标志并设置 start_date。
- 前置条件:必须处于草稿状态;标志需要有 2–20 个多变量变体(无需指定特定键;如果存在名为 "control" 的基线变体,则默认使用它,否则使用第一个变体)
- 启动前检查清单:是否至少有一个指标?变体是否正确?标志是否已在代码中实现?
- 变体:用户开始根据配置的流量分配比例进入各个变体
- 分析:从
start_date开始收集数据
无需请求正文。
仅在启动时提及一次值得考虑的可选事项:当更改对用户可见且影响较大时,可添加一份简短调查问卷,在用户完成实验流程时显示(例如由表单提交事件触发),从第一天起就与指标一同收集定性反馈(评分和可选评论)。将其作为设置建议提供一次;如果用户拒绝,就不再提及,也绝不能因此延迟启动。不要在实验结束或发布变体时提及这项建议——那样会让它看起来像是发布的门槛。→ 参见 [[diagnosing-experiment-health]] 中的 references/qualitative-feedback.md
暂停(experiment-pause)
停用功能标志。用户将回退到默认体验(通常为 control)。
- 前置条件:必须处于运行中且尚未暂停
- 变体:
/decide不会返回该标志——不会记录新的曝光事件 - 分析:暂停期间不会产生新数据,但现有数据会保留。实验仍保持“运行中”状态。
无需请求正文。使用 experiment-resume 重新启用。
恢复(experiment-resume)
暂停后重新启用功能标志。用户会被确定性地重新分配到相同的变体。
- 前置条件:必须处于暂停状态
- 变体:与暂停前的分配相同——确定性分桶
- 分析:恢复曝光跟踪
无需请求正文。
冻结曝光(experiment-freeze-exposure)
停止招募新用户,同时其他一切照常进行:已加入实验的用户保留其变体,指标继续流入,end_date 保持为 null。
将已曝光用户快照为静态队列,并将功能标志的所有发布条件收窄至该队列。
状态变为 exposure_frozen。
当长期指标(收入、LTV、留存率、续订)所需的样本量已经足够,且你想停止添加用户但继续测量时,可使用此操作。
结束或暂停都不适合这种情况:结束会在 end_date 停止测量,暂停则会为所有人停用功能标志。
- 前提条件:必须处于运行状态(不能是草稿、已停止、已暂停或已冻结),功能标志必须已关联且未删除,并且至少有一个发布条件
- 变体:已加入实验的用户保留其变体(确定性分桶);新用户将不再匹配该功能标志
- 分析:曝光量不再增长(预期曝光曲线会趋于平缓),但已加入实验用户的指标数据仍会累积
耗时:曝光扫描和队列快照会在 API 调用中同步运行,耗时随已曝光人数增加而增加——有数万名已曝光用户的实验可能需要几十秒。 请向用户说明预期耗时,等待响应,不要将缓慢的调用视为失败或重试。
不适用(400)的情况:
- 按组聚合的实验——功能标志针对的是群组,而非个人;个人队列无法冻结基于群组的匹配
- 处于保留组中的实验——保留组分配在发布条件之前进行评估,因此新用户仍会进入保留组
- 带有提前访问条件的功能标志——此类条件也在发布条件之前进行评估,因此冻结无法阻止新用户加入
- 以匿名曝光为主的实验(例如,针对已登出界面的实验)——匿名的“无个人”用户永远无法匹配个人队列,因此会悄然失去其变体;未解析占比超过较小比例的冻结请求会被拒绝
- 已曝光用户数过多——曝光扫描受个人数量上限和超时时间限制;超过任一限制时,API 会返回明确的 400,而不会执行冻结
冻结请求被拒绝时,请说明适用的限制,而不要重试——这些限制属于结构性限制,并非暂时性问题。
与其他操作的交互:发布变体和重置会移除冻结(两者也会删除快照队列);结束操作不会更改功能标志,因此结束已冻结的实验后,功能标志仍会限定为快照队列。
使用本地评估的 SDK 无法解析静态队列,因此冻结后的功能标志会通过 /decide 端点进行评估(这是静态队列的标准行为)。
冻结前最后时刻摄入的曝光数据可能赶不上快照(摄入延迟)。
无需请求正文。使用 experiment-unfreeze-exposure 重新开放招募。
解冻曝光(experiment-unfreeze-exposure)
重新开放已冻结曝光实验的招募。
从每个发布组中移除快照队列条件和冻结标记,恢复功能标志原先的定向规则,并删除快照队列。
状态恢复为 running。
- 前提条件:曝光必须处于冻结状态(且实验尚未结束)
- 变体:已加入实验的用户保留其变体;新用户可以再次根据原始发布条件加入实验
- 分析:曝光量恢复增长
可能引入偏差:重新开放招募会使功能标志面向一批可能不同的新用户。 冻结前加入的用户和解冻后加入的用户是在不同时间加入的,且可能处于不同条件下——在同一分析中混合这两个队列可能会使结果产生偏差。 解冻前请提醒用户,尤其是在冻结时间较长,或期间受众或产品发生变化时。如果用户只是想检查冻结后的结果,可能根本不需要解冻。
无需请求正文。
结束实验(experiment-end)
设置 end_date 并将实验转换为已停止状态。不会修改功能标志。
- 前置条件:实验必须正在运行(已启动,且尚未停止)
- 变体:用户继续看到已分配的变体(标志保持激活)
- 分析:结果冻结为截至
end_date的数据
可选请求正文:conclusion(“won”、“lost”、“inconclusive”、“stopped_early”、“invalid”)和 conclusion_comment。
如果你想冻结结果,同时不改变用户看到的内容,请使用此操作。 如果实验的曝光已被冻结,结束实验不会解除冻结——标志仍会限定在快照用户群中(如果不希望如此,请先解除冻结或发布某个变体)。
发布变体(experiment-ship-variant)
重写功能标志,让所有用户(100%)都看到所选变体。
- 前置条件:实验必须已启动(正在运行或已停止)。不能从草稿状态发布。
- 变体:所有用户都能看到已发布的变体。标志会通过全匹配组进行重写。
- 分析:如果实验仍在运行,也会同时结束实验(设置
end_date)
发布前务必先与用户确认——这会永久重写功能标志。
必填:variant_key(例如“test”)。可选:conclusion、conclusion_comment。
如果审批策略要求在变更标志前进行审核,则返回 409。
标志清理 PR(结束实验和发布变体时的可选项)
experiment-end 和 experiment-ship-variant 均接受 open_cleanup_pr: true。
随后,后台 PostHog Code 任务会移除实验的功能标志代码,并在团队关联的 GitHub 代码库中创建一个草稿拉取请求。
- 仅在用户提出要求或确认后才设置此项。
- 调用方必须具有
task:write范围;否则整个请求会被拒绝并返回 403,且实验不会结束或发布。 - 只有当调用实际结束实验且设置了
conclusion时,才会执行清理——发布一个已停止的实验,或在未设置结论的情况下结束实验,都会跳过清理。此外,团队必须启用标志清理功能;未启用时会静默跳过。 repository(“organization/repository”)用于在关联了多个代码库时选择目标。省略时,将依次使用实验中保存的代码库、团队默认代码库或唯一关联的代码库。如果有多个候选代码库且没有默认值,除非提供此参数,否则会跳过清理。- 使用
experiment-cleanup-task跟踪进度——PR 创建后,其 URL 会显示在此处;清理通常需要几分钟。
归档(experiment-archive)
在默认列表视图中隐藏已停止的实验。
- 前置条件:实验必须已停止(已设置
end_date) - 变体:无变化——不影响标志
- 分析:无变化——仍可访问结果
不需要请求正文。可通过 experiment-update 将 archived=false 恢复。
重置(experiment-reset)
将实验恢复为草稿状态。清除 start_date、end_date、conclusion 和 archived。
- 前置条件:实验当前不能处于草稿状态
- 变体:标志保持不变——用户继续看到已分配的变体
- 分析:之前收集的数据仍然存在,但除非在重新启动后调整
start_date,否则不会纳入结果
不需要请求正文。
复制(experiment-duplicate)
以新的草稿形式创建副本,使用新的日期且不包含结果。
重要:务必提供一个不同于原实验的唯一 feature_flag_key。如果使用相同的键,两个实验将共用一个标志——其中一个实验的变更会影响另一个。
可选:自定义 name(默认为“Original Name (Copy)”)。
复制到项目(experiment-copy-to-project)
将实验复制为新的草稿,放入同一组织中的其他项目。如果要复制到其他项目,请使用此功能,而不是
experiment-duplicate;如果复制后仍留在同一项目中,则使用 duplicate。
- 前置条件:源实验不能使用旧版指标;目标项目必须属于同一组织,并且你必须拥有该项目的写入权限。不能跨组织或区域复制。
- 复制内容:名称、描述、类型、参数、筛选条件、主要/次要指标(使用新的 uuid)、统计信息和排期配置、曝光条件。不复制的内容:已保存的指标引用(限定于项目)、留出组、曝光群组、日期、结果、结论。
- 功能标记:必须提供
target_team_id;feature_flag_key可选。随后会在目标项目中查找解析后的标记键;决定后续操作的是查找结果,而不是你是否传入了标记键:- 如果省略
feature_flag_key:默认使用_源_实验的标记键。该键通常不存在于目标项目中,因此会在目标项目中创建一个使用该键的新标记。(默认键仍可能冲突,见下一条;因此,为确保安全,请传入明确的键。) - 如果解析后的键已作为标记存在于目标项目中:复制后的实验会共享该现有标记,而不是创建新标记。两个实验随后会指向同一个标记,因此,对任一实验执行生命周期操作(发布、暂停)都会影响两者。现有标记必须是包含 2-20 个变体的多变量标记,否则调用会返回 400。
- 如果解析后的键在目标项目中不存在:会使用该键创建一个新的独立标记。若要确保标记彼此独立,请传入目标项目中尚不存在的
feature_flag_key。
- 如果省略
调用前,请通过名称确认源实验和目标项目——这会向用户当前未查看的项目写入内容。返回的实验(及其 id)属于目标项目。
迁移到新引擎(experiment-migrate)
将旧版实验(is_legacy: true,指标类型为 ExperimentTrendsQuery 或 ExperimentFunnelsQuery)迁移到新版实验引擎。
切勿手动实现此流程。
创建新实验并复制指标会生成第二个功能标记,因此新实验一开始没有曝光量和数据。
experiment-migrate 会复用原始标记,因此迁移后的实验从第一分钟起就会保留原有受众。
- 前置条件:实验必须是旧版实验。如果实验已使用新引擎,400 响应会说明这一点。
- 迁移后的结果:会创建一个配置相同、指标已转换为新格式的新实验。旧版实验保持不变,因此项目最终会有两个实验共用一个功能标记。旧版实验不再显示结果,因此迁移是查看该实验结果的唯一方法。
- 旧版共享指标:会在同一次调用中转换。每个指标都会生成一个新的共享指标,供迁移后的实验关联。
- 变体:保持不变——标记是共享的,因此用户仍会保留当前所处的变体。
- 分析:迁移后的实验会读取相同的曝光量。结果由新引擎计算,因此数值可能与旧版视图之前显示的不同。
调用前请告知用户将会有两个实验,并在调用后链接到两者。 再次调用会返回首次调用创建的实验,因此重试是安全的。
不需要请求体。
旧版实验也不允许进行大多数编辑:experiment-update 对名称、描述和 end_date 以外的任何修改都会返回 400。
这三项仍可在旧版实验上修改,因此请直接编辑,不要为此迁移。
仅在用户提出迁移要求、想查看该实验的结果,或要求修改被限制的字段时才进行迁移。将该修改应用到迁移后的实验。
决策框架
| 情况 | 操作 | 工具 |
|---|---|---|
| 草稿已准备就绪、标记已实现、指标已设置 | 启动 | experiment-launch |
| 已有明确胜出方案,且结果显著 | 发布胜出变体 | experiment-ship-variant |
| 经过足够时间后仍无显著差异 | 以结果不确定结束 | experiment-end |
| 出现问题,需要暂时停止曝光 | 暂停 | experiment-pause |
| 暂停后继续 | 恢复 | experiment-resume |
| 停止招募新用户,但继续衡量已加入用户的表现 | 冻结曝光 | experiment-freeze-exposure |
| 冻结后重新开放招募 | 取消冻结曝光 | experiment-unfreeze-exposure |
| 实验已结束,准备清理 | 归档 | experiment-archive |
| 需要使用相同配置重新开始 | 重置为草稿 | experiment-reset |
| 想要从头开始进行类似实验 | 复制 | experiment-duplicate |
| 想在其他项目中进行相同实验 | 复制到其他项目 | experiment-copy-to-project |
| 实验使用旧版引擎,需要迁移到新引擎 | 迁移 | experiment-migrate |
解析实验
所有生命周期操作都需要实验 ID。如果你没有实验 ID,请先加载
finding-experiments 技能,将用户提到的内容(名称、描述、
“最新”等)解析为具体 ID,再继续操作。
错误处理
| 错误消息 | 含义 |
|---|---|
| "Experiment has already been launched." | 无法启动非草稿状态的实验 |
| "Experiment has not been launched yet." | 无法结束、暂停或发布草稿实验 |
| "Experiment has already ended." | 无法结束或暂停已停止的实验 |
| "Experiment is already paused." | 请改用恢复操作 |
| "Experiment is not paused." | 实验已处于活动状态 |
| "Experiment is already in draft state." | 无需重置 |
| "Experiment is already archived." | 已完成 |
| "Experiment exposure is already frozen." | 无需冻结 |
| "Experiment exposure is not frozen." | 无需取消冻结 |
| "Cannot freeze a paused experiment. Resume it first." | 先恢复,再冻结 |
| "Group-aggregated experiments cannot have their exposure frozen." | 结构性限制 — 请勿重试 |
| "This experiment uses legacy metric formats..." | 请先迁移 — experiment-migrate |
收到 400 错误时,请向用户说明情况,而不是重试。
相关技能
creating-experiments— 从头创建下一个实验diagnosing-experiment-health— 在决定发布或结束实验前,对结果进行合理性检查configuring-experiment-rollout— 拆分并发布变更;这是配置编辑,而非生命周期操作