La première fois qu'une équipe branche un modèle de langage dans une base de code testée, quelqu'un écrit un test qui compare la sortie à une chaîne de caractères attendue. Il passe le lundi, échoue le mardi, et l'équipe le désactive le mercredi. À partir de là, la fonctionnalité part en production sans filet, et c'est ça le vrai problème — pas le test qui a échoué.
Le raisonnement à changer tient en une phrase : on ne vérifie plus une égalité, on vérifie qu'un comportement reste dans des bornes acceptables. Ça se teste, mais avec d'autres outils.
Trois familles de tests, trois usages
Le jeu de référence noté
C'est le socle. Un ensemble de cas d'entrée représentatifs, une grille de notation, et une exécution complète à chaque changement significatif — de prompt, de version de modèle, de source de données.
Ce qui compte dans la construction : les cas viennent de la production réelle, pas d'exemples fabriqués. Et la grille décompose plutôt qu'elle ne moyenne. Sur une extraction, je note séparément l'exactitude de chaque champ. Sur une génération de texte, je note le format, la présence des éléments obligatoires, l'absence d'affirmation non étayée.
La notation peut être partiellement automatisée quand le critère est vérifiable par programme — format JSON valide, champ présent, valeur dans une liste fermée, montant identique à la source. Le reste demande un œil humain, et c'est là qu'un jeu de 40 cas devient un vrai avantage : c'est relisable en une heure, un jeu de 400 ne le sera jamais.
Les tests de non-régression sur les cas critiques
Sous-ensemble du jeu de référence, mais avec un statut différent. Ce sont les cas où une erreur a une conséquence sérieuse : un dossier client sensible, un calcul qui part en facturation, un refus qui aurait dû être une escalade.
Sur ceux-là, le seuil est binaire. Pas de moyenne, pas de tolérance. Si un cas critique échoue, la version ne part pas. C'est la seule catégorie où j'accepte une règle rigide, parce que c'est celle qui protège la confiance dans l'outil.
Ces cas s'enrichissent au fil du temps : chaque incident de production donne un nouveau cas critique, ajouté le jour même. C'est la même discipline que pour un bug classique, appliquée à un comportement probabiliste.
Les tests de garde-fous
Ceux-là ne testent pas la qualité, ils testent les limites. Trois catégories que je vérifie systématiquement.
- Le refus. Le système doit refuser hors périmètre, et le faire proprement. Demande sans rapport avec le métier, question qui appelle un avis médical ou juridique, information manquante pour répondre. Le comportement attendu est écrit dans la spécification, sinon il n'est pas testable.
- Les données sensibles. Rien de confidentiel ne doit ressortir là où ça ne doit pas. Cas de test avec des identifiants, des données personnelles, des informations d'un autre client. Sur ce terrain, je m'en tiens à des principes généraux et je renvoie aux obligations propres à chaque secteur : ce que j'écris ici n'est pas un avis juridique.
- Les injections. Une instruction glissée dans un document que le système lit doit rester du texte, pas devenir une consigne. Un jeu de tests dédié, avec des tentatives classiques d'écrasement d'instruction, à rejouer à chaque évolution du prompt système.
Le seuil d'acceptation
C'est la décision que les équipes repoussent le plus longtemps, et il faut la prendre avant la mise en production, pas pendant.
Un seuil se formule sur trois lignes :
Sur le jeu de référence, au moins X % des cas obtiennent la note maximale sur les critères bloquants. Zéro échec sur les cas critiques. Zéro fuite sur les tests de garde-fous.
Le X ne se choisit pas par intuition. Il se déduit de deux choses : le baseline humain sur la même tâche, et le coût réel d'une erreur qui passe. Une erreur rattrapée par un contrôle en aval permet un seuil plus bas qu'une erreur qui part directement chez le client.
Le seuil doit être écrit, daté, et porté par le propriétaire de la fonctionnalité. Sinon il se renégocie la veille de la mise en ligne, dans le sens que tu devines.
La revue humaine par échantillon
Les tests couvrent ce que tu as anticipé. La production apporte le reste. D'où la troisième pièce du dispositif, celle qui fonctionne dans la durée : une revue régulière d'un échantillon de sorties réelles.
Le format qui tient : une personne, une heure par semaine, un tirage aléatoire de vingt à trente cas passés en production. Elle applique la même grille que le jeu de référence. Elle note ce qui l'a surprise.
Deux choses en sortent. Des cas à ajouter au jeu de référence — c'est ainsi qu'il reste vivant. Et une dérive éventuelle : quand la qualité baisse sans qu'aucun test n'échoue, c'est souvent que les entrées réelles ont changé, pas le modèle.
Cette heure hebdomadaire est la première à sauter quand l'équipe est sous pression. Mets-la dans la definition of done et donne-lui un nom de propriétaire, sinon elle disparaîtra au deuxième mois.
Ce qui ne marche pas
Faire noter les sorties par un modèle sans jamais vérifier le noteur. C'est un raccourci utile pour dégrossir, mais il faut le calibrer contre des notes humaines sur un échantillon, sinon tu automatises un jugement dont tu ignores la fiabilité.
Fixer la température à zéro et se dire qu'on a réglé le problème de reproductibilité. Ça réduit la variabilité, ça ne l'annule pas, et ça n'aide en rien contre une entrée inattendue.
Empiler des milliers de cas de test. Un gros jeu ne se relit pas, donc il ne se maintient pas, donc il finit par mesurer autre chose que ce que tu crois.
Par où commencer lundi
Prends ta fonctionnalité IA en cours et écris les cinq cas critiques : ceux où une erreur ferait vraiment mal. Rien que ça, mis en test avant chaque livraison, t'apporte plus de sécurité que trois semaines de couverture générale.