exploring-llm-evaluations

Par posthog · skills

Explorez les évaluations analytiques LLM des deux types — `hog` (basé sur du code déterministe) et `llm_judge` (basé sur des prompts LLM). Trouvez les évaluations existantes, inspectez leur configuration, exécutez-les contre des générations spécifiques, interrogez les résultats individuels de réussite/échec, et générez des synthèses alimentées par l'IA sur les tendances observées à travers de nombreuses exécutions. À utiliser lorsque l'utilisateur souhaite déboguer la raison pour laquelle une évaluation échoue, faire remonter les modes d'échec courants, comparer les résultats selon différents filtres, effectuer un dry-run d'un évaluateur Hog, prototyper un nouveau prompt de juge LLM, ou gérer le cycle de vie des évaluations (créer, mettre à jour, activer/désactiver, supprimer).

npx skills add https://github.com/posthog/skills --skill exploring-llm-evaluations

Explorer les évaluations LLM

PostHog évalue les événements $ai_generation. Chaque évaluation est de l'un de deux types, tous deux de premier ordre :

  • hog — code Hog déterministe retournant true/false (et optionnellement N/A). Idéal pour les vérifications objectives basées sur des règles : validation de format (parsing JSON, correspondance de schéma), limites de longueur, présence/absence de mots-clés, patterns regex, assertions structurelles, seuils de latence, garde-fous de coût. Bon marché, rapide, reproductible — pas d'appel LLM par exécution. À privilégier quand le critère peut s'exprimer en code.
  • llm_judge — un LLM note les générations selon une consigne que vous écrivez. Idéal pour les vérifications subjectives ou floues : ton, utilité, détection d'hallucinations, dérive hors sujet, suivi d'instructions. Coûte un appel LLM par exécution et nécessite une approbation de traitement des données IA au niveau de l'organisation.

Les résultats des deux types aboutissent dans ClickHouse sous forme d'événements $ai_evaluation avec le même schéma, donc les workflows de lecture/requête/résumé sont identiques quel que soit le type d'évaluateur — la seule différence est que $ai_evaluation_reasoning a été écrit par du code Hog ou par un LLM.

Cette compétence couvre le cycle de vie complet : lister/inspecter/gérer les configurations d'évaluation (Hog ou LLM judge), les exécuter sur des générations spécifiques, interroger les résultats individuels, et obtenir un résumé généré par IA des patterns de passage/échec/N/A sur plusieurs exécutions.

Outils

Outil Objectif
posthog:llma-evaluation-list Lister/chercher les configurations d'évaluation (filtre par nom, flag activé)
posthog:llma-evaluation-get Obtenir une configuration d'évaluation unique par UUID
posthog:llma-evaluation-create Créer une nouvelle évaluation llm_judge ou hog
posthog:llma-evaluation-update Mettre à jour une évaluation existante (nom, consigne, activée, …)
posthog:llma-evaluation-delete Soft-delete une évaluation
posthog:llma-evaluation-run Exécuter une évaluation sur un événement $ai_generation spécifique
posthog:llma-evaluation-test-hog Dry-run de la source Hog sur les générations récentes (pas de sauvegarde)
posthog:llma-evaluation-summary-create Résumé alimenté par IA des patterns de passage/échec/N/A sur plusieurs exécutions
posthog:execute-sql HogQL ad-hoc sur les événements $ai_evaluation
posthog:query-llm-trace Approfondir la génération sous-jacente qu'une évaluation a notée

Tous les outils llma-evaluation-* sont définis dans products/llm_analytics/mcp/tools.yaml.

Schéma d'événement

Chaque exécution d'une évaluation émet un événement $ai_evaluation. Propriétés clés :

Propriété Signification
$ai_evaluation_id UUID de la configuration d'évaluation
$ai_evaluation_name Nom lisible
$ai_target_event_id UUID de l'événement $ai_generation noté
$ai_trace_id ID de trace parent (pour accéder à l'UI de trace)
$ai_evaluation_result true = passage, false = échec
$ai_evaluation_reasoning Explication en texte libre (définie par le judge LLM ou le code Hog)
$ai_evaluation_applicable false quand l'évaluateur a décidé que la génération est N/A

Quand $ai_evaluation_applicable = false, l'exécution compte comme N/A indépendamment de $ai_evaluation_result. Pour les évaluations qui ne supportent pas N/A, cette propriété peut être null — traiter null comme « applicable ».

Workflow : enquêter pourquoi une évaluation échoue

Fonctionne de la même façon pour les évaluations llm_judge et hog — les différences ne comptent que quand vous allez éventuellement corriger l'évaluateur (éditer la consigne vs. éditer la source Hog).

Étape 1 — Trouver l'évaluation

posthog:llma-evaluation-list
{ "search": "hallucination", "enabled": true }

Regardez l'id, le name, l'evaluation_type retournés, et soit :

  • evaluation_config.prompt pour un llm_judge
  • evaluation_config.source pour un évaluateur hog

La source Hog est la source de vérité pour savoir pourquoi un évaluateur hog passe ou échoue — lisez-la avant d'assumer que l'échec est dans la génération.

Étape 2 — Obtenir le résumé généré par IA

posthog:llma-evaluation-summary-create
{
  "evaluation_id": "<uuid>",
  "filter": "fail"
}

Retourne :

  • overall_assessment — résumé en langage naturel
  • fail_patterns — patterns groupés avec title, description, frequency, et example_generation_ids
  • pass_patterns et na_patterns — même structure, remplis quand filter les inclut
  • recommendations — prochaines étapes exploitables
  • statisticstotal_analyzed, pass_count, fail_count, na_count

Le point de terminaison analyse environ 250 exécutions récentes (EVALUATION_SUMMARY_MAX_RUNS). Les résultats sont mis en cache pendant une heure par (evaluation_id, filter, set_of_generation_ids). Passez force_refresh: true pour recalculer.

Comparez les filtres en deux appels pour repérer ce qui est distinctif aux échecs par rapport aux passages :

posthog:llma-evaluation-summary-create
{ "evaluation_id": "<uuid>", "filter": "pass" }

Puis différenciez les pass_patterns par rapport aux fail_patterns de l'étape 2.

Étape 3 — Approfondir les exemples d'exécutions échouées

Chaque pattern expose example_generation_ids. Tirez la trace sous-jacente pour l'exemple le plus représentatif :

posthog:query-llm-trace
{ "traceId": "<trace_id>", "dateRange": {"date_from": "-30d"} }

(Si vous n'avez que l'ID de génération, interrogez-le d'abord via execute-sql pour trouver l'ID de trace parent — voir ci-dessous.)

Étape 4 — Vérifier le pattern avec du SQL brut

Le résumé est généré par LLM et doit être vérifié. Utilisez execute-sql pour compter et vérifier :

posthog:execute-sql
SELECT
    properties.$ai_target_event_id AS generation_id,
    properties.$ai_trace_id AS trace_id,
    properties.$ai_evaluation_reasoning AS reasoning,
    timestamp
FROM events
WHERE event = '$ai_evaluation'
    AND properties.$ai_evaluation_id = '<evaluation_uuid>'
    AND properties.$ai_evaluation_result = false
    AND (
        properties.$ai_evaluation_applicable IS NULL
        OR properties.$ai_evaluation_applicable != false
    )
    AND timestamp >= now() - INTERVAL 7 DAY
ORDER BY timestamp DESC
LIMIT 25

La garde N/A (IS NULL OR != false) est importante — elle correspond à la même logique que le backend utilise pour regrouper les exécutions.

Workflow : exécuter une évaluation sur une génération spécifique

Utilisez ceci quand l'utilisateur colle une URL de trace/génération et demande « que dirait l'évaluation X à ce sujet ? ».

posthog:llma-evaluation-run
{
  "evaluationId": "<eval_uuid>",
  "target_event_id": "<generation_event_uuid>",
  "timestamp": "2026-04-01T19:39:20Z",
  "event": "$ai_generation"
}

Le timestamp est requis pour une recherche ClickHouse efficace de l'événement cible. Passez distinct_id si vous l'avez — cela accélère davantage la recherche.

Workflow : construire et tester un nouvel évaluateur

Évaluateur Hog (déterministe, basé sur le code)

Optez d'abord pour ceci quand le critère est basé sur des règles — c'est moins cher, plus rapide et reproductible. Prototypez avec llma-evaluation-test-hog (pas de sauvegarde) :

posthog:llma-evaluation-test-hog
{
  "source": "return event.properties.$ai_output_choices[1].content contains 'sorry';",
  "sample_count": 5,
  "allows_na": false
}

Le gestionnaire retourne le résultat booléen pour chacun des N événements $ai_generation les plus récents. Itérez sur la source jusqu'à ce qu'elle se comporte comme prévu, puis promouvez-la via llma-evaluation-create :

posthog:llma-evaluation-create
{
  "name": "Output is valid JSON",
  "description": "Fails when the assistant message can't be parsed as JSON",
  "evaluation_type": "hog",
  "evaluation_config": {
    "source": "let raw := event.properties.$ai_output_choices[1].content; try { jsonParseStr(raw); return true; } catch { return false; }"
  },
  "output_type": "boolean",
  "enabled": true
}

Les évaluateurs Hog ont un accès complet à l'événement et ses propriétés — les patterns courants incluent la validation de schéma, les limites de longueur/tokens, les correspondances regex, et les vérifications de forme d'appels d'outils. Comme ils sont déterministes, les résultats sont reproductibles sur les réexécutions et trivialement diff-ables.

Évaluateur LLM-judge (subjectif, basé sur la consigne)

Utilisez ceci quand le critère est flou et qu'une règle de code serait fragile (ton, factualité, utilité, pertinence). Il n'existe pas d'équivalent à llma-evaluation-test-hog pour les LLM judges — la boucle typique consiste à créer l'évaluateur avec enabled: false, l'exécuter manuellement sur une poignée de générations représentatives via llma-evaluation-run, inspecter les résultats, affiner la consigne avec llma-evaluation-update, puis basculer enabled: true quand vous êtes satisfait :

posthog:llma-evaluation-create
{
  "name": "Response stays on-topic",
  "description": "LLM judge — fails if the assistant changes topic from the user's question",
  "evaluation_type": "llm_judge",
  "evaluation_config": {
    "prompt": "You are evaluating whether the assistant's reply stays on-topic relative to the user's most recent question. Return true if it does, false if the assistant changed the subject. Return N/A if the user did not actually ask a question."
  },
  "output_type": "boolean",
  "output_config": { "allows_na": true },
  "model_configuration": {
    "provider": "openai",
    "model": "gpt-5-mini"
  },
  "enabled": false
}

Puis dry-run sur une génération connue-bonne et une connue-mauvaise :

posthog:llma-evaluation-run
{
  "evaluationId": "<new_eval_uuid>",
  "target_event_id": "<generation_uuid>",
  "timestamp": "2026-04-01T19:39:20Z"
}

Les LLM judges nécessitent une approbation du traitement des données IA au niveau de l'organisation. Les évaluateurs Hog ne le nécessitent pas.

Workflow : gérer le cycle de vie de l'évaluation

Action Outil
Ajouter un évaluateur Hog llma-evaluation-create avec evaluation_type: "hog" et evaluation_config.source
Ajouter un évaluateur LLM-judge llma-evaluation-create avec evaluation_type: "llm_judge", evaluation_config.prompt, et une model_configuration
Affiner la source ou la consigne llma-evaluation-update (édite evaluation_config.source pour Hog, evaluation_config.prompt pour LLM judge)
Basculer la gestion N/A llma-evaluation-update avec output_config.allows_na
Désactiver temporairement llma-evaluation-update avec enabled: false
Supprimer llma-evaluation-delete (soft-delete via PATCH {deleted: true})

Les évaluations llm_judge nécessitent une approbation du traitement des données IA au niveau de l'organisation (is_ai_data_processing_approved). Le même gate s'applique à llma-evaluation-summary-create. Les évaluations Hog ne nécessitent pas ce gate — elles s'exécutent en tant que code simple sur le pipeline d'ingestion.

Quand utiliser Hog vs LLM judge

Optez pour Hog par défaut. Basculez sur LLM judge uniquement quand le critère ne peut pas s'exprimer en code.

Utiliser Hog quand… Utiliser LLM judge quand…
La vérification est structurelle (JSON parses, schéma correspond) La vérification porte sur le sens (pertinence, utilité, factualité)
Vous avez besoin d'un résultat déterministe et reproductible Une petite variabilité de jugement est acceptable
Le critère est bon marché à calculer Le critère nécessite de lire et comprendre du texte
Vous ne pouvez pas obtenir l'approbation du traitement des données IA Vous avez l'approbation et le critère est vraiment flou
Vous avez besoin de forcer une limite dure (longueur, coût, etc.) Vous avez besoin de noter une dimension de qualité
Vous voulez une évaluation en moins d'une milliseconde Quelques centaines de millisecondes + coût LLM sont acceptables

Un pattern courant consiste à les superposer : un évaluateur Hog gate les violations évidentes de format/longueur bon marché, et un évaluateur LLM-judge ne s'exécute que sur les générations qui passent le gate Hog (via conditions).

Patterns d'investigation

L'outil de résumé fonctionne de la même façon indépendamment de si l'évaluateur est hog ou llm_judge — il analyse les événements $ai_evaluation résultants, pas l'évaluateur lui-même. Le chemin de correction diffère (éditer la source Hog vs. éditer la consigne) mais le diagnostic est identique.

« Pourquoi l'évaluation X échoue-t-elle soudainement davantage ? »

  1. llma-evaluation-list — confirmez que l'évaluation est toujours activée et inchangée (comparez evaluation_config.source ou evaluation_config.prompt à la version que vous attendiez)

  2. llma-evaluation-summary-create avec filter: "fail" — obtenez les patterns d'échec dominants et les IDs d'exemple

  3. Comptage SQL des échecs par jour pour confirmer la fenêtre de régression :

    SELECT toDate(timestamp) AS day, count() AS fails
    FROM events
    WHERE event = '$ai_evaluation'
        AND properties.$ai_evaluation_id = '<uuid>'
        AND properties.$ai_evaluation_result = false
        AND timestamp >= now() - INTERVAL 30 DAY
    GROUP BY day
    ORDER BY day
  4. Approfondissez une trace représentative par pattern via query-llm-trace

« Les passages et les échecs sont-ils causés par le même contenu racine ? »

  1. Générez deux résumés : un avec filter: "pass", un avec filter: "fail"
  2. Si pass_patterns et fail_patterns décrivent un contenu similaire :
    • Pour un llm_judge : la consigne ou la rubrique est probablement ambiguë — reformulez evaluation_config.prompt et utilisez llma-evaluation-update
    • Pour un évaluateur hog : la règle correspond probablement trop ou trop peu — lisez la source via llma-evaluation-get, affinez le prédicat, et retestez avec llma-evaluation-test-hog avant de pousser le correctif via llma-evaluation-update

« Un évaluateur Hog a-t-il régressé après un changement de code ? »

Les évaluateurs Hog sont reproductibles — si la source n'a pas changé, des entrées identiques doivent produire des sorties identiques. Quand les taux d'échec grimpent pour un évaluateur Hog :

  1. llma-evaluation-get — notez la source actuelle et updated_at
  2. Vérifiez les exécutions échouées les plus récentes avec la requête SQL de l'étape 4 ci-dessus
  3. Réexécutez la source sur ces générations exactes en utilisant llma-evaluation-test-hog avec un filtre conditions modifié qui les cible
  4. Si les résultats du test correspondent aux résultats en direct, le changement est dans les générations, pas l'évaluateur (une mise à niveau de modèle, changement de consigne en amont, etc.) — enquêtez auprès du producteur
  5. S'ils divergent, l'évaluateur a été édité ; vérifiez l'historique git du champ source via le journal d'activité

« Quels types de générations cet évaluateur saute-t-il comme N/A ? »

posthog:llma-evaluation-summary-create
{ "evaluation_id": "<uuid>", "filter": "na" }

Inspectez na_patterns pour voir si la logique N/A fait la bonne chose. Si un pattern dans na_patterns semble être quelque chose qui aurait dû être noté :

  • Pour un llm_judge : l'instruction d'applicabilité dans la consigne est trop large — affinez-la
  • Pour un évaluateur hog avec output_config.allows_na: true : la source retourne null (ou quel que soit le signal N/A) trop facilement — resserrez la précondition

« Noter cette génération unique maintenant »

llma-evaluation-run avec l'ID de génération et le timestamp de la trace. Utile pour vérifier ou intégrer les évaluations dans une boucle d'agent plus grande.

Construire des liens UI

  • Listes d'évaluations : https://app.posthog.com/llm-analytics/evaluations
  • Évaluation unique : https://app.posthog.com/llm-analytics/evaluations/<evaluation_id>
  • Génération/trace sous-jacente : voir les conventions d'URL de la compétence exploring-llm-traces

Surfacez toujours le lien pertinent pour que l'utilisateur puisse vérifier dans l'UI.

Conseils

  • L'outil de résumé est limité en débit (burst, soutenu, quotidien) et met en cache les résultats pendant une heure — les appels répétés avec le même (evaluation_id, filter) sont bon marché ; utilisez force_refresh: true seulement quand vous avez vraiment besoin d'une analyse fraîche
  • Passez generation_ids: [...] pour limiter un résumé à une cohorte spécifique d'exécutions (max 250)
  • Le bloc statistics dans la réponse du résumé est calculé à partir de données brutes, pas du LLM — fiez-vous à ces comptages même si le champ frequency d'un pattern est qualitatif
  • Pour un filtrage riche non supporté par llma-evaluation-list (par ex. par auteur ou configuration de modèle), retombez sur execute-sql sur la table Postgres evaluations ou les événements ClickHouse $ai_evaluation
  • Quand vous montrez les patterns d'échec à l'utilisateur, incluez toujours 1-2 liens de trace d'exemple pour qu'ils puissent valider le pattern visuellement
  • Les outils llma-evaluation-* utilisent evaluation:read pour les outils de lecture et evaluation:write pour les outils mutants ; llma-evaluation-summary-create utilise llm_analytics:write
  • Les évaluateurs Hog sont reproductibles — si vous suspectez une régression, llma-evaluation-test-hog avec la source suspecte sur les générations échouées est le moyen le plus rapide de bissecter si le changement est dans l'évaluateur ou dans le producteur des générations
  • Les évaluateurs LLM-judge sont non-déterministes sur les réexécutions ; attendez-vous à 1-5 % de bruit même avec une consigne et un modèle fixes. Si vous chassez une petite régression en taux d'échec, préférez Hog ou épinglez un provider/seed déterministe dans la model_configuration

Skills similaires