Un test logiciel classique tient en une phrase : pour cette entrée, j'attends cette sortie. Si le résultat diffère, le test échoue et la chaîne d'intégration bloque la livraison.
Cette phrase cesse de fonctionner dès qu'un modèle de langage entre dans le chemin. La même question, posée deux fois au même modèle sur le même corpus, produit deux réponses différentes. Elles peuvent être toutes deux excellentes, toutes deux fausses, ou l'une bonne et l'autre médiocre. L'égalité stricte n'a plus de sens.
Nous éditons NeuraScope et nous la déployons chez nos clients. Cette double position nous oblige à répondre à une question que beaucoup d'équipes contournent : comment garantir qu'une modification n'a pas dégradé la qualité, quand la qualité n'est pas une valeur exacte ?
Voici ce que nous appliquons, avec nos chiffres réels, et ce que ces chiffres ne disent pas.
Séparer ce qui est déterministe de ce qui ne l'est pas
La première erreur consiste à traiter une plateforme d'IA comme un seul bloc imprévisible. Elle ne l'est pas.
Dans NeuraScope, l'écrasante majorité du code produit des résultats parfaitement prévisibles. Un document importé est découpé en fragments : pour un fichier donné, avec les mêmes paramètres, le découpage est identique à chaque exécution. Un connecteur qui récupère des données renvoie ce que la source contient. Un workflow qui enchaîne des nœuds suit le chemin décrit. Le cloisonnement entre projets répond par oui ou par non.
L'ordre de grandeur le dit mieux qu'un raisonnement. Notre mesure du 5 août 2026 porte sur 72 407 lignes de code applicatif côté plateforme. Le non-déterminisme se concentre en réalité sur deux points : la sélection des passages pertinents dans un corpus, et la génération de la réponse finale par le modèle de langage. Deux points seulement, mais les deux qui décident de la valeur perçue par l'utilisateur.
Tout le reste se teste normalement, avec des assertions strictes. Et c'est là que se logent la plupart des régressions réelles : une extraction de texte qui perd les tableaux d'un PDF, un connecteur qui tronque au-delà d'un certain volume, un workflow dont la branche d'erreur n'est jamais empruntée.
La conséquence pratique est simple. Avant d'inventer une méthode d'évaluation sophistiquée pour la partie IA, il faut couvrir sévèrement tout ce qui est prévisible. Une équipe qui néglige cette base passe son temps à chasser des variations de formulation pendant qu'un connecteur perd silencieusement des données.
Ce que la couverture a révélé
Nous avons conduit une campagne de couverture sur l'ensemble de la plateforme. Le résultat global, au 5 août 2026 : 81,25 %, soit 58 833 lignes couvertes sur 72 407, réparties sur 33 couches applicatives toutes au-dessus du seuil de 80 % que nous nous étions fixé.
Le chiffre global est le moins intéressant. Ce qui compte est la répartition avant campagne.
Quatorze couches partaient de zéro. Aucun test. Parmi elles : les contrôleurs API, RAG, Chat, MCP, CrewAI, Projects, Canvas, Personas, Tools, LLM, Orchestration, Integration, Public, et la validation des requêtes HTTP. Autrement dit, une part substantielle de ce qui fait la valeur fonctionnelle de la plateforme n'était vérifiée par rien d'autre que l'usage.
Les couches déjà testées l'étaient inégalement, et pas là où on l'aurait souhaité :
| Couche | Avant | Après |
|---|---|---|
| Jobs (traitements asynchrones) | 21,1 % | 85,9 % |
| Contrôleurs Customer | 39,6 % | 80,9 % |
| Modèles | 40,3 % | 81,7 % |
| Contrôleurs Security | 40,3 % | 80,5 % |
| Services | 51,0 % | 80,4 % |
| Middleware | 67,3 % | 87,8 % |
Deux lignes de ce tableau méritent qu'on s'y arrête.
Les Jobs à 21 %. Ce sont les traitements asynchrones : l'indexation d'un corpus, la vectorisation, les tâches longues. Précisément le code qui s'exécute hors de la vue de l'utilisateur, dont l'échec est silencieux, et qu'un test manuel ne rencontre jamais. Le code le moins testé était le plus difficile à surveiller autrement.
La sécurité à 40 %. Les contrôleurs qui portent l'authentification et les contrôles d'accès étaient couverts à moins de la moitié. Sur une plateforme dont l'argument central est le cloisonnement des données entre organisations, c'est le point où l'écart entre le discours et la vérification était le plus large.
Ce constat vaut au-delà de notre cas. Quand une équipe mesure sa couverture pour la première fois, elle découvre rarement un déficit uniforme. Elle découvre que le code le mieux testé est celui qu'il était facile de tester, et que les zones les plus critiques sont les moins couvertes, parce qu'elles sont les plus difficiles à mettre en scène.
Côté client lourd, la mesure porte sur 231 fichiers applicatifs et atteint 92,43 %, soit 4 238 lignes couvertes sur 4 585. L'écart avec le backend n'a rien d'un jugement de valeur : une interface se prête mieux au test unitaire qu'une couche de services traversée par des appels externes.
Les scénarios de bout en bout
La couverture mesure les lignes exécutées, pas les parcours vérifiés. Une couverture élevée est compatible avec un système inutilisable : chaque fonction testée isolément, aucun enchaînement validé.
Nous avons donc constitué en parallèle une suite de scénarios de bout en bout : 287 tests répartis sur 31 fichiers et 16 modules (authentification, chat, RAG, workflows, sécurité, vision, voix, MCP, agents, intégrations), tous au vert à la mesure du 5 août.
Ces scénarios suivent des parcours complets : un utilisateur se connecte, crée un projet, importe des documents, pose une question, obtient une réponse sourcée. C'est le seul niveau qui détecte les défauts d'assemblage, ceux qui naissent de l'interaction entre des composants individuellement corrects.
Un point de méthode : ces 287 tests portent sur la mécanique, pas sur la qualité des réponses. Ils vérifient qu'une question sur un corpus renvoie une réponse structurée avec ses sources, pas que cette réponse soit pertinente. C'est une distinction que nous tenons, parce que la confondre reviendrait à annoncer une garantie que nous ne pouvons pas tenir.
Évaluer ce qui reste non déterministe
Restent les deux points qui échappent à tout cela : la récupération des passages et la génération.
Pour ceux-là, nous constituons un jeu d'évaluation : un ensemble de questions posées sur un corpus figé, dont nous connaissons la réponse attendue. Sa construction est le travail le plus ingrat et le plus rentable du projet, et elle demande un praticien du métier, pas un développeur. Sur un corpus juridique, seul un juriste sait qu'une question sur les délais de prescription doit remonter tel article et non tel autre.
Un jeu utile comporte trois familles de questions.
Les questions à réponse factuelle. La réponse est dans le corpus et l'évaluation contrôle que l'information exacte figure dans la réponse produite.
Les questions à sources attendues. Ce qu'on mesure ici n'est pas la formulation mais la récupération : les passages pertinents ont-ils été retrouvés ? C'est le test le plus précieux, parce qu'il sépare la recherche documentaire de la génération. Une réponse fausse construite sur les bons passages relève du modèle ; construite sur les mauvais passages, elle relève de l'indexation. Deux problèmes distincts, deux corrections distinctes.
Les questions sans réponse. Volontairement, une partie du jeu porte sur des sujets absents du corpus. Le comportement attendu n'est pas une réponse, c'est un aveu d'ignorance. Un système qui invente une réponse plausible sur un sujet absent est plus dangereux qu'un système qui se tait, parce que rien ne signale l'erreur à l'utilisateur. C'est la famille que les équipes oublient le plus souvent, et celle qui détecte le plus de problèmes réels.
Sur ces questions, plusieurs mesures cohabitent, et il faut résister à la tentation de les fondre en un score unique : taux de récupération des passages attendus, présence des éléments discriminants dans la réponse, taux d'abstention sur les questions sans réponse, vérification que les sources citées existent et correspondent au propos.
Aucune n'exige de juger la beauté d'une formulation. Toutes sont calculables automatiquement, donc utilisables dans une chaîne d'intégration continue.
Le seuil, et pourquoi il ne doit pas être à 100 %
Une fois ces mesures en place, il faut décider ce qui bloque une livraison.
Exiger 100 % est une erreur qui se paie vite. Le bruit inhérent au modèle fera échouer la chaîne sur des variations sans importance, l'équipe prendra l'habitude de relancer jusqu'à ce que ça passe, et le test perdra toute valeur de signal. Un test qu'on relance jusqu'au succès ne teste plus rien.
Nous raisonnons par écart à une référence. On établit une mesure de base sur la version en production, et on bloque si la nouvelle version dégrade significativement un indicateur. Une baisse de plusieurs points sur la récupération est un signal ; une variation de formulation n'en est pas un.
C'est aussi la logique de notre seuil de couverture à 80 %. Il n'est pas choisi parce que 80 % serait un bon chiffre dans l'absolu, mais parce qu'il est tenable dans la durée. Un seuil trop haut se contourne par des tests écrits pour la mesure plutôt que pour le défaut.
Deux précautions rendent l'approche exploitable. D'abord, exécuter plusieurs fois la même question et raisonner sur l'agrégat : une exécution unique mesure autant le hasard que la qualité. Ensuite, distinguer les questions critiques du reste. Sur un corpus réglementaire, certaines n'ont pas droit à l'erreur ; celles-là bloquent individuellement, sans moyenne qui viendrait diluer un échec.
Surveiller la production, pas seulement la recette
Un jeu d'évaluation tourne sur un corpus figé. La production, elle, travaille sur un corpus vivant qui grossit, se corrige et se contredit.
D'où les tests synthétiques : un ensemble de vérifications rejouées à intervalle régulier sur l'environnement réel, dont on suit les mesures dans le temps. Ils ne valident pas une livraison, ils détectent une dérive.
Sur NeuraScope, ce dispositif compte 23 tests répartis sur cinq couches, relancés en continu. Les couches sont volontairement séparées : infrastructure, points d'entrée HTTP, services applicatifs, couche IA, et parcours utilisateur réel.
Cette séparation n'est pas cosmétique, et les latences observées expliquent pourquoi :
| Couche | Latence p95 |
|---|---|
| Infrastructure (base de données, file d'attente, journaux) | 1 ms |
| Points d'entrée HTTP | 88 ms |
| Services applicatifs | 421 ms |
| Couche IA (modèle de langage, RAG) | 676 ms |
| Parcours utilisateur complet | 1 597 ms |
Un facteur 1 600 sépare la couche la plus basse du parcours complet. Quand le temps de réponse ressenti se dégrade, la question n'est jamais « est-ce lent ? » mais « où est-ce devenu lent ? ». Sans découpage par couche, un incident se traduit par une plainte utilisateur et une heure de recherche. Avec ce découpage, la couche fautive se lit directement.
Deux caractéristiques comptent davantage que le nombre de tests.
Les seuils sont explicites. Le test de latence du modèle de langage compare le temps de réponse à un plafond de 5 secondes. Une mesure sans seuil n'est pas un test : c'est une donnée que personne ne regarde. Un seuil transforme une courbe en alerte.
Certains tests mesurent la pertinence, pas seulement la disponibilité. Le test RAG complet ne vérifie pas qu'une réponse arrive : il contrôle le nombre de résultats retournés, combien sont jugés pertinents, et la distance de similarité obtenue. C'est la transposition en production du taux de récupération décrit plus haut. Un service qui répond vite, sans erreur, avec des passages hors sujet, est en panne du point de vue de l'utilisateur, et seul ce type de test le voit.
Enfin, l'historique compte plus que l'instantané. Une latence qui monte de 400 à 700 ms sur quinze jours ne déclenche aucune alerte et pose pourtant un vrai problème. Elle ne se voit que sur une série.
Ce que ces tests attrapent est invisible autrement.
La dérive du corpus. Un document important remplacé par une version obsolète, ou dupliqué. Sur ce point nous sommes précis avec nos clients : NeuraScope ne gère pas aujourd'hui les mises à jour de document, et réimporter un fichier crée un doublon. C'est une limite connue, et un test synthétique portant sur une question dont la réponse dépend d'un document fréquemment mis à jour la rend visible immédiatement.
La panne silencieuse d'un connecteur. Une source cesse d'alimenter la base. Aucune erreur ne remonte : le système continue de répondre, simplement sans les données récentes. Sans surveillance active, ce type de panne se découvre par un utilisateur mécontent, des semaines plus tard.
Le changement de comportement d'un modèle externe. Quand le modèle est fourni par un tiers, il évolue sans préavis. Les tests synthétiques transforment cette surprise en signal daté. Ce point pèse dans l'arbitrage entre modèle hébergé et modèle externe : un modèle auto-hébergé ne bouge que quand on décide de le faire bouger.
Le smoke test : trois minutes qui évitent l'appel client
À côté de tout cela existe une catégorie de vérifications bien plus simple, et dont l'absence coûte le plus cher : contrôler après chaque mise en production que les chemins essentiels répondent.
Un utilisateur peut-il se connecter ? Une question sur un corpus connu renvoie-t-elle une réponse ? Les pages principales s'affichent-elles ?
Ces vérifications ne mesurent aucune qualité. Elles détectent les pannes franches, celles qui rendent le service inutilisable, et qu'aucun test unitaire ne voit parce qu'elles naissent de l'assemblage : un fichier de configuration non régénéré, un lien symbolique cassé, un droit d'accès perdu au déploiement, une dépendance absente sur le serveur.
Notre conviction, formée sur nos propres incidents : la panne la plus fréquente en production n'est pas une régression de qualité subtile, c'est une page blanche. Elle se détecte en trois minutes de vérifications automatiques. Sans elles, elle se découvre par un appel client.
Ce que ces chiffres ne disent pas
Il faut être clair sur les limites, faute de quoi ces mesures donnent une fausse assurance.
81 % de couverture ne signifie pas 81 % de fiabilité. La couverture mesure les lignes exécutées pendant les tests, pas la pertinence des assertions. Du code peut être parcouru sans qu'aucun comportement soit réellement vérifié. Nous suivons la couverture parce qu'une zone à 20 % signale un angle mort, pas parce qu'une zone à 85 % serait garantie.
287 scénarios au vert ne valident pas la qualité des réponses. Ils valident la mécanique. La pertinence métier ne se mesure qu'avec les utilisateurs, sur leurs cas réels. C'est pourquoi nos jalons de déploiement prévoient une recette conduite par les référents métier, et non une validation technique.
Aucun jeu d'évaluation ne couvre les questions jamais imaginées. Il reflète ce que ses auteurs ont anticipé, et les usages réels débordent toujours ce cadre.
Rien de tout cela ne remplace l'humain sur les sujets à risque. Quand une erreur a des conséquences juridiques ou médicales, aucun taux ne justifie de retirer la relecture. La bonne question n'est pas « le système est-il fiable ? » mais « que se passe-t-il quand il se trompe ? ».
Enfin, une mesure interne n'est pas une preuve de valeur. Les chiffres de cet article décrivent l'état de notre code au 5 août 2026. Ils disent ce que nous vérifions, pas ce que la plateforme apporte à un métier donné.
Ce qu'il faut retenir
Tester une plateforme d'IA ne consiste pas à trouver la méthode qui rendrait le non-déterminisme déterministe. Cela consiste à réduire la surface non déterministe, à mesurer ce qui est objectivement mesurable, et à surveiller dans le temps ce qui refuse de se figer.
Quatre niveaux, dont aucun ne remplace les autres :
- des tests stricts sur tout ce qui est prévisible, c'est-à-dire la majeure partie du code ;
- des scénarios de bout en bout qui valident les parcours, pas seulement les fonctions ;
- un jeu d'évaluation construit avec des praticiens, mesuré sur la récupération plutôt que sur la formulation ;
- des tests synthétiques par couche rejoués en production, avec des seuils explicites et un historique, parce qu'une dérive progressive ne déclenche aucune alerte ;
- des smoke tests après chaque mise en production, parce que la panne la plus coûteuse est souvent la plus bête.
Une équipe qui investit uniquement dans l'évaluation sophistiquée découvrira ses pannes par ses utilisateurs. Une équipe qui se limite aux smoke tests livrera une régression de qualité sans le savoir.
Et si vous n'avez pas encore mesuré votre couverture, commencez par là. Ce n'est pas le chiffre global qui compte : c'est la découverte des zones à 20 % dont vous pensiez qu'elles étaient testées.