Notes du cycle de release — Partie V
La page la plus citée qui n’est pas sortie le trimestre dernier est celle pour laquelle notre observer s’est déclenché tout seul à 2h14 du matin. La release candidate avait passé la porte, attendu pendant les quatre minutes requises à 5%, progressé à 25%, puis était restée là. Le moniteur de qualité par minute a vu trois lectures consécutives sous le seuil sur le slice du domaine juridique, a arrêté le rollout et a redirigé le routage vers la release précédente. Au moment où la notification de l’ingénieur d’astreinte s’est déclenchée — pour le reçu, pas pour une panne — le trafic de production était revenu sur la release connue comme saine depuis neuf minutes.
Personne n’avait besoin de faire quoi que ce soit. L’architecture du premier article de cette série décrit ce que sont les quatre étapes. Cet article porte sur ce qui s’exécute entre les approbations humaines — la couche d’automatisation sous l’architecture, la frontière où le pipeline fait la bonne chose tout seul, ou ne le fait pas.
L’affirmation centrale : la plupart des décisions de pipeline doivent être automatisées, mais pas toutes. La frontière compte. Le pipeline qui automatise tout finira par promouvoir une release qu’un humain aurait dû intercepter ; le pipeline qui n’automatise rien n’a aucun objet. Tracer la frontière correctement est ce dont il est question dans cet article.
Le spectre d’automatisation
Chaque décision de pipeline se situe quelque part sur un spectre allant de « se déclenche tout seul sans notification humaine » à « refuse d’avancer sans une approbation explicite et signée ». Voici où se situe chacune des actions structurantes du pipeline sur ce spectre dans notre pipeline en production.
Deux des marqueurs ci-dessus sont rouges plutôt que colorés selon leur zone. Ce sont les décisions asymétriques — les deux endroits où le pipeline prend une position forte sur qui peut décider quoi. Le déclencheur d’auto-rollback se déclenche sans demander ; vous ne pouvez pas le désactiver, parce que tout l’intérêt de l’avoir est qu’il fonctionne à 2h14 du matin. L’override en cas d’échec de porte refuse d’avancer sans une justification écrite ; vous ne pouvez pas non plus le désactiver, parce que tout l’intérêt de l’avoir est que le vous-du-futur a besoin de lire la raison. La plupart du reste du pipeline est configurable ; ces deux-là ne le sont pas.
Comment l’auto-rollback se déclenche réellement
La question la plus posée sur l’auto-rollback est « qu’est-ce qui l’empêche de se déclencher pour la mauvaise raison ? ». La réponse honnête est : rien à lui seul. La protection vient de la façon dont le déclencheur est câblé.
L’étape Observe exécute une boucle de scoring par minute. Chaque minute elle :
- Échantillonne un petit ensemble de traces récentes de production de la release active.
- Rejoue chaque trace à travers le modèle actif (pas la candidate — nous scorons ce qui sert réellement).
- Score chaque rejeu à l’aide du même juge calibré ancré sur l’humain qui a piloté Gate-2[1].
- Calcule un score unique de qualité de sortie sur l’échantillon. Écrit dans
CanaryHealthSample.
Le rollback se déclenche lorsque trois échantillons consécutifs par minute tombent sous le seuil de rollback (par défaut : 0,85 du seuil de la porte — donc 0,55 si la porte était à 0,65). Pas une seule minute mauvaise ; trois. Le verrou de trois minutes est le filtre anti-bruit — une lecture anormale isolée ne déclenche rien, mais une régression soutenue oui.
Lorsque le verrou se rompt, le worker de rollback exécute :
# En pratique — le pipeline exécute ceci tout seul. Aucun ack humain.
POST /api/v1/releases/<previous_release_sha>/activate
# réponse en <1s ; drain en vol en ~12s sur un service ~100 réplicasUn reçu se déclenche. L’ingénieur d’astreinte voit une notification Slack pour le reçu, pas pour une panne. Il ouvre le reçu ; il voit les trois lectures sous le seuil, le temps écoulé et les hachages vindex_sha256_before/after[2]. Douze secondes correspondent au temps de drain en vol ; le swap lui-même est sous la seconde. Quand l’ingénieur est suffisamment réveillé pour demander « ai-je besoin de faire quelque chose ? », la réponse est « non, mais vous devriez quand même regarder pourquoi la porte a laissé passer ceci ».
Le reçu réel d’un auto-rollback
Voici à quoi ressemble le reçu en production. Même format chaîné par hachage que documenté sur la page de conformité, avec les champs supplémentaires spécifiques à un événement d’auto-rollback :
{
"kind": "auto_rollback",
"release_id": "rel_a01c66",
"previous_release_id": "rel_8f72b1",
"trigger_at": "2026-05-29T02:14:23Z",
"completed_at": "2026-05-29T02:14:35Z",
"elapsed_seconds": 12,
"trigger_reason": "observer_quality_threshold_breach",
"observer_readings": [
{ "minute_at": "2026-05-29T02:11:00Z", "quality_score": 0.523, "below_threshold": true, "slice": "legal-IP-licensing" },
{ "minute_at": "2026-05-29T02:12:00Z", "quality_score": 0.508, "below_threshold": true, "slice": "legal-IP-licensing" },
{ "minute_at": "2026-05-29T02:13:00Z", "quality_score": 0.491, "below_threshold": true, "slice": "legal-IP-licensing" }
],
"rollback_threshold": 0.55,
"active_manifest_sha256_before": "9abaeaf6c91f8b...",
"active_manifest_sha256_after": "8f72b1de4a93c5...",
"audit_chain_signature": "sha256(...)",
"notified_users": ["oncall@customer.example"],
"notification_sent_at": "2026-05-29T02:14:36Z"
}Le reçu lui-même est le premier point de contact de l’astreinte. Le lire répond aux questions qu’un ingénieur à moitié réveillé poserait réellement : qu’est-ce qui l’a déclenché, quel slice a échoué, de combien, combien de temps le swap a pris, ce qui tourne maintenant. La prochaine action évidente depuis là est généralement « allez voir pourquoi la porte a laissé passer ça en premier lieu » — et le reçu de la release défaillante contient déjà le tableau Spearman par slice.
Ce que le pipeline ne fait PAS tout seul
Le corollaire de « l’auto-rollback se déclenche sans demander » est que certaines autres choses ne le peuvent activement pas. Trois refus explicites.
Il ne promeut pas une release qui a échoué à la porte sans un override signé. Un échec de porte marque la release gate_fail ; le endpoint /activate refuse d’accepter le SHA du manifeste ; aucune incantation en ligne de commande ne contourne cela. La seule voie d’avancement est un force-override avec forceGateOverride: true ET overrideReason: "<texte libre>". Le champ de raison est obligatoire, en texte libre, et va dans le journal d’audit aux côtés de l’ID utilisateur. Nous avons conçu cela pour que le vous-du-futur puisse lire pourquoi le vous-actuel a décidé que la régression du slice était acceptable. Trois personnes ont utilisé la voie d’override en production. Leurs justifications sont toujours dans le journal d’audit.
Il ne passe pas de canary à 100% si un quelconque moniteur se dégrade. Si la latence p95, le taux de 5xx OU le score de qualité de sortie est en dehors de sa bande à la fin d’un palier de checkpoint, le pipeline s’arrête à ce checkpoint et alerte. Il n’avance pas en s’excusant plus tard.
Il ne passe pas en auto-canary une release cold-start. Une release sans historique de trafic de production — un fine-tune frais sur un dataset tout neuf, disons — n’a rien à quoi comparer sa qualité de sortie. Le pipeline refuse de démarrer un canary sur une release cold-start. Nous exigeons d’abord un déploiement shadow de 24 heures, qui observe la candidate face aux traces de production réelles mais ne sert aucune de ses réponses. Après 24 heures, nous avons une baseline de qualité ; le canary peut alors avancer. Plus lent ; honnête ; non configurable.
À quelle vitesse se fait la récupération, de bout en bout ?
Le temps de récupération que nous publions est de 12 secondes. C’est le drain en vol sur un service à ~100 réplicas. Le swap de manifeste lui-même est sous la seconde. Pour être utile à un lecteur, les 12 secondes doivent être décomposées :
- 0–60 secondes avant le rollback : les trois lectures consécutives sous le seuil arrivent. La première lecture sous le seuil démarre le minuteur de verrou. Chaque minute suivante étend le verrou si la qualité est toujours sous le seuil.
- t = 0 : la troisième lecture sous le seuil s’écrit dans
CanaryHealthSample. Le worker de rollback observe le troisième strike et dépêche/activate previous_release. - t < 1 seconde : le pointeur de release active de la couche de routage (dans Redis) bascule. Les nouvelles requêtes commencent à frapper la release précédente.
- t = 1 à ~12 secondes : la release candidate continue de servir toutes les requêtes qui étaient en vol au moment du swap. Drain en vol. Certaines réponses en streaming prennent 8 à 10 secondes pour se terminer naturellement, donc la traîne de nettoyage est d’environ 12s sur un service typique.
- t ≈ 13 secondes : le reçu du journal d’audit est écrit et signé. La notification se déclenche.
Comparé aux post-mortems publics que nous citons en référence : la panne de Cloudflare de juin 2022[3] a pris 44 minutes entre « nous savons ce qu’il faut annuler » et « l’annulation est terminée » — et c’était au niveau infrastructure. La panne d’Atlassian d’avril 2022[4] a pris 12 heures par site parce que l’état était réparti sur plusieurs systèmes. Le seuil DORA[5] pour la récupération après déploiement échoué chez les « elite performers » est documenté à moins d’une heure. Douze secondes, ce n’est pas un ordre de grandeur de mieux que le seuil élite — c’est trois ordres de grandeur de mieux. La décision architecturale qui rend cela possible est le manifeste de release groupé de l’étape 1. Sans le manifeste, vous n’avez pas un seul objet vers lequel re-pointer le routage.
Exercices de rollback — la pratique peu glamour que personne n’exécute
Voici la partie que la plupart des équipes sautent : le seul signal fiable que votre chemin de rollback fonctionne, c’est d’avoir exécuté un exercice délibéré et planifié et de l’avoir confirmé. Chaque trimestre, nous en exécutons un. L’exercice se déroule ainsi :
- Choisir une heure aléatoirement planifiée, en semaine et en heures ouvrées. Prévenir l’équipe que cela arrive, mais pas l’heure précise.
- Injecter une régression de qualité synthétique sur le slice canary. (Nous avons un drapeau de mode test qui permet au modèle candidat de répondre à un en-tête magique par « je refuse de répondre » — garanti pour faire échouer le juge calibré.)
- Pousser la release de test à travers la porte (elle passe — nous testons le rollback, pas la porte). Démarrer un canary.
- L’observer remarque trois lectures sous le seuil. L’auto-rollback se déclenche.
- Attendre la réaction de l’ingénieur d’astreinte. Chronométrer combien de temps il prend. Noter s’il fait suffisamment confiance au reçu pour ne pas alerter en retour comme s’il s’agissait d’une alarme.
- Vérifier que le journal d’audit montre le drapeau de mode test dans le reçu de rollback, afin que les audits futurs puissent distinguer un exercice d’un incident réel.
Le premier exercice que nous avons exécuté a pris 19 secondes de bout en bout (12s de swap + un délai de stabilisation de 7s que nous avons dû corriger). L’exercice le plus récent — T1 2026 — a pris 12 secondes. L’exercice n’a jamais le droit d’être sauté. Chaque trimestre ; chaque cluster client.
La plupart des équipes n’ont jamais exécuté un exercice de rollback délibéré. La première fois que leur chemin de rollback s’exécute, c’est lors d’un incident réel, sous pression, avec plusieurs personnes dans l’appel. L’exercice est ce qui fait du chiffre de 12 secondes un chiffre réel plutôt qu’aspirationnel.
Ce que cela ne résout pas
Trois limitations honnêtes :
L’auto-rollback peut faire du ping-pong. Si à la fois la candidate ET la release précédente sont mauvaises — disons, la release précédente avait aussi une régression de slice à développement lent que personne n’avait attrapée — le pipeline peut faire un rollback, puis la release précédente échoue aussi à son observer post-rollback, et il n’y a pas de troisième release vers laquelle faire un rollback. Le pipeline arrête le trafic et envoie vers une page de maintenance plutôt que de s’agiter. Le correctif est de garder plus d’une release antérieure saine indexée dans la chaîne de manifestes pour que la cible de rollback soit configurable.
L’observer ajoute un coût d’inférence. Rejouer des traces de production à travers le modèle actif sur un échantillon de 5% ajoute environ 5% à la dépense d’inférence. Nous pensons que c’est le bon compromis. Certains clients trouvent cela trop coûteux pour des charges de travail à faible marge et veulent baisser le taux d’échantillonnage. Le réglage existe.
Un mauvais juge est pire que pas de juge. Si le juge calibré qui pilote l’observer est lui-même mal calibré — décalé par rapport à l’ancrage humain, ou entraîné sur un corpus obsolète — l’observer peut déclencher un auto-rollback pour la mauvaise raison. La cadence de recalibrage compte. L’article Calibrating-the-Judge[6] documente la procédure ; l’exigence opérationnelle est que vous l’exécutiez effectivement.
FAQ
Pourquoi le déclencheur de rollback est-il de trois minutes consécutives plutôt qu’une seule ?
Parce que les scores de qualité LLM ont un plancher de bruit — une lecture anormale isolée peut venir d’un aléa d’échantillonnage (l’échantillon de 5% de traces est tombé sur un slice difficile), pas d’une régression réelle. Le verrou de trois minutes est le filtre anti-bruit le moins cher qui maintient quand même le temps de réaction total sous une minute et demie. Nous avons réglé dans les deux sens ; trois est le point optimal pour la forme de trafic typique de nos clients. Le palier est configurable par release si la forme de votre trafic est différente.
L’auto-rollback devrait-il être configurable sur « off » ?
Dans notre pipeline livré, non. Tout l’intérêt d’avoir un mécanisme de sécurité automatisé est qu’il fonctionne à 2h14 du matin quand personne ne regarde. Un auto-rollback configurable sur off est un post-it qui dit « nous avions un filet de sécurité ». L’argument pour le rendre configurable est que certaines charges de travail sont à enjeu trop faible pour justifier le moindre rollback de faux positif. Nous pensons que cet argument mène au mauvais endroit — si votre charge de travail est à enjeu trop faible pour l’auto-rollback, vous n’avez pas non plus besoin d’un pipeline de release.
Comment gérez-vous le cas où la release précédente était aussi mauvaise ?
La cible de rollback est previous_release par défaut, mais la chaîne de manifestes stocke plus d’historique que N-1. Les opérateurs peuvent re-cibler un rollback vers n’importe quel SHA de manifeste historiquement sain — /api/v1/releases/<historically_good_sha>/activate — ce qui est la voie d’intervention manuelle quand le rollback automatique N-1 tombe sur une mauvaise release antérieure. La soupape d’échappement est là. C’est rare.
Quelle est la bonne métrique à optimiser — MTTR ou MTBF ?
MTTR — Mean Time To Recovery — de loin, du moins pour les systèmes LLM. Le MTBF (Mean Time Between Failures) suppose une notion déterministe de « panne » que les charges de travail LLM n’ont pas. La qualité de sortie dérive en continu ; la « panne » est un seuil qu’on choisit. Optimiser pour une récupération rapide est robuste à l’endroit où vous tracez le seuil ; optimiser pour ne jamais échouer est fragile et faux. Le seuil élite de DORA[5] est lui-même formulé en termes de MTTR, ce qui est le bon cadrage.
Exécutez-vous réellement des exercices de rollback ?
Oui — trimestriellement, planifiés, avec un drapeau de mode test dans le reçu pour que l’exercice puisse être distingué d’un incident réel dans le journal d’audit. Le premier exercice que nous avons exécuté a exposé un délai de stabilisation de 7 secondes dont nous n’avions pas conscience. L’exercice est le seul moyen de savoir que le chemin fonctionne effectivement ; lire le runbook ne suffit pas. La plupart des équipes n’en ont pas exécuté un, ce qui explique pourquoi les chiffres de MTTR de la plupart des équipes sont aspirationnels plutôt que mesurés.
Références
- Calibration LLM-as-judge. Zheng et al., Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena (NeurIPS 2023). L'ancrage qui justifie qu'un juge calibré est nécessaire et que l'accord par slice compte plus que l'accord agrégé. La boucle de scoring par minute de l'observer en dépend.
- Attestation des poids vindex. Documenté sur la page de conformité Divinci et parcouru dans l'article sur les domaines régulés. Les champs `vindex_sha256_before/after` du reçu d'auto-rollback sont l'ancrage cryptographique qu'un auditeur peut vérifier sans faire confiance à nos logs.
- Panne Cloudflare de juin 2022. Cloudflare outage on June 21, 2022. « 06:58 : Cause racine trouvée et comprise. Le travail commence pour annuler le changement problématique… 07:42 : La dernière des annulations est terminée. » Quarante-quatre minutes pour annuler au niveau infrastructure, en partie parce que les ingénieurs ont marché sur les annulations les uns des autres. Ancrage pour l'affirmation « un swap piloté par manifeste ne peut pas avoir ce mode d'échec ».
- Panne Atlassian d'avril 2022. Post-Incident Review: April 2022 Outage. 12 heures par site pour restaurer, 14 jours au total pour 883 sites, parce que l'état était réparti sur des systèmes versionnés indépendamment. Ancrage pour l'affirmation « le manifeste de release groupé est ce qui rend possible les secondes-pas-les-heures ».
- Seuil DORA de récupération après déploiement échoué. DORA — Software delivery performance metrics. Le seuil « failed deployment recovery time » pour les elite performers est documenté à moins d'une heure. Le chiffre du pipeline de 12 secondes est trois ordres de grandeur en dessous du seuil élite, ce qui est la bonne manière de lire la comparaison.
- Calibrer le juge IA. Notre article compagnon Calibrating the AI Judge. La procédure pour maintenir le juge ancré sur l'humain en calibration au fil du temps. L'affirmation opérationnelle de cet article — que l'auto-rollback ne fonctionne aussi bien que le juge qui le pilote — ne tient que si le juge est en fait recalibré périodiquement.
- Interne — référence pipeline Divinci. L'architecture sous laquelle se situe cette couche d'automatisation : l'article sur le pipeline en quatre étapes. L'ensemble de la surface API est documenté à la référence API ; la section sur la gestion des releases est celle dont parle cet article.
Prochain dans cette série : CI Testing for Custom Language Models in 2026. Cet article porte sur la couche opérationnelle entre les approbations humaines. Le suivant porte sur la couche avant que le pipeline ne démarre — la CI pré-merge : que faut-il évaluer au moment du PR, quelles régressions vous attrapez réellement avant que la porte ne les voie, et lesquelles vous ratez.
Prêt à Construire Votre Solution IA Personnalisée ?
Découvrez comment Divinci AI peut vous aider à implémenter des systèmes RAG, automatiser l'assurance qualité et rationaliser votre processus de développement IA.
Commencer Aujourd'hui