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

Fichiers de contexte pour agents de code

Après cette leçon: Je peux écrire un court fichier de contexte qui dit à un agent de code comment travailler dans un dépôt.

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

Qu’est-ce qu’un fichier de contexte ?

Un fichier de contexte est un court fichier du dépôt qu’un agent de code lit avant chaque tâche. Il dit comment lancer les tests, quelles conventions l’équipe suit et ce qu’il ne faut pas toucher.

Sans lui, l’agent réapprend votre projet à chaque tâche et devine le reste. Savoir ce qui remplit la fenêtre de l’agent aide, mais ne suffit pas ; cette leçon écrit le fichier que garde une équipe.

À la fin de cette leçon

Remarque

Je peux écrire un court fichier de contexte qui dit à un agent de code comment travailler dans un dépôt.

Mots clés

MotCe que ça veut direExemple
Fichier de contextedes notes permanentes qu’un agent lit avant chaque tâcheAGENTS.md
Conventionune règle que l’équipe suit toujours
Commandeune ligne que l’on tape pour lancer quelque chosenpm run test
Chemin protégéun fichier ou un dossier que l’agent ne doit pas modifier
Limite de lignesle nombre maximal de lignes du fichier

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

Ce que le code ne dit pas

Le code montre ce que fait le programme. Il ne montre pas comment l’équipe travaille. Un fichier de contexte contient quatre sortes de lignes : les commandes de test et de lancement, les conventions, les chemins protégés et l’emplacement des choses.

opencode, l’agent de ce labo, lit un fichier nommé AGENTS.md à la racine du projet. D’autres agents lisent des fichiers aux noms différents.

Exemple guidé : lignes à garder ou à couper

LigneGarder ou couperPourquoi
Lancez les tests avec npm run testGarderUne commande dont l’agent a besoin à chaque fois
Les prix sont en centimes entiersGarderUne convention que le code ne dit pas
Ne pas toucher : data/prix.jsonGarderUn chemin protégé
La boutique a ouvert en 2019CouperDe l’histoire dont l’agent n’a pas besoin
total additionne le panierCouperLe code le dit déjà
API_KEY=abc123CouperUn secret ne va jamais dans le dépôt

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

Court, vrai et sûr

L’agent lit chaque ligne à chaque tâche, donc chaque ligne coûte du temps et de la place. Fixez une limite de lignes, par exemple 40, et tenez-la.

Une ligne qui n’est plus vraie est pire qu’aucune ligne. Une commande qui n’existe pas envoie l’agent dans la mauvaise direction. Un chemin qui a bougé ne protège rien.

Une erreur fréquente

Attention

Beaucoup pensent qu’un fichier de contexte plus long donne un meilleur travail. Une règle à la ligne 300 passe facilement inaperçue, pour un agent comme pour une personne. Gardez le fichier court, et vérifiez que chaque commande et chaque chemin existent encore.

É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 dépôt d’exemple, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const { demander } = require(\"./model\");' 'const NL = String.fromCharCode(10);' 'fs.mkdirSync(\"ctx-demo/data\", { recursive: true });' 'fs.mkdirSync(\"ctx-demo/src\", { recursive: true });' 'const pkg = { name: \"boutique\", scripts: { test: \"node --test\", lint: \"node lint.js\" } };' 'fs.writeFileSync(\"ctx-demo/package.json\", JSON.stringify(pkg, null, 2));' 'fs.writeFileSync(\"ctx-demo/data/prix.json\", JSON.stringify({ pomme: 35, jus: 85 }));' 'fs.writeFileSync(\"ctx-demo/src/boutique.js\", \"module.exports = {};\" + NL);' > context.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 dépôt d’exemple, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const brouillon = [\"# Notes pour les agents de code\", \"Lancez les tests avec npm run test\",' '  \"Vérifiez le style avec npm run lint\", \"Construisez le site avec npm run build\",' '  \"Les prix sont en centimes entiers, jamais en décimales.\", \"Ne pas toucher : data/prix.json\",' '  \"Ne pas toucher : secrets/cles.txt\", \"API_KEY=abc123 pour le serveur de test\"];' 'fs.writeFileSync(\"ctx-demo/AGENTS.md\", brouillon.join(NL) + NL);' >> context.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 dépôt d’exemple, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const LIMITE = 40;' 'const DEBUT = \"Ne pas toucher : \";' 'const lignes = fs.readFileSync(\"ctx-demo/AGENTS.md\", \"utf8\").trim().split(NL);' 'const scripts = JSON.parse(fs.readFileSync(\"ctx-demo/package.json\", \"utf8\")).scripts;' 'const trouves = [];' 'if (lignes.length > LIMITE) trouves.push(\"trop long : \" + lignes.length + \" lignes\");' >> context.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 dépôt d’exemple, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'lignes.forEach(function (ligne, i) {' '  const mots = ligne.split(\" \");' '  const r = mots.indexOf(\"run\");' '  const ou = \"ligne \" + (i + 1) + \" : \";' '  if (r > 0 && mots[r - 1] === \"npm\" && scripts[mots[r + 1]] === undefined) trouves.push(ou + \"pas de script \" + mots[r + 1]);' '  const chemin = ligne.slice(DEBUT.length);' '  if (ligne.indexOf(DEBUT) === 0 && fs.existsSync(\"ctx-demo/\" + chemin) === false) trouves.push(ou + \"chemin introuvable \" + chemin);' '  if (ligne.indexOf(\"KEY=\") >= 0 || ligne.toLowerCase().indexOf(\"mot de passe\") >= 0) trouves.push(ou + \"ressemble à un secret\");' '});' >> context.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 dépôt d’exemple, partie 5

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  console.log(\"AGENTS.md : \" + lignes.length + \" lignes, limite \" + LIMITE);' '  trouves.forEach(function (un) { console.log(un); });' '  const q = \"En une phrase courte, pourquoi un fichier de contexte pour un agent de code doit-il rester court ?\";' '  const echantillon = \"L’agent lit chaque ligne à chaque tâche, donc un long fichier noie les règles qui comptent.\";' '  const reponse = await demander([{ role: \"user\", content: q }], echantillon, 60);' '  console.log(\"le modèle dit : \" + reponse.texte);' '}' 'main();' >> context.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 contexte

Commande
docker exec -w /home/node/project agent node context.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
AGENTS.md : 8 lignes, limite 40Le brouillon est assez court
ligne 4 : pas de script buildpackage.json n’a pas de script build
ligne 7 : chemin introuvable secrets/cles.txtLe chemin protégé n’existe pas
ligne 8 : ressemble à un secretUne clé inventée, qui doit sortir du fichier
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.

À 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.