Alejandro Rioja.
AI Agents Operations

Le Harness d'Évals que J'Utilise pour Déployer des Agents IA Sans Peur

Alejandro Rioja
Alejandro Rioja
7 min de lecture
TL;DR

Déployer des agents sans peur tient à une seule chose : un harness d'évals. Un ensemble fixe de cas de test notés, scorés automatiquement (assertions plus un juge LLM), exécuté avant chaque changement de prompt ou de modèle. Si le score tient, on déploie. Le jeu de tests est construit à partir d'échecs réels en production.

Newsletter gratuite

Chaque mercredi. 28 400+ opérateurs. Zéro superflu.

Table des matières

Mis à jour juin 2026.

TL;DR : La raison pour laquelle je peux changer un prompt ou échanger un modèle sur un agent en production sans retenir mon souffle tient à une seule chose : un harness d’évals. Un ensemble fixe de cas de test notés, scorés automatiquement — des assertions strictes là où je peux les écrire, un juge LLM là où je ne peux pas — exécuté avant chaque changement. Le score tient, je déploie. Le score baisse, je m’abstiens. Le jeu de tests n’est pas synthétique ; il est construit à partir d’échecs réels en production, donc chaque bug devient un test de régression permanent.

Lecture de l’opérateur : Sur plus de 100 agents, la différence entre ceux que je touche avec confiance et ceux qui me font peur, c’est de savoir s’ils ont des évals. Pas de harness d’évals signifie que chaque ajustement de prompt est un pari. Un harness d’évals transforme « je pense que c’est mieux » en « c’est mesurablement 4 points de mieux et ça n’a rien cassé ». C’est tout le déverrouillage.

Tu ne déploierais pas du code sans tests. Les gens déploient des agents sans évals en permanence, puis se demandent pourquoi un « minuscule ajustement de prompt » a cassé la production. Un harness d’évals est la suite de tests pour les logiciels non déterministes. Voici celui que j’exécute réellement.

Commence avec un jeu de tests construit à partir d’échecs réels

Le harness ne vaut que ses cas de test, et les meilleurs cas de test viennent de la production, pas de ton imagination. Chaque fois qu’un agent échoue dans la nature, je capture l’entrée exacte (je journalise chaque exécution avec un ID de trace — voir comment déboguer un agent en production) et je la transforme en cas d’éval :

typescript
interface EvalCase {
  id: string;
  input: AgentInput;        // l'entrée exacte de production
  expected?: string;        // vérité terrain, quand elle existe
  assertions: Assertion[];  // vérifications strictes qui doivent passer
  rubric?: string;          // pour le juge LLM, quand la sortie est ouverte
}

Deux pratiques comptent ici. Tire de la production, pour que tes évals testent ce qui casse réellement, pas ce que tu as supposé qui pourrait casser. Et couvre l’éventail — le chemin heureux, les cas limites, les entrées adversariales et les entrées vides/malformées qui provoquent des échecs silencieux. Un jeu de tests de 30 à 50 cas bien choisis attrape bien plus que 500 cas paresseux. Je préfère avoir 40 cas représentant chacun un mode d’échec réel que mille qui testent tous le même chemin facile.

Score avec des assertions d’abord, un juge LLM ensuite

Toute sortie n’a pas besoin d’un modèle pour la noter. Je me tourne vers le scoreur le moins cher qui fonctionne.

Assertions strictes pour tout ce qui est structuré. La sortie se parse-t-elle en JSON valide ? Contient-elle le champ requis ? La date extraite est-elle dans la plage ? A-t-elle appelé le bon outil avec les bons arguments ? Elles sont déterministes, gratuites et sans ambiguïté — écris-en autant que tu peux.

typescript
const assertions: Assertion[] = [
  (out) => isValidJSON(out),
  (out) => parse(out).category in ALLOWED_CATEGORIES,
  (out) => parse(out).confidence >= 0 && parse(out).confidence <= 1,
];

Un juge LLM pour le reste ouvert — le ton, l’utilité, « est-ce que ça a vraiment répondu à la question ». Ici tu donnes à un modèle l’entrée, la sortie et une grille, et tu lui demandes de noter. Deux règles gardent le juge honnête : rends la grille spécifique (une échelle de 1 à 5 avec des ancres décrites bat « note la qualité »), et utilise un modèle puissant comme juge — juger est une tâche de raisonnement, donc c’est un endroit où je paie volontiers pour Sonnet même quand l’agent lui-même tourne sur Haiku selon les calculs de coûts. Une grille vague ou un juge faible te donne du bruit qui ressemble à du signal.

Exécute le harness avant chaque changement

Le harness existe pour répondre à une question : ce changement a-t-il rendu l’agent meilleur ou pire ? Donc je l’exécute avant chaque édition de prompt, échange de modèle ou changement d’outil.

bash
# référence sur main
npm run eval -- --suite=booking-agent > baseline.json

# fais le changement, puis relance
npm run eval -- --suite=booking-agent > candidate.json

# compare
npm run eval:diff baseline.json candidate.json

Le diff montre le score agrégé, le pass/échec par cas et — surtout — quels cas spécifiques ont régressé. Un agrégat qui grimpe pendant que trois cas cassent silencieusement n’est pas une amélioration ; c’est un compromis que je veux voir et approuver, pas un qui se faufile. Surveiller le diff par cas, c’est comme ça qu’on évite « corrigé une chose, cassé deux autres », le mode d’échec qui rend les gens craintifs de leurs propres prompts.

Pose une barrière anti-régression et laisse-la bloquer

Une fois que tu fais confiance au harness, branche-le sur le chemin vers la production comme une barrière. Ma règle est franche : un changement qui fait passer le score sous le seuil de référence ne se déploie pas. Pas « je regarderai ça plus tard » — c’est bloqué, comme un test CI qui échoue.

typescript
const PASS_THRESHOLD = 0.90; // 90 % des cas doivent passer
if (candidate.passRate < PASS_THRESHOLD || candidate.passRate < baseline.passRate) {
  throw new Error(`Eval regression: ${candidate.passRate} < ${baseline.passRate}`);
}

C’est ce qui transforme les évals d’un agrément en la chose qui te permet d’avancer vite. La barrière est ce qui rend « déployer sans peur » littéralement vrai : le pire cas pour un mauvais changement est une exécution d’éval en rouge, pas un incident en production. Et comme le jeu de tests grandit chaque fois que quelque chose casse, la barrière devient plus stricte et plus protectrice avec le temps, d’elle-même.

Tiens compte du non-déterminisme dans le scoring

Une subtilité qui fait trébucher les gens : la même entrée peut obtenir un score différent d’une exécution à l’autre parce que le modèle échantillonne différemment. Si tu exécutes chaque cas une seule fois, tu verras des régressions fantômes — un cas « cassé » qui n’est en réalité que du bruit d’échantillonnage.

Deux remèdes. Exécute les évals à temperature: 0 pour réduire la variance (ça ne l’éliminera pas complètement). Et pour les cas que tu as vus vaciller, exécute-les N fois et prends le taux de réussite, pas un seul pass/échec. Un cas qui passe 9 fois sur 10 est en meilleure forme qu’un qui passe 5 fois sur 10 même si les deux peuvent afficher une seule exécution verte. C’est le même principe du volume-sur-l’anecdote que j’utilise quand je débogue des échecs intermittents — une exécution est une opinion, cinquante exécutions sont des données.

Boucle la boucle avec la surveillance de production

Le harness d’évals teste contre des cas connus. La production en lance des inédits. Donc la boucle est : surveille le comportement en direct, attrape un nouveau mode d’échec, transforme-le en cas d’éval, corrige-le, et maintenant il est protégé en permanence. Le côté surveillance — suivre le taux de réussite, la validité de la sortie et le coût par exécution sur le trafic en direct — c’est ce que je couvre dans comment je mesure si un agent IA fonctionne vraiment. Évals et surveillance sont deux moitiés du même système : la surveillance trouve les bugs, les évals s’assurent qu’ils restent morts.

Cette boucle de rétroaction est le vrai produit. N’importe quel jeu d’évals individuel devient obsolète ; un processus qui convertit chaque échec de production en test permanent se renforce chaque semaine. C’est ainsi qu’un agent passe de « effrayant à toucher » à quelque chose que je refactoriserai un vendredi après-midi sans broncher.

FAQ

Qu’est-ce qui entre dans un jeu d’évals pour un agent IA ?

Des entrées réelles de production transformées en cas notés — chemin heureux, cas limites, entrées adversariales et malformées — chacun avec des assertions strictes et, pour les sorties ouvertes, une grille de juge LLM. De 30 à 50 cas tirés d’échecs réels battent des centaines de cas synthétiques qui testent tous le chemin facile.

Devrais-je utiliser un LLM pour noter les sorties de l’agent ?

Utilise des assertions strictes partout où la sortie est structurée (JSON valide, champ correct, bon appel d’outil) — elles sont gratuites et déterministes. Réserve un juge LLM pour les qualités ouvertes comme le ton et l’utilité, avec une grille spécifique et un modèle juge puissant pour obtenir du signal, pas du bruit.

Comment empêcher un changement de prompt de casser silencieusement la production ?

Exécute le harness d’évals avant chaque changement et compare à une référence, en surveillant les régressions par cas, pas seulement le score agrégé. Puis conditionne les déploiements au résultat afin que tout changement passant sous le seuil de référence soit bloqué comme un test qui échoue.

Comment gérer le non-déterminisme dans les évals ?

Exécute à température 0 pour réduire la variance, et pour les cas qui vacillent, exécute-les plusieurs fois et note le taux de réussite plutôt qu’une seule exécution. Un cas qui passe 9 fois sur 10 est plus sain qu’un qui passe 5 fois sur 10, même si une seule exécution les affiche tous deux en vert.

Continuer à lire

Recevez le guide IA dans votre boîte mail

Chaque mercredi. 28 400+ opérateurs. Zéro superflu.

↵ pour voir tous les résultats esc esc pour fermer