Une chaîne d'intégration continue quand la sortie n'est pas déterministe

Une chaîne d'intégration bloque une livraison quand un test échoue. Avec un modèle de langage, un test peut échouer sans qu'il y ait de régression. Voici comment construire une chaîne qui reste crédible.

Une chaîne d'intégration continue quand la sortie n'est pas déterministe

Une chaîne d'intégration continue repose sur une convention simple : si un test échoue, la livraison est bloquée. Cette convention n'a de valeur que si un échec signifie réellement qu'il y a un problème.

Introduisez un modèle de langage dans la chaîne, et cette garantie se fissure. Un test peut échouer parce que le modèle a formulé sa réponse autrement, sans qu'aucune régression n'ait eu lieu. Répétez l'expérience quelques fois, et l'équipe apprend à relancer plutôt qu'à investiguer.

Le jour où un vrai défaut passe, il passe avec le bruit.

Nous éditons NeuraScope et nous exploitons sa chaîne d'intégration au quotidien. Voici les principes qui la rendent utilisable, et les erreurs qui la rendent inutile.

Le seul défaut vraiment grave : le test instable

Avant de parler de méthode, il faut nommer le risque principal. Ce n'est pas de manquer un défaut, c'est de produire un signal auquel personne ne croit plus.

Un test instable, qui échoue une fois sur cinq sans raison, ne coûte pas seulement le temps des relances. Il modifie le comportement de l'équipe. On relance sans lire. On fusionne malgré le rouge parce que « c'est encore le test qui déconne ». On finit par désactiver.

À ce stade, la chaîne d'intégration continue existe encore, mais elle ne protège plus rien.

Toute décision de conception qui suit découle de cette contrainte : mieux vaut une chaîne qui détecte moins mais dont chaque alerte est crédible, qu'une chaîne exhaustive dont personne ne lit les résultats.

Trois étages, trois vitesses

Une chaîne utilisable se découpe selon le temps d'exécution et la stabilité du signal.

Premier étage : les tests déterministes. Ils s'exécutent à chaque envoi de code, en quelques minutes, et bloquent sans discussion. Ce sont eux qui couvrent l'essentiel du code applicatif. Sur NeuraScope, cela représente la majeure partie de 72 407 lignes analysées : découpage de documents, connecteurs, workflows, contrôles d'accès, validations. Un échec ici est toujours un vrai défaut.

Deuxième étage : les scénarios de bout en bout. Plus lents, ils valident les parcours complets plutôt que les fonctions isolées. Notre suite compte 287 tests sur 16 modules. Ils tournent sur les branches destinées à être fusionnées, pas à chaque sauvegarde, parce que leur durée ne le permet pas.

Troisième étage : l'évaluation de la qualité IA. C'est le seul étage non déterministe, et le seul qui demande une convention particulière. Il ne bloque pas sur une valeur absolue mais sur un écart à une référence.

Cette séparation est ce qui permet de garder un premier étage rapide et catégorique. Mélanger les trois donnerait une chaîne lente dont le verdict serait toujours discutable.

Bloquer sur un écart, pas sur une valeur

Pour l'étage IA, la règle qui fonctionne est comparative.

On établit une mesure de référence sur la version en production : taux de récupération des passages attendus, taux d'abstention sur les questions sans réponse, présence des éléments discriminants dans les réponses. Cette référence est enregistrée.

À chaque candidate à la livraison, on rejoue le même jeu d'évaluation et on compare. Le blocage se déclenche sur une dégradation nette, pas sur une variation.

Concrètement, cela demande trois décisions.

Choisir des mesures stables. Le taux de récupération est presque déterministe : pour une question donnée, les mêmes passages remontent, parce que la recherche vectorielle ne dépend pas du modèle de langage. C'est notre indicateur le plus fiable, et celui sur lequel nous plaçons les seuils les plus stricts. À l'inverse, toute mesure portant sur la formulation est bruitée par nature.

Exécuter plusieurs fois. Une question posée une seule fois mesure autant le hasard que la qualité. Trois à cinq exécutions, et on raisonne sur la moyenne. Cela multiplie le coût de l'étage, ce qui justifie de ne pas le lancer à chaque sauvegarde.

Séparer les questions critiques. Sur un corpus réglementaire ou médical, certaines questions n'ont pas droit à l'erreur. Celles-là bloquent individuellement, sans moyenne qui viendrait diluer un échec. C'est une décision métier, pas technique : elle se prend avec le client, pas dans un fichier de configuration.

Le coût, qui n'est pas anecdotique

Un point que les articles sur le sujet passent souvent sous silence : évaluer un système d'IA à chaque livraison a un coût réel.

Si le modèle est fourni par un tiers, chaque exécution du jeu d'évaluation est facturée. Multipliez par le nombre de questions, par le nombre d'exécutions, par le nombre de livraisons quotidiennes, et l'addition devient un sujet de discussion.

Trois leviers permettent de tenir.

Réduire le jeu pour l'intégration continue. Un sous-ensemble représentatif suffit à détecter une régression franche. Le jeu complet peut tourner une fois par jour, la nuit, plutôt qu'à chaque envoi.

Utiliser un modèle local pour la partie évaluation. Comparer les passages retrouvés à une liste attendue ne demande aucun modèle de langage. C'est du calcul d'ensemble. Seule la génération en demande un.

Ne pas évaluer ce qui n'a pas changé. Une modification de l'interface d'administration ne peut pas dégrader la récupération documentaire. Déclencher l'étage IA uniquement quand le code concerné est touché divise la facture sans réduire la protection.

C'est aussi un argument concret en faveur des modèles auto-hébergés : leur coût marginal par appel est nul, ce qui change la conception d'une chaîne d'évaluation.

Ce que la chaîne doit garder en mémoire

Une chaîne d'intégration qui ne conserve rien ne permet de répondre à aucune question intéressante.

Ce qui mérite d'être stocké à chaque exécution : les mesures obtenues, la version du code, et la version du modèle utilisé. Ce troisième élément est souvent oublié, et c'est celui qui explique les incidents les plus déroutants.

Quand un fournisseur met à jour son modèle, les réponses changent sans qu'une ligne de code ait bougé. Sans historique des versions de modèle, l'équipe cherche pendant des heures une régression dans son propre code. Avec cet historique, la corrélation saute aux yeux.

Cet historique sert aussi à distinguer une dégradation brutale d'une dérive lente. Une baisse de deux points par semaine ne déclenche jamais d'alerte et finit par représenter une perte considérable. Elle ne se voit que sur une série.

Ce qui se passe après la livraison

Une chaîne d'intégration valide une version avant sa mise en service. Elle ne dit rien de ce qui se passe ensuite.

Deux dispositifs complètent le tableau, et je les mentionne ici parce qu'ils sont souvent confondus avec la chaîne elle-même.

Le smoke test vérifie, juste après le déploiement, que les chemins essentiels répondent. Il attrape les pannes d'assemblage : configuration non régénérée, droits perdus, fichiers non reconstruits. Aucune de ces pannes n'existe dans l'environnement d'intégration, parce qu'elles naissent précisément du passage à la production.

La surveillance synthétique rejoue en continu un ensemble de vérifications sur l'environnement réel. Sur NeuraScope, ce dispositif compte 23 tests répartis sur cinq couches, avec des seuils explicites et des latences suivies séparément : 1 ms pour l'infrastructure, 88 ms pour les points d'entrée HTTP, 421 ms pour les services, 676 ms pour la couche IA, 1 597 ms pour le parcours utilisateur complet.

Ce découpage par couche est ce qui transforme une plainte vague en diagnostic. Quand le temps de réponse ressenti se dégrade, la question n'est jamais « est-ce lent ? » mais « où est-ce devenu lent ? ».

Les erreurs qui reviennent le plus souvent

Vouloir un score unique. Fondre récupération, exactitude et abstention en un seul chiffre rend le résultat incompréhensible : quand il baisse, personne ne sait pourquoi. Trois mesures suivies séparément valent mieux qu'un indice composite.

Faire juger la qualité par un autre modèle sans précaution. Utiliser un modèle de langage pour noter les réponses d'un autre est séduisant et fragile. Le juge a ses propres biais, sa propre variabilité, et son propre coût. Cette approche a sa place, mais jamais comme unique critère de blocage.

Confondre couverture et fiabilité. Une couverture de 81 % signifie que 81 % des lignes sont exécutées pendant les tests, pas qu'elles sont correctement vérifiées. Nous suivons cette mesure parce qu'une zone à 20 % signale un angle mort, pas parce qu'une zone à 85 % serait garantie.

Placer le seuil trop haut. Un seuil de couverture à 95 % se contourne par des tests écrits pour la mesure plutôt que pour le défaut. Nous nous tenons à 80 %, non parce que ce serait un bon chiffre dans l'absolu, mais parce qu'il est tenable dans la durée sans encourager la triche.

Ce qu'il faut retenir

Une chaîne d'intégration continue sur un système d'IA n'est pas une chaîne classique à laquelle on ajouterait des tests de qualité. C'est une chaîne à trois vitesses, dont seule la plus lente tolère le non-déterminisme.

Quatre principes la rendent utilisable :

  • séparer ce qui bloque sans discussion de ce qui se juge par comparaison ;
  • mesurer ce qui est stable, la récupération plutôt que la formulation ;
  • conserver l'historique, code et version de modèle compris ;
  • protéger la crédibilité du signal, quitte à détecter moins.

Une chaîne qu'on relance jusqu'à ce qu'elle passe ne teste plus rien. C'est le seul échec dont on ne se relève pas facilement, parce qu'il ne se voit sur aucun tableau de bord.

3 minutes de lecture
Partager :

Articles similaires

Découvrez d'autres actualités qui pourraient vous intéresser