Évaluer un agent IA : evals, pass@k et pass^k, juge LLM et journal des échecs
Évaluer un agent IA consiste à lancer régulièrement un jeu fixe de tâches réelles, à vérifier le résultat automatiquement et à calculer des métriques, et non à se fier à l'impression laissée par quelques bonnes sessions. L'essentiel est de mesurer non seulement pass@k (au moins une des k tentatives réussit), mais aussi pass^k (toutes les k tentatives réussissent), car c'est la stabilité qui détermine si l'on peut confier un travail à l'agent sans supervision.
Pourquoi évaluer un agent IA quand on voit bien qu'il travaille
C'est justement là que l'on voit mal. Un agent n'a pas été bloqué une seule fois en une semaine après la modification d'un prompt : est-ce une réparation, ou simplement une semaine de tâches faciles ? Un ingénieur est sûr que le nouveau modèle a tout changé, un second a regardé le même journal et n'a rien remarqué. Ils ont raison l'un et l'autre, dans la mesure exacte où personne n'a compté.
L'évaluation d'un agent IA (evals) remplace l'impression par un chiffre. On prend un jeu fixe de tâches, on fait tourner l'agent, on vérifie automatiquement le résultat et on compare les métriques avant et après un changement. La discussion « est-ce mieux ? » se tranche alors par un tableau, et non par l'autorité de quelqu'un.
Sans evals, toute modification du harnais — prompt, AGENTS.md, jeu d'outils, modèle — est un pari à l'aveugle. Avec eux, c'est une expérience dont le résultat se mesure.
Pourquoi le « ressenti » trompe
L'impression qu'on tire du travail d'un agent comporte trois erreurs systématiques, et toutes poussent vers une fausse assurance.
- Le biais du survivant. Les exécutions réussies sont retenues et montrées aux collègues, les échecs sont relancés et oubliés. Une fiabilité calculée sur les seules réussites ne dit rien de l'endroit où l'agent casse réellement.
- Un petit échantillon. Trois succès d'affilée sont un événement banal, même pour un agent qui réussit une fois sur deux. La probabilité est de 0,5³ = 12,5 %, soit environ une série sur huit.
- Le ton assuré. L'agent écrit « c'est terminé, tous les tests passent » avec la même assurance, que ce soit vrai ou faux. La confiance du modèle n'est pas calibrée : le ton d'une réponse n'est pas un signal de justesse.
D'où la règle : tout ce qui n'est ni consigné ni recalculé est considéré comme non mesuré.
pass@k et pass^k : deux métriques qu'on confond
L'agent n'est pas déterministe : la même tâche peut réussir à une nouvelle exécution et échouer à la suivante. On lance donc chaque tâche plusieurs fois et l'on calcule l'une de deux métriques.
pass@k — au moins une tentative sur k réussit
Cette métrique vient de l'évaluation de la génération de code. Elle répond à la question : « le système est-il capable, en principe, de résoudre la tâche si on lui donne plusieurs essais ? » C'est une métrique honnête pour le scénario où un humain choisit la meilleure de plusieurs propositions, ou quand une vérification automatique fiable élimine les mauvaises.
pass^k — toutes les k tentatives réussissent
Cette métrique répond à une autre question : « à quel point l'agent résout-il la tâche de façon stable ? » Elle décrit le travail sans supervision, où l'agent est lancé de nombreuses fois et où chaque échec coûte de l'argent ou du temps.
La différence entre les deux est énorme. Supposons qu'un agent résolve la tâche avec une probabilité de 70 % par tentative, les tentatives étant indépendantes :
| k | pass@k = 1 − 0,3^k | pass^k = 0,7^k |
|---|---|---|
| 1 | 70 % | 70 % |
| 3 | 97,3 % | 34,3 % |
| 5 | 99,8 % | 16,8 % |
| 10 | ~100 % | 2,8 % |
Selon pass@5, l'agent paraît presque parfait ; selon pass^5, il n'est pas fiable. Les deux chiffres sont justes, ils décrivent simplement des choses différentes. Si vous comptez le laisser travailler de manière autonome, regardez pass^k : il est plus proche de ce que vous observerez dans un usage réel.
Comment calculer en pratique
Lancez chaque tâche n fois (par exemple 5) et notez le nombre de succès c. Pour une tâche, pass^k vaut approximativement la part des séries où les k exécutions sont toutes réussies ; plus simplement, on estime la probabilité de succès p = c / n et on l'élève à la puissance k. Pour un jeu de tâches, on fait la moyenne sur les tâches.
import json
from statistics import mean
# results.jsonl : {"task": "add-pagination", "runs": [true, true, false, true, true]}
rows = [json.loads(line) for line in open("results.jsonl")]
def pass_at_k(runs, k):
p = sum(runs) / len(runs)
return 1 - (1 - p) ** k
def pass_pow_k(runs, k):
p = sum(runs) / len(runs)
return p ** k
for k in (1, 3, 5):
print(k,
round(mean(pass_at_k(r["runs"], k) for r in rows), 3),
round(mean(pass_pow_k(r["runs"], k) for r in rows), 3))
L'estimation par p à la puissance k est grossière quand n est petit, mais pour comparer entre elles des versions du harnais, elle suffit généralement. Il est plus important que n et le jeu de tâches ne changent pas entre deux comparaisons.
Comment constituer un jeu de tâches pour les evals
Le jeu de tâches est le principal capital. Une bonne métrique calculée sur de mauvaises tâches mesure autre chose.
Prenez des tâches de votre réalité
Les benchmarks publics comme SWE-bench sont utiles pour comparer des modèles, mais leurs tâches sont sélectionnées : description claire, tests prêts. Dans votre dépôt, les exigences sont floues et certains tests manquent, si bien que le score du benchmark est presque toujours supérieur à ce que l'agent montrera chez vous. Les meilleures sources de tâches sont les tickets fermés et les échecs réels de l'agent, tirés du journal.
Composition du jeu
- 20 à 50 tâches pour commencer. Moins, et le bruit efface la différence entre deux versions. Davantage, et chaque lancement devient coûteux : on finit par ne plus le lancer.
- Des types variés : nouvelle fonctionnalité, correction de bogue, refactorisation, tâche sur un module étranger, tâche piège (où la bonne réponse est « ne fais pas ça » ou « il faut une précision »).
- Chaque tâche échouée en travail réel devient un test. Ainsi le jeu grandit avec la connaissance des points faibles de l'agent, et les régressions ne reviennent pas inaperçues.
- Un état initial figé : un commit précis, des dépendances verrouillées, un environnement identique. Sinon, on mesure la dérive de l'environnement et non l'agent.
Format d'une tâche
Chaque tâche est une description, un état initial et un critère de réussite vérifiable sans humain.
id: add-pagination
repo_ref: 3f2c1ab
prompt: |
Ajoute la pagination à GET /payments : paramètres limit (par défaut 20, maximum 100)
et cursor. La réponse contient next_cursor.
check:
- pytest tests/test_payments_pagination.py
- mypy app/
limits:
max_changed_files: 6
Remarquez que le critère de réussite est une définition de « terminé » écrite sous forme de commandes. Si vous ne pouvez pas écrire le critère d'une tâche, c'est le signe que la tâche est aussi ambiguë pour l'agent.
Vérifications automatiques ou juge LLM
On peut vérifier le résultat par du code ou par un autre modèle. Chaque méthode a son domaine.
| Vérifications automatiques (code) | Juge LLM | |
|---|---|---|
| Ce qu'elles contrôlent | Tests, types, linter, E2E, taille du diff, fichiers interdits | Conformité aux exigences, lisibilité, style, qualité de l'explication |
| Déterminisme | Total | Non : la note varie d'une exécution à l'autre |
| Coût | Presque nul | Un appel de modèle supplémentaire par tâche |
| Risque principal | Ne contrôle pas tout : les tests sont verts, mais la fonctionnalité n'est pas la bonne | Le juge approuve une solution assurée, mais fausse |
Règle : d'abord le code, le juge en complément
Tout ce qui peut être vérifié de façon déterministe doit l'être. Ajoutez un juge LLM seulement pour les propriétés que le code ne sait pas exprimer, et jamais à la place des tests.
Comment rendre le juge LLM utile
- Un contexte différent de celui du générateur. Le juge ne doit pas voir le raisonnement de l'agent, seulement la tâche, les critères et le diff final. Sinon il répète les mêmes erreurs : c'est la N-version, deux regards indépendants au lieu d'un seul.
- Une grille plutôt que « note sur dix ». Des questions précises auxquelles on répond par oui ou non : « la validation de limit > 100 est-elle présente ? », « des fichiers hors de app/payments ont-ils été modifiés ? ».
- Un calibrage sur un étiquetage manuel. Étiquetez à la main 20 à 30 résultats et comparez-les aux verdicts du juge. Si la concordance est faible, c'est la grille qu'il faut changer, et non faire davantage confiance au juge.
- Asymétrie des erreurs. Un faux « terminé » coûte plus cher qu'un faux « pas terminé » : le premier part en production, le second coûte une relance. Réglez le juge pour qu'il rejette en cas de doute.
Quelles métriques suivre en plus de la part de réussite
La part des tâches résolues n'est que le sommet. Pour savoir précisément quoi réparer, il faut les métriques de fiabilité de l'ingénierie classique.
- MTBF — le nombre d'étapes ou de tâches que l'agent enchaîne avant de se bloquer. Il montre à quelle fréquence il casse.
- MTTR — le temps nécessaire pour revenir à un état de travail après une panne. Le réduire coûte presque toujours moins cher que d'augmenter le MTBF : un bon fichier de progression et un environnement reproductible raccourcissent la reprise plusieurs fois.
- Rayon de dégâts — la quantité de code qu'une étape ratée abîme. On le limite par une borne sur le diff et par l'isolation de la copie de travail.
- Part des faux « terminé » — les tâches où l'agent a déclaré le succès alors que la vérification a échoué. C'est la métrique la plus dangereuse : elle montre s'il est permis de croire le rapport de l'agent.
- Coût et temps — tokens et minutes par tâche. Un harnais qui fait gagner 5 % de réussite mais double le coût ne gagne pas toujours.
Journal des échecs : evals du quotidien
Toutes les équipes ne peuvent pas construire tout de suite un banc d'essai. La version minimale de l'évaluation est un journal des échecs à trois colonnes.
| Tâche | Résultat | Couche |
|-------------------------|------------------------------------|---------------|
| pagination /payments | « terminé », 2 tests rouges | vérification |
| correction timeout webhook | 30 min de pip install | environnement |
| refactorisation refunds | ancienne syntaxe de l'ORM | contexte |
La couche désigne l'un des cinq endroits où l'agent casse : spécification de la tâche, contexte, environnement d'exécution, retour de vérification, gestion de l'état. Après vingt entrées, le vrai goulot d'étranglement apparaît, et presque jamais là où vous le pensiez. Chaque ligne du journal est un candidat pour le jeu de tâches des evals.
Pourquoi un modèle plus puissant ne suffit pas
Premier réflexe face aux échecs de l'agent : prendre un modèle plus cher. Cela aide parfois, mais l'écart entre le benchmark et votre réalité est le plus souvent comblé non par le modèle, mais par l'environnement qui l'entoure.
Si l'agent passe une demi-heure à monter l'environnement, c'est la couche environnement, et le modèle phare passera les mêmes trente minutes. S'il déclare « terminé » alors que les tests sont rouges, c'est la couche vérification : il n'a pas de commande qui dise la vérité. S'il écrit du code dans un style étranger, on ne lui a pas donné les conventions du projet. Aucun de ces problèmes ne tient à l'intelligence du modèle.
Les evals permettent de le vérifier honnêtement. Faites tourner le jeu avec le modèle actuel, puis avec un modèle plus cher, puis avec le modèle actuel et un AGENTS.md enrichi des commandes de vérification. Souvent, la seconde modification apporte plus de progrès que la première, à coût nul. Mais ne le croyez pas sur parole : c'est précisément pour ce genre de comparaison que le jeu existe.
Plan en cinq jours : évaluer un agent IA en une semaine
- Jour 1. Ouvrez un journal des échecs et notez-y chaque défaillance de l'agent en indiquant la couche.
- Jour 2. Sélectionnez 20 tâches parmi les tickets fermés et le journal. Pour chacune, fixez un commit et écrivez le critère de réussite sous forme de commandes.
- Jour 3. Écrivez un lanceur : copie de travail propre, lancement de l'agent avec le prompt de la tâche, exécution des vérifications, écriture du résultat en JSONL.
- Jour 4. Lancez chaque tâche 3 à 5 fois. Calculez pass@1, pass^3, la part des faux « terminé » et le coût moyen.
- Jour 5. Changez une seule chose dans le harnais et relancez. Ne comparez que pour un jeu identique et un même nombre de répétitions.
Modifiez une variable à la fois. Si vous changez dans une même expérience le modèle, le prompt et les outils, vous ne saurez pas ce qui a fonctionné.
Erreurs typiques dans l'évaluation des agents
- Une seule exécution par tâche. Le caractère non déterministe de l'agent fait de ce résultat une loterie. Trois répétitions au minimum.
- Le jeu change entre deux comparaisons. Ajouter de nouvelles tâches et modifier le prompt en même temps rend les chiffres incomparables.
- L'agent voit les tests de contrôle. Si les tests sont dans le dépôt, l'agent peut adapter le code à ces tests, ou simplement les modifier. Gardez les vérifications cachées hors de la copie de travail et contrôlez que l'agent n'a pas touché aux fichiers de test.
- Le rapport de l'agent à la place de la vérification. « Tous les tests sont passés » dans la réponse du modèle n'est pas un résultat. Le résultat est le code de retour de la commande lancée par le lanceur.
- Seulement pass@k. Un beau chiffre pour une présentation, une mauvaise prévision pour un travail autonome.
En résumé
Évaluer un agent IA, c'est un jeu fixe de tâches réelles, des vérifications automatiques et des métriques recalculées après chaque modification du harnais. pass@k montre ce que l'agent est capable de faire, pass^k dit si on peut lui faire confiance sans supervision. Les vérifications automatiques donnent la vérité, un juge LLM avec une grille et un contexte séparé les complète là où le code ne peut rien. Quant au journal des échecs réparti sur cinq couches, il indique par quoi commencer, et le plus souvent ce n'est pas le modèle. Les métriques de fiabilité et la boucle de diagnostic sont présentées en pratique dans le cours de harness engineering.
Questions fréquentes
Combien de tâches faut-il pour évaluer un agent ?
Pour commencer, 20 à 50 tâches réelles avec un critère de réussite automatique et 3 à 5 répétitions de chacune suffisent. Un jeu plus petit ne distingue pas une amélioration du bruit ; un jeu plus grand devient coûteux et on finit par ne plus le lancer.
Peut-on évaluer un agent uniquement avec des benchmarks publics ?
Non. Les benchmarks publics comparent les modèles sur des tâches sélectionnées, avec des tests prêts à l'emploi, alors que les exigences et les tests de votre dépôt sont différents. Pour décider de votre propre harnais, il faut un jeu de tâches à vous.
Quelle différence entre pass@1 et pass^1 ?
Aucune : avec une seule tentative, les deux métriques sont égales à la part des exécutions réussies. Elles ne commencent à diverger qu'à partir de k supérieur à un.
Le juge LLM peut-il être le même modèle que l'agent ?
Oui, à condition qu'il ait un contexte séparé : il ne voit que la tâche, la grille et le diff final, sans le raisonnement de l'agent. Ses verdicts doivent malgré tout être recoupés avec un étiquetage manuel.
À quelle fréquence lancer les evals ?
Après chaque modification notable du harnais : prompt, fichier d'instructions, jeu d'outils, modèle. Il est aussi utile de lancer le jeu selon un calendrier, pour repérer la dérive de l'environnement et des dépendances.
Ce sujet est traité en détail avec de la pratique dans le cours « Harness Engineering: инженерия надёжности AI-агентов ».
- Метрики надёжности AI-агента: MTBF, MTTR, радиус поражения и закон Литтла
- Почему AI-агент ломается в проде: пять слоёв отказа и диагностическая петля