Introduction
Les montées de version sont un bon candidat pour un agent IA. Elles reviennent souvent, elles demandent de lire des changelogs, de repérer les ruptures de compatibilité et de toucher beaucoup de fichiers. Elles sont aussi risquées : une dépendance mal montée casse un build, ou pire, un comportement en production.
La tentation est de brancher un agent autonome qui ouvre des merge requests tout seul. En mission dans le secteur public, sur une infrastructure cloud souveraine hébergée en France, j’ai pris l’autre chemin : un agent intégré à GitLab CI/CD, qui analyse et propose un plan, et rien ne se poursuit sans la validation d’un humain. Cet article décrit ce pattern, les choix qui le rendent fiable, et ce qu’il faut encore construire pour le passer à l’échelle.
L'idée centrale
L'agent fait le travail de lecture et d'analyse. L'humain garde la décision. La CI garantit que cet ordre est respecté.
- L’agent reste dans le processus de l’équipe : CI, merge request, revue.
- La validation humaine est un point de blocage réel, pas une case à cocher.
- Chaque run laisse des preuves exploitables par quelqu’un d’autre.
Ce qui est en place, ce qui est cible
Beaucoup d’articles sur les agents mélangent ce qui tourne et ce qui est imaginé. Je sépare les deux.
En place
- Un agent de montée de version exécuté dans GitLab CI/CD.
- Un modèle et une exécution sur une infrastructure cloud souveraine, en France.
- Une analyse par LLM qui produit un plan.
- Une validation humaine après l’analyse, avant toute suite.
- Des présentations de l’approche à plusieurs équipes.
- Une collecte de métriques engagée sur les premiers cas.
Architecture cible
- Exécution du plan dans un environnement isolé.
- Boucle de correction bornée par un budget.
- Merge request idempotente avec rapport de vérification.
- Approbation liée à une version du plan et à un commit.
- Suite d’evals reproductible et observabilité complète.
Je ne publie pas de gain chiffré pour l’instant : l’échantillon n’est pas encore interprétable. La section Mesurer avant de conclure explique pourquoi c’est un choix, pas un oubli.
Ce pattern prolonge deux migrations menées avec des workflows IA sur la même mission (React 16 → 18 sur 352 composants, puis un design system vers le DSFR). Elles sont détaillées dans les retours terrain. La leçon commune : l’agent n’est fiable que si les règles, les pièges connus et les contrôles sont écrits avant de lui déléguer le travail.
Workflow ou agent ?
Anthropic distingue les workflows, où le code orchestre le LLM et les outils selon des chemins prédéfinis, des agents, où le LLM dirige lui-même son processus et ses outils (Building effective agents). La distinction compte, parce qu’elle fixe où se trouve le contrôle.
Pour une montée de version en entreprise, un workflow explicite avec des étapes agentiques est le bon point de départ. L’analyse du dépôt peut s’adapter, mais les transitions sensibles (appliquer, ouvrir une merge request, fusionner) restent décidées par le programme et par des humains.
- Prévisible
- Peu coûteux
- Facile à auditer
- Aucune adaptation aux ruptures de compatibilité
- •Montées mineures sans rupture
- Transitions contrôlées
- Analyse adaptée au dépôt
- Validation humaine naturelle
- Demande de concevoir le plan et ses contrôles
- •Montées majeures
- •Migrations de bibliothèques
- Gère des cas imprévus
- Plus difficile à évaluer et à sécuriser
- •Diagnostic d’échecs de build complexes
Script déterministe | Workflow + étapes LLM | Agent borné |
|---|---|---|
Règles stables, transformation répétable (ex. Renovate seul). | Étapes connues, analyse variable confiée au modèle. | Recherche adaptative, outils multiples, périmètre et budget fixés. |
Avantages
| Avantages
| Avantages
|
Inconvenients
| Inconvenients
| Inconvenients
|
Cas d'usage
| Cas d'usage
| Cas d'usage
|
L’architecture d’un run
Un run suit une séquence courte. Les étapes marquées « en place » tournent déjà ; les autres forment l’architecture cible.
- 1Ticket et commit de référencecible
- 2Éligibilité et niveau de risquecible
- 3Analyse du dépôt et des sources par le LLMen place
- 4Plan structuré avec preuvesen place
- 5Validation humaine : approuver, corriger ou refuseren place
- 6Exécution dans un environnement isolécible
- 7Tests et contrôles qualité, boucle de correction bornéecible
- 8Merge request avec rapport de vérificationcible
- 9Revue et décision de merge par une personne habilitéecible
Chaque run conserve un identifiant, le ticket, le dépôt et le commit de départ, les versions du workflow et des prompts, le modèle utilisé, les outils appelés, le plan, les validations, les contrôles exécutés, les coûts et l’état final. Sans ce contrat minimal, personne d’autre que l’auteur ne peut diagnostiquer un run raté.
Le pipeline GitLab
Trois jobs suffisent à matérialiser l’ordre analyse → validation → exécution. L’exemple ci-dessous est simplifié et générique : ce n’est pas la configuration du projet.
1# Exemple simplifié : "agent" représente votre CLI d'orchestration.2stages:3 - analyse4 - validation5 - execution6
7analyse-upgrade:8 stage: analyse9 image: $AGENT_IMAGE10 rules:11 - if: $CI_PIPELINE_SOURCE == "web" && $UPGRADE_TARGET12 script:13 - agent analyse --target "$UPGRADE_TARGET" --base-commit "$CI_COMMIT_SHA" --out plan.json14 - agent render-plan plan.json > plan.md15 artifacts:16 paths: [plan.json, plan.md]17 expire_in: 7 days18
19approve-plan:20 stage: validation21 rules:22 - if: $CI_PIPELINE_SOURCE == "web" && $UPGRADE_TARGET23 when: manual24 allow_failure: false # bloque le pipeline tant que personne n'a validé25 environment:26 name: agent-approval # environnement protégé : qui peut valider27 script:28 - agent verify-plan plan.json --base-commit "$CI_COMMIT_SHA"29
30apply-upgrade:31 stage: execution32 image: $AGENT_IMAGE33 needs: [analyse-upgrade, approve-plan]34 resource_group: agent-upgrade # un seul run à la fois pour ce projet35 rules:36 - if: $CI_PIPELINE_SOURCE == "web" && $UPGRADE_TARGET37 script:38 - agent apply plan.json --branch "agent/upgrade-$CI_PIPELINE_ID"39 - npm ci && npm test40 - agent open-mr --branch "agent/upgrade-$CI_PIPELINE_ID" --report report.mdTrois détails font la différence :
- Le job manuel doit bloquer. Par défaut, un job
when: manualdéfini hors derulesaallow_failure: true: le pipeline peut passer au vert sans que personne n’ait validé. Dansrules, la valeur par défaut devientfalseet le pipeline reste bloqué (when, allow_failure). Je l’écris quand même explicitement. - Qui peut valider compte autant que la validation. Rattacher le job à un environnement protégé limite son déclenchement aux personnes autorisées (fonctionnalité des éditions Premium et Ultimate de GitLab ; sinon, s’appuyer sur les branches protégées et les droits du projet).
- Un seul run à la fois. resource_group empêche deux exécutions concurrentes de modifier le même projet.
Un plan structuré et vérifiable
Le plan n’est pas un paragraphe de texte libre. C’est un objet validé par un schéma, que le programme peut vérifier et qu’un humain peut lire vite. Il contient les sources utilisées, les ruptures détectées avec les fichiers impactés, ce qui est hors périmètre, les incertitudes et les tests prévus.
1import { z } from 'zod';2
3export const UpgradePlan = z.object({4 planVersion: z.number().int().positive(),5 baseCommit: z.string().regex(/^[0-9a-f]{40}$/),6 target: z.object({7 dependency: z.string(),8 from: z.string(),9 to: z.string(),10 }),11 sources: z.array(z.object({ url: z.string().url(), note: z.string() })).min(1),12 breakingChanges: z.array(13 z.object({14 description: z.string(),15 impactedFiles: z.array(z.string()),16 source: z.string().url(),17 })18 ),19 plannedChanges: z.array(z.string()).min(1),20 outOfScope: z.array(z.string()),21 uncertainties: z.array(z.string()),22 tests: z.object({23 commands: z.array(z.string()).min(1),24 knownGaps: z.array(z.string()),25 }),26 rollback: z.string(),27});28
29export type UpgradePlan = z.infer<typeof UpgradePlan>;Un schéma valide ne garantit pas une analyse juste. Il garantit seulement que l’analyse est complète dans sa forme et vérifiable. La justesse, c’est le rôle de la validation humaine et des evals.
Concevoir la validation humaine
Une validation humaine mal conçue devient une approbation machinale. L’écran ou le message de validation doit réduire le coût de compréhension. Il présente :
- l’objectif et la version cible ;
- les sources utilisées et les points incertains ;
- les changements prévus et ce qui est hors périmètre ;
- les risques, la compatibilité et le retour arrière possible ;
- les tests prévus et les limites de leur couverture ;
- trois actions distinctes : approuver, demander une correction, refuser.
L’accord doit être lié à une version du plan et à l’état du dépôt. Si l’un des deux change, l’approbation ne vaut plus :
1import type { UpgradePlan } from './upgrade-plan';2
3interface Approval {4 planVersion: number;5 baseCommit: string;6 approvedBy: string;7 decision: 'approve' | 'request-changes' | 'reject';8 expiresAt: string;9}10
11type ApplyCheck = { ok: true } | { ok: false; reason: string };12
13export function canApply(14 plan: UpgradePlan,15 approval: Approval | null,16 headCommit: string,17 now = new Date()18): ApplyCheck {19 if (!approval || approval.decision !== 'approve') {20 return { ok: false, reason: 'Aucune approbation' };21 }22 if (approval.planVersion !== plan.planVersion) {23 return { ok: false, reason: 'Le plan a changé depuis l’approbation' };24 }25 if (approval.baseCommit !== plan.baseCommit || plan.baseCommit !== headCommit) {26 return { ok: false, reason: 'Le dépôt a bougé : nouvelle analyse requise' };27 }28 if (new Date(approval.expiresAt) < now) {29 return { ok: false, reason: 'Approbation expirée' };30 }31 return { ok: true };32}La matrice d’autonomie
Toutes les actions ne méritent pas le même contrôle. Gartner prévient d’ailleurs qu’appliquer une gouvernance uniforme à tous les agents, quel que soit leur niveau d’autonomie, mène à l’échec (Gartner, mai 2026). Voici une matrice de départ, volontairement conservatrice :
| Action | Politique initiale | Condition |
|---|---|---|
| Lire le dépôt | Automatique | Dépôt et identité autorisés |
| Consulter des sources externes | Automatique sous politique | Sources approuvées, contenu traité comme non fiable |
| Produire un plan | Automatique | Hypothèses et preuves visibles |
| Appliquer le plan dans une branche isolée | Après approbation du plan | Périmètre inchangé, droits limités |
| Exécuter les tests | Automatique en isolation | Scripts du dépôt considérés comme du code exécutable |
| Créer une merge request | Selon la politique de l’équipe | Rapport et contrôles joints |
| Fusionner | Décision d’une personne habilitée | Règles de revue satisfaites |
| Déployer en production | Autorisation dédiée | Politique de livraison et retour arrière possible |
Les incidents à prévoir
Un agent en CI rencontre les mêmes problèmes que n’importe quel système distribué : relances, concurrence, états qui changent pendant l’attente. Six cas à traiter dès le départ :
Job relancé
Ne pas créer une deuxième merge request ni rejouer une action déjà faite. Chaque effet doit être idempotent.
Commit de base modifié
Le plan a été approuvé sur un état du dépôt qui n’existe plus : invalider et relancer l’analyse.
Modèle indisponible
Arrêt explicite, reprise contrôlée ou traitement manuel. Jamais de résultat partiel présenté comme complet.
Validation qui expire
Le silence n’est pas un accord. Sans décision dans le délai, le run s’arrête et le dit.
Test instable préexistant
Distinguer la dette déjà présente d’une régression introduite, en exécutant les tests avant et après.
Plan impossible
Demander une décision humaine au lieu d’élargir seul le périmètre ou les droits.
Le premier est le plus fréquent. Un job relancé ne doit pas ouvrir une deuxième merge request : on cherche d’abord celle qui existe pour la même branche.
1// Réutilise la merge request existante si le job est relancé.2export async function ensureMergeRequest(projectId: string, branch: string, title: string) {3 const baseUrl = `${process.env.CI_API_V4_URL}/projects/${projectId}/merge_requests`;4 const headers = { 'PRIVATE-TOKEN': process.env.AGENT_TOKEN ?? '' };5
6 const search = await fetch(7 `${baseUrl}?source_branch=${encodeURIComponent(branch)}&state=opened`,8 { headers }9 );10 if (!search.ok) throw new Error(`Recherche de MR impossible : ${search.status}`);11
12 const existing: Array<{ iid: number; web_url: string }> = await search.json();13 if (existing.length > 0) return existing[0];14
15 const created = await fetch(baseUrl, {16 method: 'POST',17 headers: { ...headers, 'Content-Type': 'application/json' },18 body: JSON.stringify({19 source_branch: branch,20 target_branch: process.env.CI_DEFAULT_BRANCH,21 title,22 remove_source_branch: true,23 }),24 });25 if (!created.ok) throw new Error(`Création de MR impossible : ${created.status}`);26 return created.json();27}Sécurité et souveraineté
Pour analyser une montée de version, l’agent lit des changelogs, des notes de version, des issues et de la documentation externe. Tout ce contenu peut contenir des instructions cachées : c’est l’injection de prompt indirecte décrite par l’OWASP (LLM01:2025). La réponse n’est pas un meilleur prompt, c’est une architecture qui limite les dégâts :
- un token dédié à l’agent, avec le minimum de droits, qui ne peut pas fusionner sur une branche protégée ;
- aucun secret de production dans les jobs d’analyse et d’exécution ;
- une exécution isolée : les scripts du dépôt et des dépendances sont du code exécutable ;
- des accès réseau limités aux sources nécessaires ;
- une protection de
.gitlab-ci.ymlet des tests : l’agent ne doit pas pouvoir affaiblir les contrôles pour réussir.
Reste la question de l’endroit où tournent le modèle et les données. Dans le secteur public comme dans beaucoup d’entreprises françaises, le code source ne doit pas quitter un environnement maîtrisé. L’agent s’appuie donc sur un modèle et une exécution hébergés sur une infrastructure cloud souveraine, en France. C’est un choix de départ, pas une contrainte ajoutée à la fin : il détermine les modèles disponibles, leur fenêtre de contexte et leurs coûts, donc la conception du workflow.
L’État a fait le même choix pour ses propres agents : son assistant d’IA générative repose sur un modèle Mistral AI hébergé en SecNumCloud (DINUM, juin 2026). Bonne nouvelle : tout ce qui précède (plan structuré, validation humaine, idempotence, evals) ne dépend pas du fournisseur du modèle.
Mesurer avant de conclure
Les gains de productivité de l’IA dépendent fortement du contexte. L’étude de METR publiée début 2025 observait un ralentissement chez des développeurs expérimentés travaillant sur des projets qu’ils connaissaient (METR, 2025). En février 2026, METR explique que ses nouveaux résultats souffrent de biais de sélection et ne permettent pas une estimation fiable des gains actuels (METR, 2026). Conclusion pratique : il faut mesurer localement, sur des tâches comparables.
| Indicateur | Définition | Attention |
|---|---|---|
| Éligibilité | Tâches éligibles / tâches reçues | Afficher les exclusions pour ne pas embellir le succès |
| Réussite finale | Tâches acceptées / tâches éligibles tentées | Inclure échecs et abandons |
| Temps humain total | Cadrage + validation + revue + corrections | Mesurer le travail déplacé par l’agent, pas seulement la génération |
| Corrections humaines | Part des tâches reprises et temps de reprise | Le nombre de lignes modifiées est un mauvais indicateur isolé |
| Coût par tâche acceptée | Coût de toutes les tentatives / tâches acceptées | Inclure les échecs et l’exécution |
| Qualité après livraison | Régressions sur une fenêtre définie | Taille d’échantillon et attribution |
Les métriques de production expliquent les runs réels. Les evals, elles, comparent des variantes sur des cas définis. Anthropic recommande de démarrer avec 20 à 50 tâches tirées d’échecs réels, et de combiner des contrôles par le code, par un modèle et par des humains (Demystifying evals for AI agents). Pour une montée de version, un cas vérifie par exemple que l’agent identifie les ruptures connues, ne modifie rien hors périmètre, s’arrête à la frontière autorisée et résiste à une instruction malveillante glissée dans un changelog.
Checklist production
Le modèle et l’exécution restent sur une infrastructure souveraine : le code ne quitte pas l’environnement maîtrisé.
Le job de validation bloque réellement le pipeline (when: manual dans rules, allow_failure: false).
Seules les personnes habilitées peuvent déclencher la validation.
L’approbation est liée à une version du plan et à un commit précis.
Le plan est un objet structuré, validé par un schéma, avec sources et incertitudes.
Un seul run par projet à la fois (resource_group).
Chaque effet externe (branche, merge request, commentaire) est idempotent.
Le token de l’agent a le minimum de droits et ne peut pas fusionner.
Changelogs, issues et documentation sont traités comme des entrées non fiables.
L’agent ne peut pas modifier la CI ni affaiblir les tests pour réussir.
Chaque run laisse une trace : versions, outils appelés, décisions, coûts, état final.
Une suite d’evals rejoue des cas réels avant chaque changement de modèle ou de prompt.
Les métriques incluent échecs, exclusions et temps de revue.
Conclusion
Un agent de montée de version utile n’est pas celui qui ouvre le plus de merge requests. C’est celui dont chaque action est bornée, dont chaque décision sensible est prise par une personne identifiée, et dont chaque run laisse assez de preuves pour être compris par quelqu’un d’autre.
La partie en place (analyse dans la CI, plan, validation humaine) suffit déjà à rendre le travail plus lisible pour l’équipe. La suite, c’est l’isolation, l’idempotence et surtout la mesure. Je publierai les chiffres quand ils seront interprétables, échecs compris.
Vous voulez mettre en place ce type de workflow dans votre équipe ? L’approche Diagnostic → Pilote → Industrialisation est décrite sur la page Travailler ensemble.
Sources
- Anthropic : Building effective agents (décembre 2024)
- Anthropic : Demystifying evals for AI agents (janvier 2026)
- GitLab : mot-clé when et allow_failure
- GitLab : resource_group
- GitLab : environnements protégés
- OWASP : LLM01:2025 Prompt Injection
- Gartner : gouvernance uniforme des agents (mai 2026)
- METR : étude sur la productivité des développeurs (2025)
- METR : mise à jour du protocole (février 2026)
- DINUM : une IA utile, humaine et souveraine pour les services publics (juin 2026)