Accueil / Articles

Évaluations des agents et des compétences en pratique : trajectoires, évaluateurs, critères d’admission et outils

Comment évaluer les agents et les compétences : ensembles de déclenchement et d’exécution, ordre de force du classeur, précision et rappel, pass@k versus pass^k, un petit outil Python et des choix de logiciels.

Éditeur : REACTAPP.TOP11 min de lecture2573 mots

Sources: Evals: A Crash Course for Agents and Skills

Tôt ou tard, toute équipe qui met en œuvre des agents et des compétences se heurte à un même obstacle : la démo est impressionnante, mais le trafic réel révèle des défauts que personne n’avait remarqués. Les évaluations remplacent les suppositions par des mesures. Ce qui suit est un guide pratique sur ce qu’il faut mesurer, comment rédiger des cas d’évaluation et des outils d’évaluation, ainsi que comment mettre en place un cycle d’amélioration qui permette à un agent de s’améliorer réellement.

Le modèle mental

Une évaluation est une expérience reproductible. Donnez à un agent une entrée et un environnement, puis observez deux éléments : la trajectoire, c’est-à-dire ce que l’agent a fait au cours du processus, et le résultat, c’est-à-dire l’objet final qu’il a produit.

Évaluez les deux aspects :

  • Résultat : l’objet final répond-il à la tâche ?
  • Trajectoire : l’agent a-t-il choisi les bonnes compétences et outils, évité les actions dangereuses et travaillé de manière efficace ?

Une réponse finale parfaite peut cacher une trajectoire médiocre, tandis qu’une trajectoire maladroite peut néanmoins aboutir à un résultat acceptable. Ne se baser que sur l’un des éléments ne permet pas de voir l’ensemble de la situation.

Les niveaux d’évaluation

Aucun chiffre isolé ne permet de déterminer si un agent est performant. Il faut diviser la question en plusieurs niveaux, chacun étant soumis à sa propre vérification :

  • Affectation des compétences. La bonne compétence a-t-elle été choisie ? Il convient d’examiner la précision, le rappel et les déclencheurs erronés.
  • Respect des compétences. Les instructions associées à la compétence ont-elles vraiment été suivies, y compris les étapes obligatoires et les actions interdites ?
  • Utilisation des outils. Les outils ont-ils été appelés correctement, avec les bons arguments, dans le bon ordre, sans appels inutiles ?
  • Résultat de la tâche. Le résultat fonctionne-t-il ? Les tests, les vérifications de schéma et les assertions comportementales permettent de le savoir.
  • Qualité. Le résultat est-il maintenable et adapté ? C’est une grille d’évaluation ou un évaluateur qui le décide.
  • Sécurité. Les limites relatives aux secrets, aux opérations destructrices et à l’injection de requêtes ont-elles été respectées ?
  • Efficacité. Quel a été le coût en termes de tokens, de latence, d’appels et de tentatives de réessai pour obtenir un résultat réussi ?
  • Une compétence nécessite deux ensembles d’évaluation

    Une compétence n’est pas simplement un ensemble d’instructions. Elle implique une décision quant au moment de l’activer ainsi qu’un plan pour les actions à entreprendre par la suite, ce qui exige donc deux ensembles d’évaluation distincts.

    Les évaluations de déclenchement vérifient si la compétence s’active pour les prompts appropriés. Chaque cas associe un prompt à la compétence attendue, ou à une compétence qui ne doit pas s’activer :

    - prompt: "Patch the vulnerable npm dependencies"
      expected_skill: cve-remediation
    - prompt: "Review authentication input validation"
      forbidden_skill: cve-remediation
    

    Cachez les aspects positifs évidents, reformulez les points positifs, présentez les négatifs qui ont failli être détectés, les prompts ambigus ainsi que les conflits entre deux compétences plausibles. Rapportez une matrice de confusion plutôt que simplement la précision, car un faux positif peut causer autant de dommages qu’un déclencheur manqué.

    Évaluations de l’exécution vérifient si l’utilisation de la compétence améliore le travail. Confrontez un agent qui ne possède pas cette compétence à ce même agent l’ayant acquise, en utilisant des cas, un environnement, un modèle et des outils identiques, et répétez les essais car les agents sont non déterministes. Une compétence ne mérite sa place que lorsque l’amélioration justifie sa complexité supplémentaire et son coût en tokens.

    À quoi ressemble un bon cas

    Préférez des captures de répertoire réalistes aux exemples isolés et anodins. Un bon cas est autonome et peut être vérifié par une machine :

    {
      "id": "fix-null-condition",
      "prompt": "Fix saving rules with a null condition",
      "fixture": "repos/null-condition",
      "setup": ["npm install"],
      "checks": [
        "npm test -- null-condition.test.js",
        "git diff --check"
      ],
      "rubric": [
        "Fixes the root cause",
        "Preserves existing behavior",
        "Adds a regression test",
        "Avoids unrelated changes"
      ],
      "forbidden": [
        "deleting existing tests",
        "hard-coded fixture-specific output"
      ]
    }
    

    Évaluateurs : utilisez le plus puissant dont vous disposez

    Préférez l’évaluateur le plus fiable disponible, et n’avez recours au jugement qu’en dernier recours. En gros, du plus puissant au moins puissant :

    1. affirmations exactes
    2. compilation et tests unitaires ou d’intégration
    3. vérification du schéma ou de l’arbre syntaxique
    4. vérifications comportementales via un navigateur ou une API
    5. inspection statique de la trajectoire
    6. un LLM évaluant selon un rubriche
    7. revue humaine

    Les évaluateurs basés sur des LLM évaluent des critères tels que la clarté et l’adéquation architecturale, mais ils ne doivent pas remplacer les vérifications exécutables. Cachez au juge quelle variante a produit un résultat, et mélangez l’ordre des comparaisons.

    Métriques à suivre

    • Taux de réussite correspond à la proportion de tentatives qui passent toutes les vérifications critiques.
    • Pass@k est la probabilité qu’au moins une des k tentatives fonctionne.
    • Pass^k est la probabilité que toutes les k tentatives fonctionnent, ce qui constitue le signe le plus fiable de fiabilité.
    • Précision et rappel du routage décrivent la qualité du choix des compétences.
    • Taux de régression compte les cas qui réussissaient auparavant mais échouent maintenant.
    • Le coût par tâche réussie, la latence médiane et latente, le nombre d’appels d’outils, les taux de tentative répétée ainsi que la fréquence à laquelle un humain doit intervenir doivent également figurer sur le tableau de bord.

    Pour les agents en production, une fiabilité constante l’emporte généralement sur des résultats impressionnants dans les meilleurs cas.

    Création du jeu de données

    Commencez par 20 à 50 cas tirés de travaux réels : échecs antérieurs et incidents de support, tâches quotidiennes, cas limites, demandes trompeuses ou hostiles, instructions insuffisamment précisées, tâches qui devraient être refusées ou clarifiées, ainsi que des situations où aucune compétence ne devrait être activée.

    Ensuite, divisez-les en trois ensembles :

    • un ensemble de développement que vous pouvez consulter pendant l’amélioration de la compétence
    • un ensemble de réserve laissé intact jusqu’à la validation
    • un ensemble de régression qui reçoit définitivement chaque échec que vous découvrez

    Évitez d’optimiser uniquement en fonction d’un ensemble public fixe, car les agents s’adaptent trop rapidement à sa formulation.

    Un cycle de travail

    Considérez cela comme un développement piloté par des tests pour le comportement des agents :

    1. Captez un échec réel.
    2. Réduisez-le en un cas de test reproductible.
    3. Écrire le juge de qualité avant de manipuler la compétence ou l’agent.
    4. Exécuter plusieurs essais de référence.
    5. Appliquer une modification ciblée.
    6. Réexécuter le cas visé ainsi que l’ensemble du jeu de tests de régression.
    7. Comparer la qualité, la fiabilité, la latence et le coût.
    8. Conserver la modification uniquement si l’équilibre global s’améliore.

    Erreurs fréquentes

    • Évaluer uniquement le texte final
    • Utiliser uniquement des prompts correspondant à des scénarios idéaux
    • Vérifier si les instructions ont été répétées plutôt que suivies
    • Demander à un juge basé sur un LLM des informations que des tests pourraient confirmer
    • Exécuter les tests une seule fois et considérer le résultat comme déterministe
    • Changer en même temps le prompt, le modèle, les outils et la compétence
    • Accepter des tests supprimés ou modifier le juge de qualité en pensant que c’est un succès
    • Utiliser des cas synthétiques qui ne ressemblent en rien au travail réel des utilisateurs
    • Ignorer l’injection de commandes cachée dans les fichiers ou les résultats des outils

    Les métriques de routage en termes concrets

    Supposons qu’il existe une compétence de revue de sécurité et qu’un évaluateur décide, pour chaque commande, si elle doit déclencher une action. Quatre résultats sont possibles :

    • Vrai positif (VP) : elle devrait déclencher une action et l’a fait.
    • Faux positif (FP) : elle n’aurait pas dû déclencher une action mais l’a fait, c’est un déclenchement faux.
    • Faux négatif (FN) : elle aurait dû déclencher une action mais ne l’a pas fait.
    • Vrai négatif (VN) : elle n’aurait pas dû déclencher une action et ne l’a pas fait.

    Précision indique avec quelle fréquence un déclenchement était correct : VP divisé par (VP + FP). Si cette compétence a déclenché l’action dix fois et que huit fois c’était correct, la précision est de 80 %. Une haute précision signifie peu de déclenchements faux.

    Rappel indique le pourcentage de requêtes nécessitant une compétence spécifique que celle-ci a réellement identifiées : TP divisé par (TP + FN). Si dix requêtes en avaient besoin et que sept ont été identifiées, le rappel est de 70 %.

    Un déclencheur faux correspond simplement à un faux positif. Une requête telle que "Upgrade React dependencies" qui active à tort la fonction de revue de sécurité en est un exemple. De nombreux déclencheurs faux signifient une faible précision.

    Une matrice de confusion compte tout. Avec TP = 8, FN = 2, FP = 3 et TN = 7, les requêtes qui devraient déclencher l’action se divisent en 8 et 2, tandis que celles qui ne devraient pas le faire se divisent en 3 et 7. La précision est de 8 / 11, soit environ 72,7 %, et le rappel est de 8 / 10, soit 80 %. Une haute précision signifie que la compétence s’active rarement par erreur. Un haut rappel signifie qu’elle rate rarement une demande pertinente. Des formulations de déclencheur trop larges augmentent généralement le rappel tout en diminuant la précision.

    Où commencer

    Grâce à cette compétence essentielle, un kit compact est très utile. Rassemblez dix prompts qui devraient la déclencher et dix cas où cela ne devrait pas se produire, ainsi que cinq tâches réalistes à exécuter. Ajoutez des vérifications de résultats déterministes, de trois à cinq répétitions de chaque tâche, une exécution de base sans cette compétence, et un ensemble de tests de régression qui conserve chaque échec identifié.

    Une telle configuration réduit considérablement le nombre de problèmes de routage et permet de déterminer si la compétence est réellement utile ou ne fait que donner l’impression de sophistication.

    Un cadre minimal que vous pouvez copier

    Assez de théorie. Un petit programme en Python pur, utilisant uniquement la bibliothèque standard, peut évaluer à la fois le routage d’une compétence et le résultat des tâches d’un agent. Avec environ 70 lignes de code, il illustre chacune des idées mentionnées : fichiers de cas, évaluateurs en couches, exécutions répétées et métriques de fiabilité.

    La structure des dossiers :

    evals/
      cases/
        skills/security-review.trigger.json
        agents/fix-null-condition.json
      graders.py
      metrics.py
      runner.py
      run.py        # CLI entry1. Case files. A skill trigger case is just positives and negatives. An agent case is a prompt plus graders and a run count.
    

    Un fichier de cas déclencheur énumère le nom de la compétence ainsi que les indications indiquant ce qui doit et ne doit pas la déclencher :

    // cases/skills/security-review.trigger.json
    {
      "skill": "security-review",
      "positives": [
        "Audit this endpoint for SQL injection",
        "Check the login flow for auth bypasses",
        "Is this file-upload handler safe?"
      ],
      "negatives": [
        "Upgrade React dependencies",
        "Rename this variable across the repo",
        "Add a loading spinner to the form"
      ]
    }
    

    Un dossier d’agent contient un identifiant, une instruction, un élément fixe ainsi que les vérifications à appliquer :

    // cases/agents/fix-null-condition.json
    {
      "id": "fix-null-condition",
      "prompt": "Fix saving rules with a null condition",
      "fixture": "fixtures/null-condition",
      "setup": ["npm ci"],
      "runs": 5,
      "graders": [
        { "type": "shell", "cmd": "npm test -- null-condition", "critical": true },
        { "type": "shell", "cmd": "git diff --check" },
        { "type": "forbidden", "pattern": "it\\.skip|xit\\(", "message": "must not disable tests" }
      ]
    }
    

    Viennent ensuite les évaluateurs. L’un exécute des commandes shell telles que les suites de tests, un autre scanne la trajectoire à la recherche d’éditions interdites, et un modèle d’arbitre qui ne peut pas savoir quelle variante il évalue s’occupe des qualités subjectives.

    # graders.py
    import re, subprocess
    def shell(step, ctx):
        r = subprocess.run(step["cmd"], cwd=ctx.workdir, shell=True,
                           capture_output=True, text=True)
        ok = r.returncode == 0
        return {"pass": ok, "score": 1 if ok else 0, "detail": r.stdout[-400:]}
    def forbidden(step, ctx):
        bad = re.search(step["pattern"], ctx.diff) is not None
        return {"pass": not bad, "score": 0 if bad else 1,
                "detail": step["message"] if bad else ""}
    def judge(step, ctx):
        v = ctx.llm.rate(step["rubric"], ctx.artifact)  # 0..1, blinded
        return {"pass": v >= step.get("threshold", 0.7), "score": v}
    GRADERS = {"shell": shell, "forbidden": forbidden, "judge": judge}3. Metrics. Success rate, pass@k, pass^k, and the routing confusion matrix — exactly the numbers from earlier.
    

    Le module de métriques transforme les listes de résultats d’exécution en nombres :

    # metrics.py
    def success_rate(rs):
        return sum(1 for r in rs if r["pass"]) / len(rs)
    def pass_at_k(rs):
        return 1 if any(r["pass"] for r in rs) else 0
    def pass_hat_k(rs):
        return 1 if all(r["pass"] for r in rs) else 0
    def routing(positives, negatives, fired):
        tp = sum(1 for p in positives if fired(p))
        fp = sum(1 for n in negatives if fired(n))
        fn = len(positives) - tp
        tn = len(negatives) - fp
        return {"tp": tp, "fp": fp, "fn": fn, "tn": tn,
                "precision": tp / (tp + fp or 1),
                "recall": tp / (tp + fn or 1)}4. The runner. One function per suite. The agent runner repeats each case so pass^k is meaningful; the skill runner just asks the router which skills fire.
    

    Un exécutant charge les dossiers, appelle les évaluateurs, répète chaque exécution et affiche les métriques :

    # runner.py
    import json
    from graders import GRADERS
    from metrics import success_rate, pass_at_k, pass_hat_k, routing
    def run_agent_case(agent, path):
        c = json.load(open(path))
        runs = []
        for _ in range(c.get("runs", 3)):
            ctx = agent.run(c["prompt"], fixture=c["fixture"], setup=c["setup"])
            ok = True
            for step in c["graders"]:
                g = GRADERS[step["type"]](step, ctx)
                if step.get("critical") and not g["pass"]:
                    ok = False
            runs.append({"pass": ok})
        return {"id": c["id"], "success": success_rate(runs),
                "pass_at_k": pass_at_k(runs), "pass_hat_k": pass_hat_k(runs)}
    def run_skill_trigger(router, path):
        c = json.load(open(path))
        fired = lambda prompt: c["skill"] in router.route(prompt)
        return {"skill": c["skill"], **routing(c["positives"], c["negatives"], fired)}5. Run it. The CLI just dispatches on the case type and prints the metrics.
    

    Le lancement produit un résultat de ce type :

    $ python run.py cases/agents/fix-null-condition.json
    fix-null-condition   success=0.80   pass@5=1.00   pass^5=0.20
    $ python run.py cases/skills/security-review.trigger.json
    security-review      precision=0.86  recall=1.00   (tp=6 fp=1 fn=0 tn=5)
    

    Lisez ces lignes comme le recommande toute cette approche. L’agent effectue quatre exécutions sur cinq, donc pass@5 semble parfait, mais pass^5 avec une valeur de 0,20 indique qu’il n’est pas encore fiable. La compétence capture toutes les demandes réelles, avec un taux de rappel de 1,0, mais a été déclenchée une fois à tort, avec une précision de 0,86 ; il reste donc un déclenchement faux à corriger.

    C’est là l’objectif des évaluations : transformer l’expression « cela semblait fonctionner » en chiffres que l’on peut améliorer. Partez d’un cadre comme celui-ci, ajoutez un cas chaque fois que quelque chose ne fonctionne pas, et laissez le ensemble de régression évoluer pour définir ce qui constitue une bonne performance.

    Utilisez un framework existant lorsque c’est possible

    Un cadre personnalisé est utile pour apprendre les mécanismes et pour avoir un contrôle total, mais des projets open source matures fournissent déjà des exécutions, des évaluateurs, des ensembles de données et des tableaux de bord. Examinez-les avant de créer votre propre solution.

    Évaluations générales des prompts et des LLM

    OpenAI Evals est le cadre de type registre original, qui définit les évaluations en YAML à l’aide de graders Python pour n’importe quel modèle, et il convient aux vérifications au niveau de la sortie et à la classification. promptfoo est piloté par des configurations, affiche les prompts par rapport aux modèles dans une matrice côte à côte, intègre des assertions telles que contains, regex, schéma JSON et grille d’évaluation LLM, et dispose d’un mode red-team, ce qui en fait un excellent point de départ pour le routage des compétences et la détection des régressions de prompts. DeepEval fonctionne comme pytest pour les LLM, avec des métriques de fidélité, de pertinence et d’hallucination, ainsi que des grilles d’évaluation G-Eval personnalisées, et s’intègre naturellement dans les processus CI. Ragas cible spécifiquement les pipelines RAG, en évaluant la précision et le rappel du contexte, ainsi que la fidélité et la pertinence des réponses. L’évaluation des LLM de MLflow permet le suivi et la comparaison si MLflow est déjà utilisé.

    Suivi, ensembles de données et plateformes d’arbitrage

    LangSmith propose des ensembles de données, des outils de suivi des trajectoires et des évaluateurs, utiles lorsque l’on doit examiner l’ensemble de la trace plutôt que seulement la réponse. Langfuse est open source, auto-hébergable et indépendant du modèle, avec des fonctionnalités de suivi, d’évaluation et des ensembles de données pour le monitoring en production. Braintrust considère les évaluations comme faisant partie du processus CI, avec des fonctions de notation, des ensembles de données versionnés et une vue diff pour les expériences. Arize Phoenix s’appuie sur le suivi OpenTelemetry et inclut des modèles d’évaluation, pratiques pour détecter les régressions dans le trafic en temps réel. Inspect, du UK AI Safety Institute, est un cadre de résolution et de notation soigneusement conçu qui gagne en popularité pour les évaluations sérieuses d’agents et de sécurité.

    Benchmarks d’agents

    SWE-bench et SWE-bench Verified constituent la norme pour déterminer si un agent est capable de résoudre un véritable problème sur GitHub, en utilisant les tests propres au répertoire comme critère d’évaluation. AgentBench, WebArena, GAIA et τ-bench offrent des critères externes pour évaluer l’utilisation d’outils, les tâches web et les agents à plusieurs étapes. Des frameworks tels qu’AutoGen et LangGraph fournissent des points d’ancrage pour vérifier les appels aux outils et les étapes intermédiaires.

    Choix

    • Pour les prompts et le routage des compétences uniquement, promptfoo est le moyen le plus rapide pour configurer et valider les assertions.
    • Pour des métriques basées sur le code et adaptées aux pipelines CI, envisagez DeepEval ou Braintrust.
    • Pour évaluer le déroulement des agents à plusieurs étapes, optez pour LangSmith, Langfuse ou Inspect.
    • Pour le RAG, ajoutez Ragas.
    • Pour un véritable benchmark d’agents de codage, utilisez SWE-bench Verified.

    Ce modèle s’applique partout : les cas d’usage, les évaluateurs, les exécutions répétées et le suivi dans le temps. Un cadre préétabli gère les aspects techniques, il faut donc maintenir la discipline et choisir l’outil qui convient à votre stack. Le harnais personnalisé est préférablement réservé aux lacunes laissées par ces outils, ou pour des projets qui souhaitent zéro dépendance dans le CI.