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
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Fichier de contexte | des notes permanentes qu’un agent lit avant chaque tâche | AGENTS.md |
| Convention | une règle que l’équipe suit toujours | |
| Commande | une ligne que l’on tape pour lancer quelque chose | npm run test |
| Chemin protégé | un fichier ou un dossier que l’agent ne doit pas modifier | |
| Limite de lignes | le 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
| Ligne | Garder ou couper | Pourquoi |
|---|---|---|
| Lancez les tests avec npm run test | Garder | Une commande dont l’agent a besoin à chaque fois |
| Les prix sont en centimes entiers | Garder | Une convention que le code ne dit pas |
| Ne pas toucher : data/prix.json | Garder | Un chemin protégé |
| La boutique a ouvert en 2019 | Couper | De l’histoire dont l’agent n’a pas besoin |
| total additionne le panier | Couper | Le code le dit déjà |
| API_KEY=abc123 | Couper | Un 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
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 dépôt d’exemple, partie 1
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
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
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
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
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
docker exec -w /home/node/project agent node context.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 |
|---|---|
| AGENTS.md : 8 lignes, limite 40 | Le brouillon est assez court |
| ligne 4 : pas de script build | package.json n’a pas de script build |
| ligne 7 : chemin introuvable secrets/cles.txt | Le chemin protégé n’existe pas |
| ligne 8 : ressemble à un secret | Une 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.