Online Evals
Attach judges to config variations for automatic LLM-as-a-judge evaluation. Create custom judges, configure sampling rates, and monitor quality scores.
- Skill ID
- launchdarkly/ai-tooling/online-evals
- Publisher
- launchdarkly
- Repository
- ai-tooling
- Installs
- 0
- Files
- 2
- Requires
- Requires LaunchDarkly API access token with ai-configs:write permission. SDK versions Python v0.20.0+ or Node.js v0.20.0+ for automatic metric recording and the consolidated `track_judge_result` / `trackJudgeResult` API.
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
launchdarkly/ai-tooling/online-evalsInstalls these files- README.md
- SKILL.md
What this skill tells the agent
Config Online Evaluations
Attach judges to config variations for automatic quality scoring using LLM-as-a-judge methodology. Judges evaluate responses and return scores between 0.0 and 1.0.
Prerequisites
- LaunchDarkly account with AgentControl enabled
- API access token with write permissions
- Existing config with variations (use
configs-createskill) - For automatic metric recording and the consolidated judge-result API: Python AI SDK v0.20.0+ or Node.js AI SDK v0.20.0+
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
What Are Judges?
Judges are specialized configs in judge mode that evaluate responses from other configs. They use an LLM to score outputs and return structured results:
{
"score": 0.85,
"reasoning": "Answered correctly with one minor omission"
}Built-in Judges
LaunchDarkly provides three pre-configured judges:
| Judge | Metric Key | Measures |
|---|---|---|
| Accuracy | $ld:ai:judge:accuracy | How correct and grounded the response is |
| Relevance | $ld:ai:judge:relevance | How well it addresses the user request |
| Toxicity | $ld:ai:judge:toxicity | Harmful or unsafe phrasing (lower = safer) |
Completion Mode Only
Judges can only be attached to completion mode configs in the UI. For agent mode or custom pipelines, use programmatic evaluation via the SDK.
Restrictions
- Cannot attach judges to judges (no recursion)
- Cannot attach multiple judges with the same metric key to a single variation
- Cannot view/edit model parameters or tools on judge variations
Workflow
Step 1: Create Custom Judges (Optional)
For domain-specific evaluation, create judge configs:
# Create judge config
curl -X POST "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs" \
-H "Authorization: {api_token}" \
-H "Content-Type: application/json" \
-H "LD-API-Version: beta" \
-d '{
"key": "security-judge",
"name": "Security Judge",
"mode": "judge",
"evaluationMetricKey": "security",
"isInverted": false
}'Note: Set isInverted: true for metrics like toxicity where 0.0 is better.Then add a variation with the evaluation prompt:
curl -X POST "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/security-judge/variations" \
-H "Authorization: {api_token}" \
-H "Content-Type: application/json" \
-H "LD-API-Version: beta" \
-d '{
"key": "default",
"name": "Default",
"messages": [
{
"role": "system",
"content": "You are a security auditor. Score from 0.0 to 1.0:\n- 1.0: No security issues\n- 0.7-0.9: Minor issues\n- 0.4-0.6: Moderate issues\n- 0.1-0.3: Serious vulnerabilities\n- 0.0: Critical vulnerabilities\n\nCheck for: SQL injection, XSS, hardcoded secrets, command injection."
}
],
"modelConfigKey": "OpenAI.gpt-4o-mini",
"model": {
"parameters": {
"temperature": 0.3
}
}
}'Step 2: Attach Judges to Variations
Use the variation PATCH endpoint:
curl -X PATCH "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/{configKey}/variations/{variationKey}" \
-H "Authorization: {api_token}" \
-H "Content-Type: application/json" \
-H "LD-API-Version: beta" \
-d '{
"judgeConfiguration": {
"judges": [
{"judgeConfigKey": "security-judge", "samplingRate": 1.0},
{"judgeConfigKey": "api-contract-judge", "samplingRate": 0.5}
]
}
}'Important: The judges array replaces all existing judge attachments. An empty array removes all judges.Step 3: Set Fallthrough on Judges
Each judge config needs its fallthrough set to the enabled variation. Configs default to the "disabled" variation (index 0).
Note:turnTargetingOndoes not work for configs. UseupdateFallthroughVariationOrRolloutinstead.
# First get the variation ID for "Default" from GET targeting response
curl -X PATCH "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/security-judge/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-default-variation-uuid"
}]
}'Python Implementation
import requests
import os
from typing import Optional
class AIConfigJudges:
"""Manager for config judge attachments"""
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"
self.headers = {
"Authorization": api_token,
"Content-Type": "application/json",
"LD-API-Version": "beta"
}
def attach_judges(self, config_key: str, variation_key: str,
judges: list[dict]) -> dict:
"""
Attach judges to a variation.
Args:
config_key: config key
variation_key: Variation key
judges: List of {"judgeConfigKey": str, "samplingRate": float}
"""
url = f"{self.base_url}/projects/{self.project_key}/ai-configs/{config_key}/variations/{variation_key}"
response = requests.patch(url, headers=self.headers, json={
"judgeConfiguration": {"judges": judges}
})
if response.status_code == 200:
print(f"[OK] Attached {len(judges)} judges to {config_key}/{variation_key}")
return response.json()
print(f"[ERROR] {response.status_code}: {response.text}")
return {}
def create_judge(self, key: str, name: str, metric_key: str,
system_prompt: str, model: str = "OpenAI.gpt-4o-mini",
is_inverted: bool = False) -> dict:
"""
Create a judge config.
Args:
key: Judge config key
name: Display name
metric_key: Metric key for scoring (appears as $ld:ai:judge:{metric_key})
system_prompt: Evaluation instructions
is_inverted: True if lower scores are better (e.g., toxicity)
"""
# Create config
config_url = f"{self.base_url}/projects/{self.project_key}/ai-configs"
response = requests.post(config_url, headers=self.headers, json={
"key": key,
"name": name,
"mode": "judge",
"evaluationMetricKey": metric_key,
"isInverted": is_inverted
})
if response.status_code not in [200, 201]:
print(f"[ERROR] Creating config: {response.text}")
return {}
# Create variation
var_url = f"{self.base_url}/projects/{self.project_key}/ai-configs/{key}/variations"
response = requests.post(var_url, headers=self.headers, json={
"key": "default",
"name": "Default",
"messages": [{"role": "system", "content": system_prompt}],
"modelConfigKey": model,
"model": {"parameters": {"temperature": 0.3}}
})
if response.status_code in [200, 201]:
print(f"[OK] Created judge: {key}")
return response.json()
print(f"[ERROR] Creating variation: {response.text}")
return {}
def set_fallthrough(self, config_key: str, environment: str,
variation_key: str = "default") -> bool:
"""
Set fallthrough to enable a judge config.
Note: turnTargetingOn doesn't work for configs. Instead, set theMore from launchdarkly
Use this skill in a project
Open any RiverX project, search the Skills panel for launchdarkly/ai-tooling/online-evals, and install it in one click.
