flag-targeting について
GrowthBook の既存フィーチャーフラグにターゲティングルールを追加、編集、削除するスキルです。属性条件、保存済みグループ、前提フラグを使った固定値や割合ロールアウトに対応し、変更は公開までドラフトに保持されます。
主な機能
- 01ルールの追加、編集、削除
- 02固定値と割合ロールアウトに対応
- 03条件、保存済みグループ、前提条件の組み合わせ
- 04変更をドラフトリビジョンに保持
活用シーン
- 01属性に一致するユーザーにフラグ値を提供
- 02一部のユーザーへの段階的な機能展開
- 03保存済みグループや別フラグによる対象設定
- 04既存ルールの範囲や条件の変更
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ growthbook/ skills --skill flag-targetingインストール後、Claude Code で/flag-targetingを入力して読み込まれたか確認します。
詳細
flag-targeting
既存のGrowthBookフィーチャーフラグのターゲティングルールを追加、編集、または削除します。force(一致したユーザーに特定の値を提供)とrollout(ランダムな割合のユーザーに値を提供)のルールタイプに対応し、条件、保存済みグループ、ルールレベルの前提条件を完全にサポートします。
変更はすべてドラフトリビジョンを経由し、公開が必要です。公開にはflag-publishを使用してください。承認が必要な場合やマージコンフリクトが発生した場合にも対応します。
API呼び出しはすべて、同梱のヘルパーを経由します:${CLAUDE_PLUGIN_ROOT}/scripts/gb-call。GB_API_KEYを環境変数に設定するか、/growthbook:gb-setupで~/.config/growthbook/.envに書き込む必要があります。
必須入力
開始前に収集します:
- フラグID — ケバブケースのキーです。説明から特定するにはflag-searchを使用します。
- 操作 —
add、edit、またはremoveです。ユーザーの依頼から推測し、変更を加える前に確認します。
操作ごとの入力
add
- ルールタイプ —
force(特定のユーザー)またはrollout(割合)です。表現から推測します:「ユーザーのX%」→ rollout、「Yに一致するユーザー向け」→ force。 - 値 — 条件に一致したときにルールが提供する値です。フラグの
valueTypeに一致し、文字列としてシリアライズされている必要があります。 - スコープ —
allEnvironments: trueまたはenvironments: [<env-ids>]です。指定がない場合は確認します。 - 条件(任意) — 保存済みグループ、属性条件、または別のフラグに対する前提条件です(下記の条件判断ツリーを参照)。
- ロールアウトルールの場合 —
coverage(0~1)とhashAttribute(coverage < 1の場合は必須)です。 - 説明(任意ですが推奨)。
edit
- ルールID — 番号付きリストを表示して対話的に特定します(ステップ3b)。ユーザーが番号で選択します。
- パッチフィールド — ユーザーが変更を希望するフィールドのみです。
remove
- ルールID — editと同じ方法で特定します。
ワークフロー
- [ ] 1. Fetch flag and current state
- [ ] 2. Confirm the action (add / edit / remove)
- [ ] 3a. Add path
- [ ] 3b. Edit path
- [ ] 3c. Remove path
- [ ] 4. Hand off to flag-publish
1. フラグと現在の状態を取得する
gb-call GET /api/v2/features/<flag-id>
次の情報を取得します:valueType、environmentSettingsのキー(利用可能な環境ID)、rules配列(ID、タイプ、スコープ、有効状態を含む全ルール)。404の場合は処理を中止し、「ID <flag-id>のフラグはありません」と伝えます。flag-searchを提案します。
2. 操作を確認する
ユーザーの依頼が曖昧な場合は、変更を加える前に質問します。
3a. 追加の手順
新しいルールはrules配列の末尾に追加されます。ルールは上から順に評価され、最初に一致したルールが適用されます。フラグに既存のルールがある場合は、次のことを伝えます:
「このフラグには既存のルールが
<N>件あり、新しいルールは最後に評価されます。既存のルールより優先させる必要がある場合は、追加後にflag-rulesで順序を変更してください。」
書き込み時にAPIは不一致を検出しないため、valueとvalueTypeの整合性を事前に検証します:
boolean→"true"または"false"である必要がありますnumber→ 数値として解析できる必要がありますjson→ 有効なJSONである必要がありますstring→ 空でない任意の文字列です
スコープを解決します。 環境IDをenvironmentSettingsと照合します。allEnvironments: trueまたはenvironments: [...]のいずれか一方を設定し、両方を設定してはいけません。
利用可能な属性を取得します — 条件の説明をユーザーに求める前に取得します。フラグにプロジェクトがある場合は、関連する属性(組織全体とプロジェクトスコープの属性)のみを取得するために、projectIdを渡します。組織全体のフラグの場合は省略します:
# Flag has a project:
gb-call GET '/api/v1/attributes?projectId=<flag-project-id>'
# Flag is org-wide (no project):
gb-call GET /api/v1/attributes
返されたリストをタイプ別にまとめ、特筆すべきメタデータを明示してユーザーに提示します:
Available targeting attributes for this flag:
id (string, hashAttribute)
country (string, format: isoCountryCode)
app_version (string, format: version)
plan (enum: free|pro|enterprise)
is_employee (boolean)
属性が存在しない場合(または対象範囲内に属性がない場合)は、次のように警告します:「このプロジェクトにはターゲティング属性が登録されていません。ターゲティングを行う前に、Settings → Attributesで追加してください。」
ロールアウトルールのhashAttributeを解決します(coverage < 1の場合は必須):
絞り込まれた属性リストから、hashAttribute: trueの項目を優先します。「ユーザー単位」の場合はidをデフォルトにします。「会社単位」の場合は会社スコープの属性を選びます。
ルールには独立したターゲティングプロパティが3つあり、自由に組み合わせられます。該当するプロパティを特定してから、必要なフィールドをすべて組み立てて送信します。
condition — 属性ベースのターゲティング(MongoDB形式のJSON文字列)
SDK に渡された属性に基づいてユーザーをターゲティングします。上記で取得したフィルタリング済みのリストから属性を選択してください。ユーザーの説明が利用可能な属性に明確に当てはまらない場合は、リストを表示して選択してもらいます。フィルタリング済みのリストにない属性名は拒否してください。未登録の属性は、SDK の評価時に一致しても通知されません。
条件オブジェクトを JSON 文字列としてペイロードにシリアライズします。
| カテゴリ | 演算子 | 意味 |
|---|---|---|
| 等価 | $eq、$ne(または eq のキーと値をそのまま指定) | =、≠ |
| 比較 | $lt、$lte、$gt、$gte | <、≤、>、≥ |
| セマンティックバージョン | $veq、$vne、$vlt、$vlte、$vgt、$vgte | バージョンを考慮した比較 — "1.0.10" > "1.0.9"。format: version 属性で使用します。 |
| 集合への所属 | $in、$nin | いずれかに一致、どれにも一致しない(大文字と小文字を区別) |
| 集合への所属(大文字と小文字を区別しない) | $ini、$nini | いずれかに一致/どれにも一致しない — 大文字と小文字を区別しません |
| 文字列の包含 | $includes、$notIncludes | 文字列または配列が値を含む/含まない |
| 正規表現 | $regex、$notRegex | パターンに一致する/しない(大文字と小文字を区別) |
| 正規表現(大文字と小文字を区別しない) | $regexi、$notRegexi | 同上。大文字と小文字を区別しません |
| 存在 | $exists、$notExists | NULL ではない/NULL である |
| 空かどうか | $empty、$notEmpty | 文字列または配列が空/空ではない |
| ブール値 | $true、$false | 属性が真値/偽値である |
| 型 | $type | JS の型が値と等しい(例:"string"、"number") |
| 配列 | $elemMatch、$all、$alli、$size | 要素が条件に一致する。すべての値が含まれる($alli は大文字と小文字を区別しない)。長さの比較 |
| 保存済みグループ(直接指定) | $inGroup、$notInGroup | ID で保存済みグループに所属する/しない — 代わりに savedGroups ルールフィールドを使用してください |
| 論理 | $or、$and、$nor、$not | 最上位のキーは AND で結合されます。OR/否定にはこれらを使用します |
主なルール:
- 複数の最上位キーは AND で結合されます:
{"country": "US", "plan": "pro"}は両方の条件を満たす必要があります。 - 文字列の比較では、デフォルトで大文字と小文字を 区別します — 必要に応じて
$ini/$regexi系の演算子を使用してください。 - 条件は SDK によってクライアント側で評価されます — 属性値が GrowthBook サーバーに送信されることはありません。
- この表に記載されている演算子のみを使用してください。記載されていない MongoDB 演算子(例:
$where、$expr)は一致しても通知されません。
例:
{"country": "US"}
{"country": {"$ini": ["us", "ca", "gb"]}}
{"plan": {"$ne": "free"}}
{"appVersion": {"$vgte": "3.0.0"}}
{"age": {"$gte": 18, "$lt": 65}}
{"email": {"$regexi": "@acme\\.com$"}}
{"$or": [{"country": "US"}, {"beta": true}]}
{"tags": {"$includes": "power-user"}}
{"company": {"$exists": true}, "plan": {"$in": ["pro", "enterprise"]}}
savedGroups — 保存済みグループによるターゲティング(別のルールフィールド)
事前定義された保存済みグループに属するユーザーをターゲティングします。利用可能なグループを取得します:
gb-call GET /api/v1/saved-groups
このフィールドはグループ参照の配列として作成します:
"savedGroups": [
{ "ids": ["<sg-id>"], "match": "all" }
]
ids— 参照する保存済みグループ ID の配列match: "all"— ユーザーはリスト内の すべての グループに属している必要があります。"any"— ユーザーはリスト内の 少なくとも 1 つ のグループに属している必要があります
「ベータテスター」「社内ユーザー」「エンタープライズアカウント」など、フラグの外部で管理されている名前付きユーザー群には、保存済みグループを使用してください。condition 文字列に $inGroup を直接記述するよりも、こちらを優先してください。
prerequisites — ルールレベルの前提条件によるターゲティング(別のルールフィールド)
別のフィーチャーフラグの評価値に基づいて、このルールを適用するかどうかを決定します。前提条件を満たさないユーザーにはこのルールがスキップされ、代わりに順序上の次のルールが評価されます。これは、フラグ全体をスキップするフィーチャーレベルの前提条件とは異なります。
"prerequisites": [
{ "id": "<flag-id>", "condition": "{\"value\": true}" }
]
condition 文字列は { "value": <前提条件となるフラグの評価結果> } に対して評価されます。有効な最上位キーは value のみです。
ほとんどのケースで使える条件は次の 2 種類です:
| 目的 | 条件 |
|---|---|
| ブール値フラグがオン | {"value": true} |
| ブール値フラグがオフ | {"value": false} |
| 非ブール値フラグが有効(何らかの値を返す) | {"value": {"$exists": true}} |
| 非ブール値フラグが無効 | {"value": {"$exists": false}} |
より具体的な条件(例:文字列フラグが特定のバリアントと等しいかどうか)が必要な場合は、上記の condition セクションにある演算子一覧を使用できます。ただし、複雑な前提条件を記述する前に、必ずユーザーに確認してください。
3 つすべての組み合わせ: 3つのプロパティはすべて AND 条件で結合されます。3つすべてが設定されたルールは、ユーザーが保存済みグループに属し、かつ属性条件に一致し、かつすべての前提条件フラグが通過した場合にのみ発動します。
{
"condition": "{\"country\": \"US\"}",
"savedGroups": [{ "ids": ["sg_beta"], "match": "all" }],
"prerequisites": [{ "id": "new-checkout", "condition": "{\"value\": true}" }]
}
曖昧なケース(「VIP 顧客」、「エンタープライズユーザー」)では、GrowthBook の名前付きグループ(保存済みグループ)なのか、ユーザーレコードの属性(条件)なのか、それとも両方なのかを確認してください。
| ユーザーの発言 | 使用するフィールド |
|---|---|
| 「ベータテスターに対して有効にする」 | savedGroups |
| 「米国のユーザー」 | country 属性に対する condition |
| 「バージョン 5.2 以上の iOS ユーザー」 | condition:{"platform": "ios", "appVersion": {"$vgte": "5.2"}} |
| 「new-checkout フラグがオンの場合のみ」 | prerequisites |
| 「エンタープライズユーザー」 | 確認 — 保存済みグループですか、それとも {"plan": "enterprise"} 条件ですか? |
ペイロードを作成して POST します:
{
"rule": {
"type": "force",
"value": "<string>",
"description": "<optional>",
"enabled": true,
"allEnvironments": false,
"environments": ["production"],
"condition": "<optional JSON string>",
"savedGroups": [{ "ids": ["<sg-id>"], "match": "all" }],
"prerequisites": [{ "id": "<flag-id>", "condition": "{\"value\": true}" }]
}
}
ロールアウトの場合は、type: "rollout" に変更し、coverage と hashAttribute を追加します。空の配列や文字列は省略します。
echo '<payload>' | gb-call POST /api/v2/features/<flag-id>/revisions/new/rules -
revision.version を取得します。
3b. 編集パス
ルールを番号付きリストで表示します:
Rules on `<flag-id>`:
1. [force] all envs value="true" "Beta testers" (saved group)
2. [rollout] production 10% hash=id
3. [force] staging value="false" "Kill switch"
ユーザーに番号を選んでもらいます。現在の値を提示し、どのフィールドを変更するかを尋ねます。
空のパッチに対するガード: 提案された変更が現在の値と完全に一致する場合は中断し、「適用する変更はありません」と伝えます。何も変更しないドラフトはレート制限の枠を消費し、resetReviewOnChange によって以前に付与された承認が無効になる可能性があります。
編集時のルールタイプの動作:
- 明示的な
typeの変更はサーバーによって拒否されます。 強制ルールを実験参照ルールに変換するには、削除して再追加します(3c の後に 3a または flag-experiment を実行)。 force↔rolloutは、有効なカバレッジに基づいて自動的に切り替わります。 強制ルールにcoverage: 0.25をパッチすると、警告なしにロールアウトへ変換されます(hashAttributeも必要です)。概要ではタイプの変更を伝えてください。
experiment-ref の編集ルール:
- サーバーによって拒否されるパッチ:
value、coverage、controlValue。理由を説明して早めに中断します。 - 警告して確認するパッチ:
experimentId、variations。API は許可しますが、フラグと実験の不整合が警告なしに発生します。明示的な確認を求めます:「experimentId/variationsを直接変更すると、フラグルールと実験に不整合が生じる可能性があります。実験が正となる情報源です。本当に変更しますか?」 - 安全に編集できる項目:
enabled、condition、savedGroups、prerequisites、スコープ、description。
スコープに関する注意点: スコープを変更する場合は、常に allEnvironments と environments の両方を一緒に送信します。allEnvironments を含めずに environments のみを送ると、サーバーは allEnvironments: false と推定し、警告なしにスコープを狭めます。
echo '<patch>' | gb-call PUT /api/v2/features/<flag-id>/revisions/new/rules/<rule-id> -
revision.version を取得します。
3c. 削除パス
番号付きリストを表示します。次のように確認します:
「
<flag-id>から<N>番目のルール(<type>、<scope>、<summary>)を削除しますか?これはドラフトに追加され、公開後にのみ反映されます。」
gb-call DELETE /api/v2/features/<flag-id>/revisions/new/rules/<rule-id>
experiment-ref の削除の場合:「このルールを削除しても、リンクされている実験には影響しません。」
revision.version を取得します。
4. flag-publish に引き継ぐ
変更後に、「この変更を今すぐ公開しますか、それともドラフトのままにしますか?」と尋ねます。
flag-publish に引き継ぎます。次の処理を担当します:
- 承認が必要な場合(400)— レビューフロー、組織全体のバイパス、トークン単位のバイパスを提示
- マージ競合(409)— 競合するフィールドを表示し、上書き/破棄の選択を集めてからリベース
ガードレール
- ドラフトのバージョンを引き継ぎます。 このセッションで前の書き込みスキルからバージョン番号がすでにコンテキストに含まれている場合は、
newではなく、明示的にそのバージョンを使用します(例:.../revisions/42/rules)。これにより、連続してスキルを使う場合もすべての変更が同じドラフトに反映されます。新たに開始する場合はnewを使用します。resolveOrCreateRevisionにより、更新日時が最も新しいオープン中のドラフトが自動的に作成または再利用されます。 - ルール ID は位置番号ではなく UUID(
fr_...)です。 必ずrules配列から特定し、推測しないでください。 forceとrolloutの違いは、サーバー側ではほぼ表面的なものです。coverage < 1の force ルールは、実質的に rollout ルールです。ユーザーが「割合」と指定するか、coverage を指定した場合を除き、forceをデフォルトにします。サーバーが自動的に切り替えます。coverage < 1の場合はhashAttributeが必要です。 POST する前に検証してください。- スコープは
allEnvironments: trueまたはenvironments: [...]のいずれか一方のみです。 両方を指定しないでください。 - 条件を尋ねる前に、必ず属性を取得してください。 フラグがプロジェクトスコープの場合は
?projectId=<id>を指定し、サーバーから関連する属性のみが返されるようにします。リストを最初に提示してください。ユーザーが指定した属性名が返されたリストに含まれていることを確認せずに受け入れないでください。未登録の属性は、SDK の評価時に一致しなくても何も通知されません。 - 条件は JSON 文字列です。 パース可能であることを検証してください。手書きの条件よりも、再利用や管理が可能な Saved Groups を優先してください。
valueTypeの不一致は問題の原因になります。 v2 のルール追加ハンドラーは書き込み時に検証しません。必ずクライアント側で事前に検証してください。- 空のパッチは拒否してください。 何も変更しないリビジョン更新でもレート制限を消費し、レビュー承認がリセットされる場合があります。
- 新しいルールは末尾に追加されます。 最初に一致したルールが適用されます。POST する前に評価順序に関する懸念を提示してください。
- 自己承認はブロックされています。
request-reviewの後にsubmit-reviewを実行しないでください。 - 環境の有効化・無効化は
flag-toggleが担当します。 このスキルは環境レベルの有効化・無効化を行いません。
使用するエンドポイント
GET /api/v2/features/:id— フラグの状態、現在のルール、環境リスト、valueType を取得GET /api/v1/attributes— 属性を取得します。フラグがプロジェクトスコープの場合は?projectId=<id>を指定します。条件を組み立てる前に最初に提示し、rollout 用のhashAttributeを選択しますGET /api/v1/saved-groups— ターゲティングに使用する保存済みグループを解決POST /api/v2/features/:id/revisions/new/rules— ルールを追加PUT /api/v2/features/:id/revisions/new/rules/:ruleId— ルールを編集DELETE /api/v2/features/:id/revisions/new/rules/:ruleId— ルールを削除
引き継ぎ
flag-toggle— 環境レベルの有効化・無効化(キルスイッチ)flag-rules— ルールの並べ替え、または他のルールタイプへの振り分けflag-experiment— experiment-ref またはインライン実験ルールの追加flag-ramp— rollout ルールの coverage を段階的に増加flag-monitoring— rollout にガードレール指標のモニタリングを追加flag-prerequisites— フィーチャーレベルの前提条件ゲートflag-search— 説明からフラグ ID を特定flag-publish— ドラフトを公開(承認とマージ競合に対応)