Mon fichier AGENTS.md faisait 340 lignes. Je sais très bien comment j’en suis arrivé là. L’agent faisait quelque chose qui ne me plaisait pas, j’ajoutais une règle, et j’ai répété l’opération pendant des mois. Personne n’a jamais rien supprimé, et deux des règles se contredisaient.
Ce fichier entre dans chaque session, avant le premier token de travail utile. Il mérite donc une heure d’édition sérieuse. Voici la méthode que j’applique maintenant, et les trois mécanismes qui expliquent pourquoi un gros fichier dégrade les résultats au lieu de les améliorer.
AGENTS.md est un simple markdown à la racine du dépôt. Aucun champ obligatoire, aucun schéma : les agents lisent le texte tel quel. C’est un format ouvert, maintenu par l’Agentic AI Foundation sous l’égide de la Linux Foundation, présent dans plus de 60 000 dépôts publics. Codex, Cursor, Amp, Jules, Aider, goose, Zed, Warp, Gemini CLI et l’agent de codage GitHub Copilot le lisent tous.
Claude Code est l’exception que vous rencontrerez en pratique. Il lit CLAUDE.md, pas AGENTS.md, et la demande de support natif est toujours ouverte. Le contournement est plus bas.
Kyle, chez HumanLayer, a mis un chiffre là-dessus dans writing a good CLAUDE.md, en s’appuyant sur ces travaux sur le suivi d’instructions : les modèles frontier avec raisonnement suivent environ 150 à 200 instructions de façon raisonnablement fiable. Les modèles plus petits, ou sans raisonnement, en suivent moins et se dégradent plus vite.
Le détail qui devrait vous inquiéter, c’est la façon dont ils se dégradent. La qualité baisse uniformément. Le modèle n’ignore pas poliment les instructions du bas du fichier, il commence à toutes les ignorer un peu. HumanLayer compte environ 50 instructions dans le prompt système de Claude Code : une partie du budget est donc consommée avant que votre dépôt n’ait dit quoi que ce soit.
Comptez les instructions, pas les lignes. Un fichier de 40 lignes avec 35 impératifs pèse plus lourd qu’un fichier de 90 lignes qui en contient 12.
C’est la partie que j’aurais aimé connaître il y a un an. HumanLayer a intercepté les requêtes du CLI Claude Code et a constaté que le fichier est injecté avec un rappel système indiquant au modèle que ce contexte n’est peut-être pas pertinent, et qu’il ne doit pas y répondre sauf s’il est très pertinent pour la tâche.
Votre fichier de dépôt est donc une suggestion que le modèle a explicitement le droit de refuser. Et plus il contient de contenu non universel, plus il est facile pour le modèle de classer l’ensemble comme du bruit. Le remplissage ne coûte pas que des tokens, il coûte la crédibilité des lignes qui comptaient vraiment.
La documentation vieillit. Un humain qui lit une doc périmée reste sceptique. Un agent qui la lit à chaque requête est confiant et se trompe. Et ce sont les chemins de fichiers qui vieillissent le plus vite. Si le fichier affirme que l’authentification vit dans src/auth/handlers.ts et que quelqu’un l’a déplacée au sprint dernier, l’agent ira chercher là, puis inventera une explication sur ce qu’il y a trouvé.
L’outillage d’Anthropic encode désormais ce principe. Le contrôle /doctor de Claude Code (v2.1.206 et suivantes) propose de supprimer ce que l’agent peut déduire du code lui-même : arborescences, listes de dépendances, vues d’ensemble d’architecture. Il conserve les pièges, les justifications et les conventions qui s’écartent des comportements par défaut des outils. C’est un bon filtre à appliquer à la main, quel que soit votre outil. Le vocabulaire métier est plus stable que la structure : si “workspace” et “organisation” désignent deux choses différentes dans votre produit, documentez-le, parce que l’agent ne peut pas le deviner et que ça ne change pas tous les sprints.
Soyez impitoyable. Ma liste actuelle :
C’est à peu près tout. HumanLayer garde son fichier racine sous 60 lignes. Le plafond officieux de la communauté est de 300, et la doc d’Anthropic note qu’au-delà de 200 lignes un fichier consomme plus de contexte et peut réduire l’adhérence aux instructions. Le mien fait 45 lignes et les 295 autres ne me manquent pas.
# AGENTS.md
Tableau de bord de risque interne pour la salle des marchés. Lecture seule
sur l'entrepôt de données ; n'écrit jamais dans les tables de production.
## Setup
- pnpm workspaces (pas npm)
- `pnpm dev` lance l'app et l'entrepôt simulé ensemble
## Vérifier avant de terminer
- `pnpm typecheck && pnpm test --filter <package>`
## Pièges
- `packages/pricing` tourne uniquement sur Node 20, le reste sur Node 22
- Les dates de l'entrepôt sont en UTC, l'UI affiche en Europe/Paris
Conventions d'API : voir docs/api.md.
Patterns de tests : voir docs/testing.md.
Le conseil habituel consiste à déplacer les règles dans des fichiers séparés et à y faire référence. C’est juste, mais le mécanisme que vous choisissez décide si vous avez réellement gagné quelque chose.
Claude Code accepte les imports @chemin/vers/fichier. Ils ressemblent à de la divulgation progressive, et n’en sont pas : la documentation est explicite, les fichiers importés sont chargés au démarrage et entrent dans la fenêtre de contexte de toute façon. Découper un fichier monstrueux en imports le rend agréable à maintenir pour les humains et ne change rien pour l’agent. Ce qui réduit vraiment la charge, ce sont les règles à portée de chemin : des fichiers .claude/rules/*.md avec un champ frontmatter paths contenant des globs, chargés uniquement quand l’agent touche aux fichiers correspondants.
| où vous le mettez | quand c’est chargé | à utiliser pour |
|---|---|---|
| AGENTS.md ou CLAUDE.md racine | à chaque session | phrase de description, gestionnaire de paquets, commandes de vérification |
| un fichier cité en prose (“voir docs/testing.md”) | quand l’agent le juge pertinent | règles de domaine, conventions |
@import dans CLAUDE.md | à chaque session, expansé en ligne | organiser un gros fichier, pas économiser du contexte |
.claude/rules/*.md avec globs paths | quand l’agent touche aux fichiers ciblés | règles par langage ou par couche |
| AGENTS.md imbriqué dans un package | quand on travaille dans ce package | spécificités d’un package de monorepo |
| un skill | quand l’agent l’invoque | procédures et workflows en plusieurs étapes |
Une autre règle de HumanLayer que j’ai adoptée : préférez les pointeurs aux copies. Ne collez pas d’extraits de code dans ces documents, ils périment en quelques semaines. Référencez fichier:ligne et laissez l’agent lire la version qui fait foi.
Vous n’êtes pas limité à un seul fichier. Chaque package peut avoir le sien, et agents.md précise que le fichier le plus proche dans l’arborescence a la priorité, les instructions envoyées dans le chat primant sur tout le reste. Le dépôt principal d’OpenAI en contient 88.
Prudence ici : les harnais diffèrent sur la fusion ou la priorité des fichiers imbriqués, et Claude Code remonte l’arborescence depuis le répertoire de travail pour lire ses fichiers de mémoire. Ne supposez rien, vérifiez ce que votre outil a réellement chargé (/memory dans Claude Code) avant de bâtir une stratégie d’imbrication sur une supposition.
Gardez la racine pour ce qui s’applique partout : ce qu’est le monorepo, l’organisation des packages au niveau conceptuel, l’outillage partagé. Gardez le fichier de chaque package pour ce package. Ne surchargez ni l’un ni l’autre.
Les conventions de style sont ce que je vois le plus souvent dans ces fichiers, et c’est la suppression la plus facile. Les linters sont plus rapides, moins chers et déterministes. Biome, ESLint, Ruff et votre formateur imposent les guillemets et les point-virgules parfaitement, pour zéro token.
Les modèles apprennent en contexte. Après quelques recherches dans votre base de code, ils suivent les patterns environnants sans qu’on le leur dise. Si vous voulez une garantie, branchez un hook Stop qui lance le formateur et lui renvoie les erreurs, ou mettez vos règles dans une slash command que vous lancez sur le diff. Les deux valent mieux que de dépenser un tiers de votre budget d’instructions sur le style des guillemets.
Un AGENTS.md canonique, des adaptateurs minces autour :
@AGENTS.md. Les imports s’imbriquent sur cinq niveaux et sont ignorés à l’intérieur des blocs de code. Un lien symbolique fonctionne aussi, mais l’import laisse la place aux deux ou trois lignes spécifiques à Claude que vous finirez par vouloir.read: AGENTS.md dans .aider.conf.yml.{ "context": { "fileName": "AGENTS.md" } } dans .gemini/settings.json.mv AGENT.md AGENTS.md && ln -s AGENTS.md AGENT.md.Ce qu’il ne faut surtout pas faire, c’est maintenir les mêmes règles dans cinq fichiers. Ils divergent en un mois et vous passez votre temps à chercher lequel l’agent a lu.
Environ une heure, dans cet ordre :
Si vous voulez confier la première passe à l’agent lui-même, ce prompt fonctionne :
Refactore mon AGENTS.md selon le principe de divulgation progressive.
1. Liste chaque instruction distincte du fichier, numérotée.
2. Signale celles qu'un linter, un formateur ou un typeur applique déjà.
3. Signale celles qui décrivent une structure que le dépôt montre
déjà (chemins, arborescences, listes de dépendances).
4. Signale les contradictions et demande-moi laquelle garder.
5. Pour ce qui reste, indique : cette règle s'applique-t-elle à toutes
les tâches du dépôt, ou seulement à un domaine (tests, API,
migrations, CI) ?
6. Produis un fichier racine ne contenant que les règles valables pour
toutes les tâches, plus une ligne pointant vers chaque fichier de
domaine, ainsi que ces fichiers de domaine.
7. N'ajoute rien que je n'aie pas écrit.
Le point 7 compte. Laissé libre, l’agent réintroduira obligeamment les conseils génériques que vous venez de passer une heure à retirer.
Avant d’ajouter une ligne, je me demande à quelle tâche elle s’applique. Si la réponse n’est pas “à toutes”, elle ne va pas dans le fichier racine. Cette seule question a plus amélioré mes résultats que n’importe quelle règle que j’y ai écrite.
Le côté contre-intuitif, c’est que ce fichier est le plus utile quand il est presque vide. Il sert à orienter l’agent, pas à le contrôler. Le contrôle vient des hooks, des linters et des tests, qui eux ne se dégradent pas quand on en ajoute un quinzième.