aiconfig-targeting

Configure targeting rules for AI Configs to control which variations serve to different contexts. Works the same for both completion and agent mode.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "aiconfig-targeting" with this command: npx skills add launchdarkly/agent-skills/launchdarkly-agent-skills-aiconfig-targeting

AI Config Targeting

Configure targeting rules for AI Configs to control which variations serve to different contexts. Works the same for both completion and agent mode.

Prerequisites

  • LaunchDarkly account with AI Configs enabled

  • API access token with write permissions

  • Project key and environment key

  • Existing AI Config with variations (use aiconfig-create skill)

API Key Detection

  • Check environment variables - LAUNCHDARKLY_API_KEY , LAUNCHDARKLY_API_TOKEN , LD_API_KEY

  • Check MCP config - Claude: ~/.claude/config.json -> mcpServers.launchdarkly.env.LAUNCHDARKLY_API_KEY

  • Prompt user - Only if detection fails

Core Concepts

Evaluation Order

Targeting rules evaluate in this order (same as feature flags):

  • Individual targets - Specific context keys (highest priority)

  • Segment rules - Pre-defined segments

  • Custom rules - Attribute-based conditions (evaluated in order)

  • Default rule - Fallthrough for all others

  • Off variation - When targeting is disabled

Semantic Patch API

AI Config targeting uses semantic patch instructions:

PATCH /api/v2/projects/{projectKey}/ai-configs/{configKey}/targeting Content-Type: application/json; domain-model=launchdarkly.semanticpatch

Key Concepts

  • variationId: UUIDs, not keys. Always fetch targeting first to get IDs.

  • Weights: Thousandths (50000 = 50%, 100000 = 100%)

  • Clause logic: Multiple clauses = AND, multiple values = OR

  • Null attributes: Rules with null/missing attributes are skipped

Workflow

Step 1: Get Targeting (with Variation IDs)

curl -X GET "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/{configKey}/targeting"
-H "Authorization: {api_token}"
-H "LD-API-Version: beta"

Response includes variations array with _id (UUID) for each variation.

Step 2: Edit the Default Rule

Edit the default rule to serve the variation you created.

Important: The turnTargetingOn instruction does not work for AI Configs. Use updateFallthroughVariationOrRollout instead.

First, get variation IDs from Step 1 response

Then set fallthrough to the enabled variation (e.g., "Default" variation)

curl -X PATCH "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/{configKey}/targeting"
-H "Authorization: {api_token}"
-H "Content-Type: application/json; domain-model=launchdarkly.semanticpatch"
-H "LD-API-Version: beta"
-d '{ "environmentKey": "production", "instructions": [{ "kind": "updateFallthroughVariationOrRollout", "variationId": "your-enabled-variation-uuid" }] }'

Step 3: Add Targeting Rules

Attribute-based rule:

curl -X PATCH "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/{configKey}/targeting"
-H "Authorization: {api_token}"
-H "Content-Type: application/json; domain-model=launchdarkly.semanticpatch"
-H "LD-API-Version: beta"
-d '{ "environmentKey": "production", "instructions": [{ "kind": "addRule", "clauses": [{ "contextKind": "user", "attribute": "selectedModel", "op": "contains", "values": ["sonnet"], "negate": false }], "variation": 0 }] }'

Percentage rollout:

curl -X PATCH "..."
-d '{ "environmentKey": "production", "instructions": [{ "kind": "addRule", "clauses": [{ "contextKind": "user", "attribute": "tier", "op": "in", "values": ["premium"], "negate": false }], "percentageRolloutConfig": { "contextKind": "user", "bucketBy": "key", "variations": [ {"variation": 0, "weight": 60000}, {"variation": 1, "weight": 40000} ] } }] }'

Set fallthrough (default rule):

curl -X PATCH "..."
-d '{ "environmentKey": "production", "instructions": [{ "kind": "updateFallthroughVariationOrRollout", "variationId": "fallback-variation-uuid" }] }'

Python Implementation

import requests import os from typing import Dict, List, Optional

class AIConfigTargeting: """Manager for AI Config targeting rules"""

def __init__(self, api_token: str, project_key: str):
    self.api_token = api_token
    self.project_key = project_key
    self.base_url = "https://app.launchdarkly.com/api/v2"

def get_targeting(self, config_key: str) -> Optional[Dict]:
    """Get current targeting with variation IDs."""
    url = f"{self.base_url}/projects/{self.project_key}/ai-configs/{config_key}/targeting"

    response = requests.get(url, headers={
        "Authorization": self.api_token,
        "LD-API-Version": "beta"
    })

    if response.status_code == 200:
        return response.json()
    print(f"[ERROR] {response.status_code}: {response.text}")
    return None

def get_variation_id(self, config_key: str, variation_key: str) -> Optional[str]:
    """Look up variation UUID from key or name."""
    targeting = self.get_targeting(config_key)
    if targeting:
        for var in targeting.get("variations", []):
            if var.get("key") == variation_key or var.get("name") == variation_key:
                return var.get("_id")
    return None

def update_targeting(self, config_key: str, environment: str,
                     instructions: List[Dict], comment: str = "") -> Optional[Dict]:
    """Send semantic patch instructions."""
    url = f"{self.base_url}/projects/{self.project_key}/ai-configs/{config_key}/targeting"

    payload = {"environmentKey": environment, "instructions": instructions}
    if comment:
        payload["comment"] = comment

    response = requests.patch(url, headers={
        "Authorization": self.api_token,
        "Content-Type": "application/json; domain-model=launchdarkly.semanticpatch",
        "LD-API-Version": "beta"
    }, json=payload)

    if response.status_code == 200:
        return response.json()
    print(f"[ERROR] {response.status_code}: {response.text}")
    return None

def enable_config(self, config_key: str, environment: str,
                  variation_key: str = "default") -> bool:
    """
    Enable an AI Config by setting fallthrough to an enabled variation.

    Note: turnTargetingOn doesn't work for AI Configs. Instead, set the
    fallthrough from the disabled variation (index 0) to an enabled one.
    """
    variation_id = self.get_variation_id(config_key, variation_key)
    if not variation_id:
        print(f"[ERROR] Variation '{variation_key}' not found")
        return False
    return self.set_fallthrough(config_key, environment, variation_id)

def add_rule(self, config_key: str, environment: str,
             clauses: List[Dict], variation: int,
             description: str = "") -> bool:
    """Add targeting rule serving a specific variation index."""
    instruction = {
        "kind": "addRule",
        "clauses": clauses,
        "variation": variation
    }
    if description:
        instruction["description"] = description

    result = self.update_targeting(config_key, environment,
        [instruction], f"Add rule: {description}")
    if result:
        print(f"[OK] Rule added")
        return True
    return False

def add_rollout_rule(self, config_key: str, environment: str,
                     clauses: List[Dict],
                     weights: List[Dict],
                     bucket_by: str = "key") -> bool:
    """
    Add percentage rollout rule.

    weights: [{"variation": 0, "weight": 50000}, {"variation": 1, "weight": 50000}]
    """
    result = self.update_targeting(config_key, environment, [{
        "kind": "addRule",
        "clauses": clauses,
        "percentageRolloutConfig": {
            "contextKind": "user",
            "bucketBy": bucket_by,
            "variations": weights
        }
    }], "Add percentage rollout")
    if result:
        print(f"[OK] Rollout rule added")
        return True
    return False

def set_fallthrough(self, config_key: str, environment: str,
                    variation_id: str) -> bool:
    """Set default (fallthrough) variation by UUID."""
    result = self.update_targeting(config_key, environment, [{
        "kind": "updateFallthroughVariationOrRollout",
        "variationId": variation_id
    }], "Set fallthrough")
    if result:
        print(f"[OK] Fallthrough set")
        return True
    return False

def target_individuals(self, config_key: str, environment: str,
                      context_keys: List[str], variation: int,
                      context_kind: str = "user") -> bool:
    """Target specific context keys."""
    result = self.update_targeting(config_key, environment, [{
        "kind": "addTargets",
        "variation": variation,
        "contextKind": context_kind,
        "values": context_keys
    }], f"Target {len(context_keys)} individuals")
    if result:
        print(f"[OK] Individual targets added")
        return True
    return False

def target_segment(self, config_key: str, environment: str,
                  segment_keys: List[str], variation: int) -> bool:
    """Target a segment."""
    result = self.update_targeting(config_key, environment, [{
        "kind": "addRule",
        "clauses": [{
            "attribute": "segmentMatch",
            "contextKind": "",  # Leave blank for segments
            "op": "segmentMatch",
            "values": segment_keys,
            "negate": False
        }],
        "variation": variation
    }], f"Target segments: {segment_keys}")
    if result:
        print(f"[OK] Segment targeting added")
        return True
    return False

def clear_rules(self, config_key: str, environment: str) -> bool:
    """Remove all targeting rules."""
    result = self.update_targeting(config_key, environment,
        [{"kind": "replaceRules", "rules": []}], "Clear all rules")
    if result:
        print(f"[OK] All rules cleared")
        return True
    return False

Instruction Reference

Note: turnTargetingOn and turnTargetingOff do not work for AI Configs. AI Configs have targeting enabled by default. To "enable" a config, set the fallthrough to an enabled variation using updateFallthroughVariationOrRollout .

Rules

Kind Description

addRule

Add rule with clauses and variation/rollout

removeRule

Remove by ruleId

replaceRules

Replace all rules

reorderRules

Change evaluation order

updateRuleVariationOrRollout

Update what a rule serves

Fallthrough

Kind Description

updateFallthroughVariationOrRollout

Set default variation or rollout

Individual Targets

Kind Description

addTargets

Target specific context keys

removeTargets

Remove specific targets

replaceTargets

Replace all targets

Operators Reference

Operator Description Example

in

Value in list ["premium", "enterprise"]

contains

String contains ["sonnet"]

startsWith

String prefix ["user-"]

endsWith

String suffix [".edu"]

matches

Regex match ["^user-\d+$"]

greaterThan / lessThan

Numeric comparison [100]

before / after

Date comparison ["2024-12-31T00:00:00Z"]

semVerEqual / semVerGreaterThan

Version comparison ["2.0.0"]

segmentMatch

Segment membership ["beta-testers"]

Clause Structure

{ "contextKind": "user", "attribute": "email", "op": "endsWith", "values": [".edu"], "negate": false }

  • Multiple clauses = AND (all must match)

  • Multiple values = OR (any can match)

  • negate: true inverts the operator

Rollout Types

Manual Percentage Rollout

{ "percentageRolloutConfig": { "contextKind": "user", "bucketBy": "key", "variations": [ {"variation": 0, "weight": 50000}, {"variation": 1, "weight": 50000} ] } }

Progressive Rollout

{ "progressiveRolloutConfig": { "contextKind": "user", "controlVariation": 1, "endVariation": 0, "steps": [ {"rolloutWeight": 1000, "duration": {"quantity": 4, "unit": "hour"}}, {"rolloutWeight": 5000, "duration": {"quantity": 4, "unit": "hour"}}, {"rolloutWeight": 10000, "duration": {"quantity": 4, "unit": "hour"}} ] } }

Guarded Rollout

{ "guardedRolloutConfig": { "randomizationUnit": "user", "stages": [ {"rolloutWeight": 1000, "monitoringWindowMilliseconds": 17280000}, {"rolloutWeight": 5000, "monitoringWindowMilliseconds": 17280000} ], "metrics": [{ "metricKey": "error-rate", "onRegression": {"rollback": true}, "regressionThreshold": 0.01 }] } }

Common Patterns

Model Routing by Attribute

Route based on selectedModel context attribute

targeting.add_rule( config_key="model-selector", environment="production", clauses=[{ "contextKind": "user", "attribute": "selectedModel", "op": "contains", "values": ["sonnet"], "negate": False }], variation=0, # Sonnet variation index description="Route sonnet requests" )

Tier-Based Variation

targeting.add_rule( config_key="chat-assistant", environment="production", clauses=[{ "contextKind": "user", "attribute": "tier", "op": "in", "values": ["premium", "enterprise"], "negate": False }], variation=0 # Premium model variation )

Segment Targeting

targeting.target_segment( config_key="chat-assistant", environment="production", segment_keys=["beta-testers"], variation=1 # Experimental variation )

Error Handling

Status Cause Solution

400 Invalid semantic patch Check instruction format, ops must be lowercase

403 Insufficient permissions Check API token

404 Config not found Verify projectKey and configKey

422 Invalid variation Use index (0, 1, 2...) or UUID from targeting response

Next Steps

After configuring targeting:

Related Skills

  • aiconfig-create

  • Create AI Configs with variations

  • aiconfig-variations

  • Manage variations

  • aiconfig-online-evals

  • Attach judges

  • aiconfig-segments

  • Create segments for targeting

References

  • Target with AI Configs

  • Targeting Rules

  • JSON Targeting

  • Guarded Rollouts

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

launchdarkly-flag-discovery

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

launchdarkly-flag-cleanup

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

launchdarkly-flag-create

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

launchdarkly-flag-targeting

No summary provided by upstream source.

Repository SourceNeeds Review