Ce qu’est une étape agent dans la CI
L’intégration continue (CI) lance des contrôles à chaque changement poussé dans un dépôt. Une équipe peut y ajouter un agent de code comme étape, par exemple pour corriger les coquilles de la documentation.
Personne ne surveille une étape de pipeline, donc ses limites sont écrites d’abord. Limiter ce qu’un agent fait pendant une seule exécution ne suffit donc pas ; cette leçon conçoit le pipeline autour.
À la fin de cette leçon
Remarque
Je peux concevoir une étape de pipeline pour un agent de code avec l’approbation d’une personne avant la fusion.
Mots clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Pipeline | des étapes lancées dans l’ordre à chaque changement | |
| Permission | ce qu’une étape a le droit de faire | ecriture-branche |
| Moindre privilège | seulement les permissions dont une étape a besoin | |
| Porte d’approbation | un point où une personne doit dire oui | |
| Journal | une trace de ce que l’étape a fait |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une étape agent reçoit le moins de permissions
Une étape peut lire le code, écrire sur une branche, écrire sur la branche principale ou lire les secrets de l’équipe. Une étape agent a besoin de lire et d’écrire sur une branche. Elle n’a jamais besoin de main ni des secrets.
Elle liste aussi les dossiers qu’elle peut modifier et une limite de temps. Le signe « * » veut dire « tout », donc aucune limite.
Exemple guidé : les permissions d’une étape agent
| Permission | Étape agent | Pourquoi |
|---|---|---|
| lecture | Oui | Elle doit lire le code |
| ecriture-branche | Oui | Son changement va sur une branche à elle |
| ecriture-main | Non | Seule une fusion approuvée par une personne écrit sur main |
| secrets | Non | Un secret dans une consigne peut fuir |
| peut modifier | docs/ seulement | Les dossiers dont sa tâche a besoin |
| limite de temps | 30 minutes au plus | Un agent bloqué s’arrête |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Des tests, une personne, puis la fusion
Après l’étape agent, les tests tournent de nouveau sur sa branche. Ensuite une personne lit le changement et l’approuve, et seulement alors la fusion a lieu.
L’étape garde un journal : la tâche reçue, chaque commande lancée et chaque fichier modifié. Quand un problème apparaît un mois plus tard, le journal dit ce qui s’est passé.
Une erreur fréquente
Attention
Beaucoup pensent qu’un agent dans la CI est sans danger parce qu’il ouvre seulement une branche. Une étape qui peut lire les secrets ou pousser sur main peut quand même nuire. Donnez-lui le moins de permissions, et placez des tests et une personne avant chaque fusion.
Écrire l’assistant du modèle, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Les jetons d’une réponse, ou null si elle n’en donne pas.' 'function compter(donnees, nom) {' ' return donnees.usage && typeof donnees.usage[nom] === \"number\" ? donnees.usage[nom] : null;' '}' > model.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire l’assistant du modèle, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function demander(messages, echantillon, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"statut \" + res.status);' ' const d = await res.json();' ' return { texte: d.choices[0].message.content, entree: compter(d, \"prompt_tokens\"), sortie: compter(d, \"completion_tokens\"), enregistre: false };' ' } catch (erreur) {' ' console.log(\"Échantillon enregistré : aucun modèle n’a répondu (\" + erreur.message + \").\");' ' return { texte: echantillon, entree: null, sortie: null, enregistre: true };' ' }' '}' 'module.exports = { demander };' >> model.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le contrôleur de pipeline, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const pipelines = {' ' \"robot docs\": [' ' { nom: \"recuperation\", type: \"preparation\", permissions: [\"lecture\"] },' ' { nom: \"agent\", type: \"agent\", permissions: [\"lecture\", \"ecriture-branche\"], peut_modifier: [\"docs/\"],' ' garde_journal: true, minutes_max: 20 },' ' { nom: \"tests\", type: \"test\", permissions: [\"lecture\"] },' ' { nom: \"fusion\", type: \"fusion\", permissions: [\"ecriture-main\"], besoin_approbation: true },' ' ],' ' \"correcteur auto\": [' ' { nom: \"agent\", type: \"agent\", permissions: [\"lecture\", \"ecriture-main\", \"secrets\"], peut_modifier: [\"*\"],' ' garde_journal: false, minutes_max: 90 },' ' { nom: \"fusion\", type: \"fusion\", permissions: [\"ecriture-main\"], besoin_approbation: false },' ' ],' '};' > ci.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le contrôleur de pipeline, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function problemesEtape(e) {' ' const sortie = [];' ' if (e.permissions.indexOf(\"ecriture-main\") >= 0) sortie.push(\"peut pousser sur main\");' ' if (e.permissions.indexOf(\"secrets\") >= 0) sortie.push(\"peut lire les secrets\");' ' if (e.peut_modifier.length === 0 || e.peut_modifier.indexOf(\"*\") >= 0) sortie.push(\"peut tout modifier\");' ' if (e.garde_journal === false) sortie.push(\"ne garde aucun journal\");' ' if (e.minutes_max > 30) sortie.push(\"dure trop longtemps\");' ' return sortie.map(function (p) { return e.nom + \" : \" + p; });' '}' >> ci.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le contrôleur de pipeline, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function problemes(etapes) {' ' let sortie = [];' ' let agent = false;' ' let teste = false;' ' etapes.forEach(function (e) {' ' if (e.type === \"agent\") { sortie = sortie.concat(problemesEtape(e)); agent = true; teste = false; }' ' if (e.type === \"test\") teste = true;' ' if (e.type === \"fusion\" && agent && teste === false) sortie.push(e.nom + \" : aucun test après l’agent\");' ' if (e.type === \"fusion\" && agent && e.besoin_approbation === false) sortie.push(e.nom + \" : aucune approbation\");' ' });' ' return sortie;' '}' >> ci.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le contrôleur de pipeline, partie 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' Object.keys(pipelines).forEach(function (nom) {' ' const trouves = problemes(pipelines[nom]);' ' console.log(nom + \" : \" + (trouves.length === 0 ? \"sûr\" : \"dangereux\"));' ' trouves.forEach(function (p) { console.log(\" \" + p); });' ' });' ' const q = \"En une phrase courte, pourquoi une personne doit-elle approuver avant la fusion d’un changement fait par un agent ?\";' ' const echantillon = \"Une personne voit ce que le changement veut dire, ce que les tests et l’agent ne peuvent pas juger.\";' ' const reponse = await demander([{ role: \"user\", content: q }], echantillon, 60);' ' console.log(\"le modèle dit : \" + reponse.texte);' '}' 'main();' >> ci.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lancer le contrôleur de pipeline
docker exec -w /home/node/project agent node ci.jsAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ce qu’affiche le Run
| Ligne | Ce qu’elle montre |
|---|---|
| robot docs : sûr | Le moins de permissions, des tests, puis une approbation |
| correcteur auto : dangereux | Sept problèmes listés en dessous |
| agent : peut pousser sur main | Il peut se passer de toute personne |
| fusion : aucun test après l’agent | Rien ne contrôle son changement |
| fusion : aucune approbation | Personne ne dit oui avant la fusion |
| le modèle dit : ... | Une phrase du labo. Une ligne Échantillon enregistré si aucun modèle ne répond |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.