Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Relire les changements d’un agent par risque

Après cette leçon: Je peux trier par risque l’ensemble de changements d’un agent de code avant de le lire.

Leçon de 70 min8 commandesLab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Comment relire les changements d’un agent de code

Un ensemble de changements regroupe tous les fichiers qu’un agent de code a ajoutés, modifiés ou supprimés pour une tâche. Un agent peut changer vingt fichiers en une minute, et tout lire avec le même soin ne tient pas.

Une relecture par le risque trouve les fichiers risqués et les lit en premier. Lire un petit diff à l’œil suffit pour un petit changement ; cette leçon trie tout un ensemble.

À la fin de cette leçon

Remarque

Je peux trier par risque l’ensemble de changements d’un agent de code avant de le lire.

Mots clés

MotCe que ça veut dire
Ensemble de changementstous les fichiers changés pour une tâche
Dérive du périmètredes changements au-delà de ce que la tâche demandait
Dépendanceun paquet dont le code a besoin pour tourner
Indicateur de risqueun signe qu’un changement demande de l’attention
Poidsle nombre de points que vaut un indicateur

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Cinq signes qu’un changement demande de l’attention

Un fichier que la tâche ne nommait pas est une dérive du périmètre. Un test supprimé, ou un test qui perd des lignes, peut cacher une fonction cassée. Un fichier de configuration modifié peut changer toute la construction.

Un très gros fichier nouveau est difficile à lire. Une nouvelle dépendance apporte du code que personne dans l’équipe n’a écrit. Chacun de ces signes est un indicateur de risque.

Exemple guidé : les indicateurs et leurs poids

IndicateurQuand il est levéPoids
test suppriméUn fichier de test est supprimé5
test réduitUn fichier de test perd plus de lignes qu’il n’en gagne3
hors périmètreLa tâche ne nommait pas le fichier3
configpackage.json, package-lock.json ou ci.yml2
grosPlus de 200 lignes ajoutées et retirées1

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Noter, trier, puis lire

Additionnez les poids des indicateurs de chaque fichier pour lui donner un score. Triez les fichiers du plus gros score au plus petit, et gardez les égalités dans leur ordre d’arrivée.

Lisez ensuite les fichiers du haut en entier, ligne par ligne. Les fichiers du bas sont lus aussi, mais ils ne cachent plus les fichiers risqués. Un test supprimé renvoie tout le changement.

Une erreur fréquente

Attention

Beaucoup pensent qu’une relecture veut dire lire chaque ligne avec le même soin. Sur 400 lignes, les dix lignes risquées se cachent parmi les autres. Triez d’abord par risque, puis lisez en entier chaque fichier risqué.

Écrire l’assistant du modèle, partie 1

Commande
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

Commande
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 script de relecture, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' '// La tâche nommait deux fichiers. L’agent en a rendu sept.' 'const autorises = [\"boutique.js\", \"boutique.test.js\"];' 'const CONFIG = [\"package.json\", \"package-lock.json\", \"ci.yml\"];' 'const POIDS = { \"test supprimé\": 5, \"test réduit\": 3, \"hors périmètre\": 3, \"config\": 2, \"gros\": 1 };' > risk.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 script de relecture, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const changements = [' '  { chemin: \"boutique.js\", ajoutees: 12, retirees: 2, type: \"modifié\" },' '  { chemin: \"boutique.test.js\", ajoutees: 1, retirees: 9, type: \"modifié\" },' '  { chemin: \"prix.json\", ajoutees: 1, retirees: 1, type: \"modifié\" },' '  { chemin: \"ancien.test.js\", ajoutees: 0, retirees: 40, type: \"supprimé\" },' '  { chemin: \"package.json\", ajoutees: 1, retirees: 0, type: \"modifié\" },' '  { chemin: \"README.md\", ajoutees: 3, retirees: 0, type: \"modifié\" },' '  { chemin: \"utils/format.js\", ajoutees: 230, retirees: 0, type: \"ajouté\" },' '];' 'const avant = [\"outils-date\"];' 'const apres = [\"outils-date\", \"format-monnaie\"];' >> risk.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 script de relecture, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function indicateurs(c) {' '  const sortie = [];' '  const estTest = c.chemin.indexOf(\".test.\") >= 0;' '  if (estTest && c.type === \"supprimé\") sortie.push(\"test supprimé\");' '  if (estTest && c.type === \"modifié\" && c.retirees > c.ajoutees) sortie.push(\"test réduit\");' '  if (autorises.indexOf(c.chemin) < 0) sortie.push(\"hors périmètre\");' '  if (CONFIG.indexOf(c.chemin) >= 0) sortie.push(\"config\");' '  if (c.ajoutees + c.retirees > 200) sortie.push(\"gros\");' '  return sortie;' '}' 'function score(c) {' '  return indicateurs(c).reduce(function (somme, f) { return somme + POIDS[f]; }, 0);' '}' >> risk.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 script de relecture, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const ordre = changements.slice().sort(function (a, b) { return score(b) - score(a); });' '  ordre.forEach(function (c) {' '    console.log(score(c) + \" \" + c.chemin + (indicateurs(c).length ? \" : \" + indicateurs(c).join(\", \") : \"\"));' '  });' '  apres.filter(function (d) { return avant.indexOf(d) < 0; })' '    .forEach(function (d) { console.log(\"nouvelle dépendance : \" + d); });' '  const parti = changements.some(function (c) { return indicateurs(c).indexOf(\"test supprimé\") >= 0; });' '  console.log(parti ? \"renvoyer : un test a été supprimé\" : \"relire dans cet ordre\");' >> risk.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 script de relecture, partie 5

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  const q = \"En une phrase courte, pourquoi un relecteur doit-il regarder d’abord un fichier de test supprimé ?\";' '  const echantillon = \"Un test supprimé peut cacher une fonction cassée, car plus rien ne la contrôle.\";' '  const reponse = await demander([{ role: \"user\", content: q }], echantillon, 60);' '  console.log(\"le modèle dit : \" + reponse.texte);' '}' 'main();' >> risk.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 la relecture par risque

Commande
docker exec -w /home/node/project agent node risk.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.

Ce qu’affiche le Run

LigneCe qu’elle montre
8 ancien.test.js : test supprimé, hors périmètreLe fichier le plus risqué, lu en premier
5 package.json : hors périmètre, configUn fichier de configuration que la tâche ne nommait pas
4 utils/format.js : hors périmètre, grosUn gros fichier nouveau que personne n’a demandé
3 boutique.test.js : test réduitLe test nommé a perdu plus de lignes qu’il n’en a gagné
3 prix.json : hors périmètreUn fichier que la tâche ne nommait pas
3 README.md : hors périmètreIdem : la tâche ne parlait pas de la documentation
0 boutique.jsUn fichier que la tâche nommait, sans aucun signe de risque, lu en dernier
nouvelle dépendance : format-monnaieDu code nouveau venu de l’extérieur
renvoyer : un test a été suppriméLa décision pour tout l’ensemble

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

À propos de ce labo et de sa source: Lab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.