Backend
Détection — Au début de chaque invocation, avant d'entreprendre une action, détermine quel backend utiliser :
- Si l'utilisateur a passé
--backend pupn'importe où dans son invocation → utilise le mode pup immédiatement, indépendamment de la présence d'outils MCP. Saute les étapes 2–4. - Vérifie si des outils MCP sont présents dans ta liste d'outils active. Le signal canonique est la présence de
mcp__datadog-llmo-mcp__search_llmobs_spansdans tes outils disponibles. - Si des outils MCP sont présents → utilise le mode MCP partout. Appelle les outils MCP exactement comme nommés dans les sections de workflow de sous-skill.
- Si des outils MCP sont absents → vérifie si
pupest exécutable : exécutepup --versionvia Bash. Une réponse JSON contenant"version"confirme que pup est disponible. - Si pup répond → utilise le mode pup partout. Chaque sous-skill porte son propre appendix Tool Reference avec la correspondance MCP→pup complète.
- Si aucun n'est disponible → arrête-toi et dis à l'utilisateur :
« Ni le serveur Datadog MCP ni la CLI pup ne sont disponibles. Connecte le serveur MCP (
claude mcp add --scope user --transport http datadog-llmo-mcp 'https://mcp.datadoghq.com/api/unstable/mcp-server/mcp?toolsets=llmobs') ou installe pup. »
--backend pup est accepté n'importe où dans les arguments d'invocation. Supprime-le des arguments avant de les passer aux sous-skills, mais porte la décision de mode pup en avant — les sous-skills doivent aussi fonctionner en mode pup pour toute la durée de l'exécution du pipeline.
Propagation du backend des sous-skills : Le backend détecté au démarrage du pipeline s'applique aux trois sous-skills (session-classify → trace-rca → eval-bootstrap). Ne redétecte pas par phase. Annonce une fois au démarrage :
- Mode MCP : « (Running in MCP mode — all features available.) »
- Mode pup : « (Running in pup mode — pup commands used throughout. RUM signals use
pup rum aggregate. Notebooks usepup notebooks create/edit. All features available.) »
Règles d'invocation pup :
- Invoque via Bash :
pup llm-obs <subcommand> [flags] - pup retourne toujours du JSON. Parse directement — pas de dépliage de bloc de contenu (contrairement aux résultats MCP).
- Si pup retourne une erreur d'authentification, dis à l'utilisateur d'exécuter
pup auth loginet arrête-toi. - Parallélisation : émet plusieurs appels Bash tool dans un seul message (une commande pup par appel).
- Drapeaux de temps : pup accepte les chaînes de durée nue (
1h,7d,30m) et les timestamps RFC3339. N'utilise pas les chaînes préfixéesnow-— supprime le préfixe lors de la conversion depuis un argument--timeframede skill :now-7d→7d,now-24h→24h,now-30d→30d.
Tagging d'intention : À chaque appel d'outil MCP, préfixe telemetry.intent avec skill:llm-obs-eval-pipeline — suivi d'une description de la raison pour laquelle l'outil est appelé.
LLM Obs Eval Pipeline — Classify → RCA → Bootstrap
Passe des données de trace LLM de production non étiquetées à une suite d'évaluateurs prête à l'emploi en trois phases, avec des points de contrôle utilisateur entre chacune. Aucune éval pré-existante ni donnée étiquetée requise.
llm-obs-session-classify (ml_app mode)
↓
llm-obs-trace-rca (from classifications)
↓
llm-obs-eval-bootstrap (from RCA output)
Usage
/llm-obs-eval-pipeline <ml_app> [--timeframe <window>] [--trace-limit <N>] [--data-only] [--publish]
Arguments : $ARGUMENTS
Inputs
| Input | Requis | Défaut | Description |
|---|---|---|---|
ml_app |
Oui | — | Application LLM à analyser de bout en bout |
--timeframe |
Non | now-7d |
Fenêtre de lookback pour l'échantillonnage des traces et la RCA |
--trace-limit |
Non | 20 |
Nombre maximal de traces à classer dans la Phase 1 |
--data-only |
Non | off | Transféré à llm-obs-eval-bootstrap : émet une spec JSON au lieu de code Python SDK |
--publish |
Non | off | Transféré à llm-obs-eval-bootstrap : publie les évaluateurs LLM-judge en ligne vers Datadog |
Si ml_app n'est pas fourni, demande à l'utilisateur avant de procéder.
Phase 1 : Classification des traces
Suis le skill llm-obs-session-classify en mode ml_app, en utilisant :
ml_app= le ml_app fournitimeframe= la timeframe fourniesample_limit= la trace-limit fournie
Exécute le workflow ml_app mode complet tel que défini dans ce skill (Étapes M1 à M3) : échantillonne les spans → classe chacun → émet des blocs compacts par unité → émet un résumé.
Produis la sortie de classification complète, incluant tous les blocs compacts par unité et la section finale # Session Classification Summary. Ne résume pas ni ne tronque cette sortie — la détection de phase en aval dépend du fait que le texte complet soit présent en contexte.
CHECKPOINT 1
Une fois que le # Session Classification Summary est produit, fais une pause et présente :
## Phase 1 Complete
[tableau de distribution des verdicts]
[tableau de fréquence des modes de défaillance]
Before I continue to root cause analysis:
- Do these failure patterns look right?
- Any traces you'd like to exclude from the RCA?
- Any failure modes to focus on or ignore?
Type "continue" to proceed, or give me adjustments.
Attends une confirmation explicite de l'utilisateur avant de procéder.
- Si l'utilisateur exclut des traces spécifiques : marque-les comme « excluded by user » et supprime-les du bucket de défaillance. Ne reclasse PAS.
- Si l'utilisateur demande de réexécuter avec des paramètres différents : réexécute la Phase 1 avec les nouveaux paramètres.
- Si la Phase 1 a produit zéro défaillances : mets cela explicitement en avant et propose de réessayer avec une timeframe plus large ou d'arrêter.
Phase 2 : Root Cause Analysis
Suis le skill llm-obs-trace-rca.
Le # Session Classification Summary de la Phase 1 est en contexte. Le skill le détecte automatiquement via son vérification Phase 0 Step 0S et entre dans le chemin « from classifications » — il extrait le bucket de défaillance, présente l'overview de Classification, et procède directement à la Phase 2 (open coding) sans exécuter sa propre recherche de spans Phase 1.
Exécute le workflow complet jusqu'à la Phase 6 (le rapport RCA compilé). Produis le rapport RCA complet — ne résume pas. Le rapport complet doit être en contexte pour que la détection Phase 3 fonctionne.
CHECKPOINT 2
Une fois que le rapport RCA est produit, fais une pause et présente :
## Phase 2 Complete
[the Phase 6 RCA report is above]
Before I generate evaluators:
- Do these root causes look accurate?
- Any failure modes to add, remove, or reframe?
- Which root causes should the evaluators target?
Type "continue" to proceed, or give me adjustments.
Attends une confirmation explicite de l'utilisateur avant de procéder.
Si l'utilisateur ajuste la taxonomie : incorpore les changements avant de continuer à la Phase 3.
Phase 3 : Eval Bootstrap
Suis le skill llm-obs-eval-bootstrap.
Le rapport RCA de la Phase 2 est en contexte. Le skill détecte automatiquement l'en-tête ## Failure Taxonomy et entre dans son chemin « from RCA » en Phase 0.
Transfère tous les drapeaux :
--data-only→ émet une spec JSON au lieu de code Python SDK--publish→ publie les évaluateurs LLM-judge en ligne directement vers Datadog
Le skill llm-obs-eval-bootstrap a son propre point de contrôle obligatoire de proposition (la proposition de suite d'évaluateurs avant la génération de code). Respecte-le — ne le saute pas ni l'auto-confirme.
Final Summary
Après la fin de la Phase 3, présente :
# LLM Obs Eval Pipeline Complete
**App**: `<ml_app>` | **Timeframe**: <timeframe>
| Phase | Output |
|-------|--------|
| 1. Classification | <N> traces sampled, <F> failures identified |
| 2. Root Cause Analysis | <K> failure modes, <M> root causes diagnosed |
| 3. Eval Bootstrap | <J> evaluators → `<output_path>` |
## Key findings
[3–5 bullets: most important failure patterns and what the evaluators capture]
## Next steps
1. Review the generated evaluators at `<output_path>`
2. Run an offline experiment to validate eval quality
3. Once validated, configure as production evals in Datadog
Orchestration Rules
- Toujours point de contrôle avant d'avancer. Ne procède jamais automatiquement entre les phases.
- Ne tronque jamais les sorties de sous-skill. La détection de phase en aval dépend du fait que le texte complet soit en contexte.
- Isolation des phases : si l'utilisateur veut réexécuter une phase unique, réexécute seulement cette phase et ses phases en aval.
- Porte le contexte en avant : la sortie de chaque phase est l'entrée pour la suivante. Présente la sortie complète de chaque sous-skill avant de montrer le prompt de point de contrôle.
Tool Reference
Cet appendix s'applique uniquement en mode pup. Chaque sous-skill porte aussi son propre Tool Reference avec les mêmes correspondances — consulte-les pour les détails complets des paramètres. Les tableaux ci-dessous sont une référence rapide pour l'orientation au niveau pipeline.
Spans et traces
| MCP Tool | pup Command |
|---|---|
search_llmobs_spans(...) |
pup llm-obs spans search --query "@ml_app:A [other_filters]" [--from F] [--to T] [--limit N] [--summary] — utilise toujours --query "@ml_app:A" ; --ml-app A n'est pas fiable. |
get_llmobs_span_details(...) |
pup llm-obs spans get-details --trace-id T --span-ids S1,S2,... |
get_llmobs_span_content(...) |
pup llm-obs spans get-content --trace-id T --span-id S --field F [--path P] |
get_llmobs_trace(...) |
pup llm-obs spans get-trace --trace-id T [--include-tree] |
get_llmobs_agent_loop(...) |
pup llm-obs spans get-agent-loop --trace-id T [--span-id S] |
find_llmobs_error_spans(...) |
pup llm-obs spans find-errors --trace-id T |
expand_llmobs_spans(...) |
pup llm-obs spans expand --trace-id T --span-ids S1,S2,... |
Evaluators
| MCP Tool | pup Command |
|---|---|
list_llmobs_evals() |
pup llm-obs evals list |
get_llmobs_evaluator(eval_name) |
pup llm-obs evals get-evaluator EVAL_NAME |
get_llmobs_eval_aggregate_stats(...) |
pup llm-obs evals get-aggregate-stats EVAL_NAME [--ml-app A] [--from F] [--to T] |
create_or_update_llmobs_evaluator(...) |
pup llm-obs evals create-or-update EVAL_NAME --file /tmp/eval_EVAL_NAME.json (voir Tool Reference d'eval-bootstrap pour les détails de schema plat) |
RUM
| MCP Tool | pup Command |
|---|---|
analyze_rum_events(event_type="view", filter="@usr.email:EMAIL", ...) |
pup rum aggregate --user-email EMAIL --from F --to T --compute count --group-by @session.id |
analyze_rum_events(event_type="action", filter="@action.type:custom ...", ...) |
pup rum aggregate --user-email EMAIL --query "@action.type:custom" --from F --to T --compute count --group-by @evt.name |
Notebooks
| MCP Tool | pup Command |
|---|---|
create_datadog_notebook(name, cells, ...) |
pup notebooks create --title "TITLE" --file /tmp/nb_cells.json |
edit_datadog_notebook(id, cells, append_only=true) |
pup notebooks edit NOTEBOOK_ID --file /tmp/nb_cells.json |
- Sécurité du parsing de résultats MCP : Avant d'écrire un script (Python, jq, etc.) qui itère ou accède aux champs d'un résultat d'outil MCP, inspecte d'abord la structure brute — vérifie
type(result), les clés au niveau supérieur, et si la payload est imbriquée dans un bloc de contenu (par ex.[{'type': 'text', 'text': '<json>'}]). Extrait etjson.loads()la payload interne si nécessaire. Ne suppose jamais que les résultats MCP sont des dicts ou listes nus.