关于 experiment-stop
experiment-stop 是用于停止 GrowthBook 标准 A/B 测试并可选声明胜出变体的技能,面向管理实验的用户。它要求用户明确选择胜出变体,并可通过临时发布将流量导向该变体。
主要功能
- 01查询并核验实验状态
- 02按变体 ID 选择胜者
- 03停止运行中的实验
- 04可选启用临时发布
- 05提示关联功能标记的后续处理
适用场景
- 01结束正在运行的标准 A/B 测试
- 02记录实验结果与分析说明
- 03停止实验并将流量临时导向胜出变体
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ growthbook/ skills --skill experiment-stop安装后在 Claude Code 中输入/experiment-stop确认已加载。
详细介绍
experiment-stop
停止正在运行的实验,可选择声明获胜变体,并通过临时发布将其推广到所有符合条件的流量。此端点为 POST /api/v1/experiments/<id>/stop(专用端点,不是通用更新端点)。所有变体引用都是变体 ID 字符串,例如 var_abc123,不是从 0 开始的整数索引。
所有 API 调用都通过捆绑的辅助程序:${CLAUDE_PLUGIN_ROOT}/scripts/gb-call。它需要 GB_API_KEY——在 shell 中设置,或由 /growthbook:gb-setup 写入 ~/.config/growthbook/.env。如果未设置或无效,gb-call 的错误消息会提示你返回 /growthbook:gb-setup。
工作流
-
获取当前实验。
gb-call GET /api/v1/experiments/<experiment-id>如果用户给出的是名称而非 ID(“停止结账测试”),请先解析名称——
q会匹配名称、跟踪键、描述和假设,status=running则会将候选项限定为此技能可操作的实验:gb-call GET '/api/v1/experiments?q=checkout&status=running'如果有多个实验都可能匹配,请列出候选项并让用户选择——不要猜测。停止错误的实验无法轻易撤销。
检查
status字段。只有running状态的实验才能通过此技能停止。如果status === "draft",说明实验尚未开始——用户想要的是删除,而不是停止(这是不同的操作)。如果status === "stopped",说明实验已经结束。同时获取
type字段。如果type === "multi-armed-bandit",请暂停并告知用户此技能面向标准 A/B 测试;老虎机实验有自己的生命周期(停止操作类似,但解读和发布有所不同——建议用户先在 UI 中查看,再编写脚本)。 -
向用户展示变体表格。 按 API 记录的内容呈现变体——获取每个变体的
variationId(字符串 ID,例如var_treatment_a)和name。用户应通过变体 ID 字符串选择,而不是通过索引:The experiment has these variations: var_control 0: Control — <description> (lift: baseline, users: N) var_treatment_a 1: Treatment A — <description> (lift: +2.3%, users: N) var_treatment_b 2: Treatment B — <description> (lift: -0.8%, users: N) Which variation should ship? Reply with the variation ID (e.g. var_treatment_a), or say "no winner" to stop without declaring.如果用户还没有运行
experiment-analyze,建议先运行,以便基于充分信息做出决定。 -
决定是否进行临时发布。 如果用户已有获胜变体并想立即上线,请提供临时发布选项:
“要我同时启用临时发布吗?这会让此实验继续保留在 SDK 负载中,并将 100% 的符合条件流量强制分配给
<winnerVariationId>。这是最简洁的‘发布获胜方案’选项——关联的功能标志规则会保留,但会将所有人导向获胜变体。之后你可以通过modify-temporary-rollout将其关闭,或通过flag-targeting清理规则。”如果用户同意,请在负载中设置
enableTemporaryRollout: true和releasedVariationId: <winner ID>。如果用户不同意,则停止实验,但不修改标志——说明用户需要手动清理experiment-ref规则。 -
确认意图。 用通俗语言重述操作:
“正在停止实验‘’,将变体
var_treatment_a(Treatment A)声明为获胜变体,并启用临时发布,将其推送到 100% 的符合条件流量。”提交前务必获得明确确认。停止操作本身可撤销(可以重启),但声明获胜变体并启用发布会产生下游信号——不要凭猜测行事。
-
构建负载。 请求正文是扁平结构;没有嵌套的
resultSummary。停止实验但不声明获胜变体:
{ "results": "inconclusive" }停止实验并声明获胜变体,但不进行发布:
{ "results": "won", "winnerVariationId": "<winner variation ID>", "analysis": "<one-paragraph markdown summary of the decision>" }停止实验并声明获胜变体,通过临时发布上线:
{ "results": "won", "winnerVariationId": "<winner variation ID>", "releasedVariationId": "<winner variation ID>", "enableTemporaryRollout": true, "analysis": "<one-paragraph markdown summary of the decision>" }字段参考:
results— 必填。取值为"won"、"lost"、"inconclusive"、"dnf"(未完成)之一。winnerVariationId— 字符串变体 ID(例如var_abc123)。当results === "won"且实验有多个测试变体时必填。releasedVariationId— 字符串变体 ID。当enableTemporaryRollout: true时必填。通常与winnerVariationId相同。enableTemporaryRollout— 布尔值。将已停止的实验保留在 SDK 负载中,并将流量强制路由到releasedVariationId。analysis— Markdown 摘要,会显示在实验结果页面上。reason— 可选原因文本,存储在最新阶段的元数据中。dateEnded— 可选 ISO 日期时间;默认值为当前时间。
-
提交更新。
echo '<payload-json>' | gb-call POST /api/v1/experiments/<experiment-id>/stop - -
说明接下来会发生什么,并提供实验链接。 告知用户:
- 实验现已停止;不会再有流量计入该实验。
- 如果已确定胜出者,说明“胜出”的变体 ID。
- 提供直接 UI 链接,以便他们验证实验已停止、记录的
analysis以及发布状态:
从<host>/experiment/<experiment-id>GB_API_URL推导<host>,将api.替换为app.(与experiment-launch的约定一致;在默认云主机上会得到https://app.growthbook.io)。 标记会怎样? 根据已提交的内容,清楚说明后续处理方式:
启用了临时发布(
enableTemporaryRollout: true): 胜出变体已生效——流量已通过现有的实验引用规则路由到该变体。在团队决定清理标记之前,无需采取进一步操作(可能要等几天或几周)。准备好后:- 转换为永久规则: 通过
flag-rules移除实验引用规则,再通过flag-targeting为胜出变体添加永久强制规则。 - 彻底清理: 如果该功能将内联到代码中,使用
flag-cleanup完成代码清理,并归档/删除标记。 - 回滚: 先关闭临时发布(
echo '{"enableTemporaryRollout": false}' | gb-call POST /api/v1/experiments/<experiment-id>/modify-temporary-rollout -),然后通过flag-rules移除实验引用规则。
未启用临时发布: 标记上的实验引用规则仍然存在,流量会被路由到已停止的实验(用户将获得对照值)。该标记需要处理:
- 选项 A — 发布胜出变体: 通过
flag-default-value将defaultValue设为胜出变体的值,然后通过flag-rules移除实验引用规则。或者,使用flag-targeting添加一条提供胜出变体的永久强制规则,然后移除实验引用规则。 - 选项 B — 回滚: 标记的默认值已经提供对照值——只需通过
flag-rules移除实验引用规则,标记便会恢复到实验前的状态。 - 选项 C — 完全清理: 使用
flag-cleanup将值内联到代码中,并归档/删除标记。
注意事项
winnerVariationId是一个变体 ID 字符串(例如var_abc123),不是整数索引、名称,也不是变体的key。 如果填错,请求会返回 400,或记录错误的变体为胜出者。- 端点是
POST /api/v1/experiments/<id>/stop,不是POST /api/v1/experiments/<id>。 请求体结构是扁平的——没有resultSummary包装对象。通用更新端点确实存在,但接受的字段不同;此处请使用专用的停止端点。 - 绝不要声明用户未选择的胜出者。 即使结果看起来显而易见,也要让用户选择变体 ID。展示结果,但不要预先填入。这是技能的约定,不是 GrowthBook 的策略:API 接受任何变体 ID 作为
winnerVariationId;这里会强制执行安全要求,服务器端不会。 - 不要停止草稿。
draft实验尚未运行——用户想要的操作是DELETE /api/v1/experiments/<id>(单独的技能,此处不涵盖)。如果用户要求停止草稿,请指出这一误解。 - 不要停止已停止的实验。 API 可能会接受该请求,但实际上不会产生任何效果;告知用户实验已经停止。要更改已停止实验的结果元数据,请使用新的
results/winnerVariationId/analysis再次提交。 - 多臂老虎机实验不在范围内。
type === "multi-armed-bandit"的实验需要采用不同的处理方式——停止操作并告知用户。 - 当
enableTemporaryRollout: true时,必须提供releasedVariationId。 否则 API 会拒绝此组合。它们通常与winnerVariationId相同,但不一定——例如,结果为“失败”且将所有人回滚到对照组时,应设置releasedVariationId: <control variation ID>,并设置results: "lost"。 - 始终提醒用户注意关联的标志。 停止实验不会从关联标志中移除
experiment-ref规则。如果没有临时发布,标志会继续将流量路由到已过时的实验,直到用户清理该规则。 analysis应使用通俗易懂的语言解释决策(支持 Markdown)。 未来的读者(包括未来的自己)会需要了解背景。声明胜出者时不要将其留空。- 如果用户尚未运行
experiment-analyze,请先运行。 仅凭浏览仪表板就停止实验是常见错误——阶段性数据可能会反转,而且experiment-analyze中的数据质量检查可以标记出看似结论明确、实际却并非如此的结果。 q不接受否定符号和运算符,使用时会返回 400。 列表端点的q参数接受应用的搜索语法(status:running tag:checkout加自由文本),但会直接拒绝!、~、^、>、<、=。只能发送普通的field:value标记和自由文本。- 按名称解析时,请使用
bandits而不是type来筛选多臂老虎机实验。 响应中的type字段(standard/multi-armed-bandit)不是列表查询参数;发送type=会返回 400。添加bandits=false,以便从候选列表中排除多臂老虎机实验,因为此技能遇到这类实验时会停止操作。(implementationType是另一个维度,表示关联变更的类型。)
使用的端点
GET /api/v1/experiments?q=<text>&status=running— 当用户只提供名称或关键词时,解析实验 ID。q会匹配名称、跟踪键、描述和假设。GET /api/v1/experiments/<id>— 获取状态、变体和typePOST /api/v1/experiments/<id>/stop— 停止实验,并可选择声明胜出者和启用临时发布POST /api/v1/experiments/<id>/modify-temporary-rollout— 停止实验后开启或关闭临时发布,无需重新运行此技能
后续步骤
experiment-analyze— 如果用户想在做决定前解读结果,请先运行。flag-rules— 停止实验后移除实验引用规则(最终总是需要执行)。flag-targeting— 添加一条永久强制规则,以获胜值提供服务(替换实验引用规则)。flag-default-value— 如果发布时没有定向规则,则将标志的默认值设为获胜值。flag-cleanup— 如果功能已全面发布,且应从代码中移除该标志并将其归档。experiment-design和experiment-launch— 如果本次测试为后续测试提供了依据,则用于下一次测试。