SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-11

AGENTS.md imbriqués pour un monorepo

Un seul AGENTS.md finit par être obsolète et consomme du contexte inutile. Découvrez une structure imbriquée, avec des règles adaptées à chaque service.

Ce que signifie AGENTS.md imbriqué dans un monorepo

Un fichier AGENTS.md imbriqué dans un monorepo consiste à placer un petit fichier à la racine du dépôt, puis un autre fichier dans le répertoire de chaque service. Le fichier racine contient les quelques règles qui s’appliquent partout, ainsi qu’une carte indiquant où se trouvent les autres fichiers. Chaque fichier de service contient les commandes et les conventions propres à ce répertoire. Un agent qui modifie services/worker/queue.py lit alors le fichier racine et celui du worker, sans utiliser de contexte pour le front end auquel il ne touchera jamais.

Il n’y a rien à installer. AGENTS.md est une convention, comme le précise clairement le projet amont :

AGENTS.md est simplement du Markdown standard. Utilisez les niveaux de titre de votre choix ; l’agent analyse uniquement le texte que vous lui fournissez.

C’est pourquoi il est utile de bien maîtriser cette technique. Le format ne changera pas sans préavis. En revanche, l’emplacement et la maintenance peuvent poser problème, et ces deux aspects relèvent de votre responsabilité.

Pourquoi un seul gros fichier AGENTS.md à la racine cesse-t-il de fonctionner ?

Un fichier AGENTS.md unique de 600 lignes à la racine d’un dépôt qui contient une application web, un background worker et un répertoire Terraform échoue de quatre façons distinctes.

Il devient obsolète, car personne n’en est responsable. L’ingénieur qui renomme un script de test dans apps/web modifie des fichiers sous apps/web. Le fichier AGENTS.md racine ne fait pas partie de ce diff. Aucun reviewer ne voit donc l’incohérence. Six semaines plus tard, le fichier décrit une étape de build qui n’existe plus, et la personne à l’origine du problème a oublié cette modification.

Il consomme du contexte pour chaque tâche. Ces fichiers sont chargés au début de la session, avant que l’agent sache ce que vous allez lui demander. La documentation de Claude Code donne un chiffre : « visez moins de 200 lignes par fichier CLAUDE.md. Les fichiers plus longs consomment davantage de contexte et réduisent le respect des instructions ». Codex cesse de fusionner les fichiers d’instructions lorsque leur taille cumulée atteint 32 KiB, la valeur par défaut project_doc_max_bytes. Un fichier racine qui documente quatre services consomme ce budget avec des informations sur trois d’entre eux pour chaque tâche.

Les instructions commencent à se contredire. Le répertoire web attend pnpm test. Le worker attend pytest -q. Dans un même fichier, chaque règle n’est correcte que dans certains cas. L’agent doit donc deviner laquelle s’applique. La documentation de Claude Code décrit le résultat : « si deux règles se contredisent, Claude peut en choisir une arbitrairement ». Un fichier propre à chaque répertoire supprime cette incertitude, car une seule des deux règles se trouve dans le contexte.

Il se remplit d’informations que l’agent peut lire dans le code. Une arborescence, une liste de dépendances, un résumé du rôle de chaque package. Le contrôle /doctor de Claude Code sert précisément à supprimer ce contenu. Il « supprime les informations que Claude peut déduire du codebase, comme la structure des répertoires, les listes de dépendances et les vues d’ensemble de l’architecture » et conserve « les pièges, la justification des choix et les conventions qui diffèrent des valeurs par défaut des outils ». Cette phrase est le meilleur test que je connaisse pour déterminer si une ligne doit réellement figurer dans le fichier.

L’agent lit-il le fichier à la racine, ou uniquement le fichier le plus proche ?

C’est sur ce point que la plupart des utilisateurs se trompent. Il est donc préférable de reprendre la convention upstream plutôt que de la paraphraser :

Placez un autre fichier AGENTS.md dans chaque package. Les agents lisent automatiquement le fichier le plus proche dans l’arborescence. Celui qui est le plus proche est donc prioritaire, et chaque sous-projet peut fournir des instructions adaptées.

Concernant les conflits :

Le fichier AGENTS.md le plus proche du fichier modifié est prioritaire ; les prompts explicites de l’utilisateur dans le chat prennent le dessus sur tout le reste.

Pour beaucoup, « est prioritaire » signifie que le fichier à la racine est ignoré. Ce n’est pas le cas. Dans les outils qui appliquent cette convention, tous les fichiers situés entre la racine du repository et le répertoire de travail sont lus et concaténés. Le fichier le plus proche est prioritaire uniquement lorsque deux fichiers donnent des instructions différentes sur le même sujet.

Codex décrit explicitement ce mécanisme : « Codex concatène les fichiers depuis la racine vers les sous-répertoires en les séparant par des lignes vides. Les fichiers les plus proches de votre répertoire courant remplacent les instructions précédentes. » Claude Code parcourt la même arborescence pour rechercher son propre nom de fichier. Les fichiers situés dans les répertoires au-dessus du répertoire de travail « sont chargés intégralement au démarrage », et « tous les fichiers détectés sont concaténés dans le contexte au lieu de se remplacer mutuellement ». Les répertoires situés sous le répertoire de travail se comportent différemment : Claude Code charge ces fichiers à la demande, « lorsque Claude lit des fichiers dans ces répertoires ».

Deux conséquences pratiques en découlent. Le fichier à la racine est un préfixe présent dans chaque session du repository. Traitez donc chaque ligne comme une ligne dont vous payez le coût cent fois par semaine. Un fichier propre à un répertoire ne coûte rien lorsque l’agent travaille ailleurs. Les détails peuvent donc y être plus nombreux et doivent être placés à cet endroit.

Ce comportement a été vérifié dans la documentation de Codex et de Claude Code en août 2026. Les outils implémentent cette convention de manière légèrement différente et leur comportement évolue. Vérifiez donc les règles de chargement applicables à l’agent utilisé par votre équipe.

Une organisation concrète pour un dépôt comportant trois services

repo/
  AGENTS.md                   rules true everywhere, plus the map
  apps/web/AGENTS.md          TypeScript client, Vite, Vitest
  services/worker/AGENTS.md   Python queue consumer, pytest
  infra/AGENTS.md             Terraform and the deploy scripts

Le fichier racine est volontairement court. Il indique où chercher et contient uniquement les règles applicables à tous les répertoires.

# AGENTS.md

This is a monorepo. Each top-level directory ships its own AGENTS.md.
Read this file and the AGENTS.md nearest the code you are editing
before you change anything.

- `apps/web` browser client
- `services/worker` queue consumer
- `infra` Terraform and deploy scripts

## Rules for the whole repository

- The package manager is `pnpm`. `npm install` writes a second lockfile
  that CI ignores, so the install you tested is not the install that ships.
- Any `generated/` directory is build output. Edit the schema in
  `schemas/` and run `pnpm codegen` instead.
- `.env.local` holds real credentials. Do not read it and do not print it.
- If you change code in a directory, update that directory's AGENTS.md
  in the same commit.

Le fichier propre à chaque répertoire contient les détails. Sa longueur peut correspondre aux besoins du répertoire.

# apps/web

Browser client. Vite and React, TypeScript with `strict` on.

## Commands

- `pnpm dev` serves on port 5173.
- `pnpm test` runs Vitest once and exits.
- `pnpm typecheck` runs `tsc --noEmit`.

## Conventions

- One component per file under `src/components/`.
- All HTTP goes through `src/api/client.ts`. Do not call `fetch` directly,
  because the client attaches the auth header and retries on 429.

## Traps

- `pnpm build` does not type check. Vite strips the types instead of
  checking them, so a broken type still produces a green build.
  Run `pnpm typecheck` as a separate step.

Le fichier du worker suit la même structure, avec un contenu différent : la commande d’installation, pytest -q, la raison pour laquelle le consumer doit rester idempotent et la migration à exécuter avant que les tests réussissent. Le fichier d’infrastructure contient les règles qui empêchent un agent de causer des dommages. N’exécutez jamais terraform apply. Exécutez terraform plan, puis arrêtez-vous là. Indiquez également le state backend déjà configuré afin que l’agent n’essaie pas d’en initialiser un nouveau.

Remarquez ce qui ne figure dans aucun de ces fichiers : une description du rôle de chaque service. Cette information est destinée aux humains. Le projet upstream établit la même distinction en indiquant que les fichiers « README.md sont destinés aux humains : démarrages rapides, descriptions de projet et consignes de contribution », tandis que AGENTS.md contient « le contexte supplémentaire, parfois détaillé, dont les agents de codage ont besoin : étapes de build, tests et conventions ». La distinction entre AGENTS.md et un README destiné aux humains examine cette séparation phrase par phrase. Un DESIGN.md qui explique pourquoi le code est structuré ainsi traite du troisième fichier, celui qui explique les décisions plutôt que les commandes.

Qui met à jour le fichier lorsque le code change ?

Une seule règle, à inscrire dans le fichier racine : la personne qui modifie du code dans un répertoire met à jour le fichier AGENTS.md de ce répertoire dans le même commit.

Cette règle fonctionne pour une raison mécanique, pas culturelle. Le fichier propre au répertoire figure dans le même diff que le code. Le reviewer de la pull request voit donc les deux en même temps. Un fichier racine appartient à tout le monde, donc à personne. Il ne figure jamais dans le diff que quelqu’un consulte déjà.

Ajoutez un contrôle sur la pull request. Il recherche le fichier AGENTS.md le plus proche au-dessus de chaque fichier modifié, puis signale lorsque ce fichier n’a pas été modifié.

#!/usr/bin/env bash
# Warn when code changed but the nearest AGENTS.md above it did not.
changed=$(git diff --name-only origin/main...HEAD)

nearest_doc() {
  d=$(dirname "$1")
  while [ "$d" != "." ]; do
    if [ -f "$d/AGENTS.md" ]; then echo "$d/AGENTS.md"; return; fi
    d=$(dirname "$d")
  done
  echo "AGENTS.md"
}

printf '%s\n' "$changed" | while read -r f; do
  [ -n "$f" ] || continue
  case "$f" in AGENTS.md|*/AGENTS.md) continue ;; esac
  doc=$(nearest_doc "$f")
  printf '%s\n' "$changed" | grep -Fqx "$doc" && continue
  echo "note: $f changed but $doc was not updated"
done

Sur une branche qui a refactoré le client d’API sans modifier la documentation, la sortie ressemble à ceci :

note: apps/web/src/api/client.ts changed but apps/web/AGENTS.md was not updated

Faites-en un warning plutôt qu’un échec. Une règle bloquante apprend aux utilisateurs à ajouter une ligne vide au fichier pour que la CI passe au vert. Un fichier modifié uniquement pour satisfaire un robot vaut moins que l’absence totale de fichier. Le warning donne au reviewer une question à poser. C’est cette partie qui fonctionne réellement.

Comment repérer un fichier AGENTS.md devenu obsolète ?

Vous pouvez effectuer deux vérifications dès aujourd’hui et observer un symptôme pendant une session.

Comparez la date de chaque fichier avec celle du code qu’il décrit. %cs affiche la date du commit au format YYYY-MM-DD.

for f in $(git ls-files '*AGENTS.md'); do
  d=$(dirname "$f")
  printf '%s  doc:%s  code:%s\n' "$f" \
    "$(git log -1 --format=%cs -- "$f")" \
    "$(git log -1 --format=%cs -- "$d")"
done
apps/web/AGENTS.md          doc:2026-02-11  code:2026-08-07
services/worker/AGENTS.md   doc:2026-07-29  code:2026-08-09
infra/AGENTS.md             doc:2026-08-01  code:2026-08-01

Une documentation datée de six mois avant le code ne prouve pas que le fichier est incorrect. Elle vous indique simplement quel fichier lire en premier. C’est tout ce qu’il faut attendre d’une vérification qui prend une seconde.

Recherchez les chemins qui n’existent plus. La documentation se dégrade d’une manière très précise : elle continue à décrire du code qui a été supprimé. Chaque chemin de ces fichiers est placé entre accents graves, ce qui permet de les extraire et de les tester facilement.

grep -o '`[^`]*`' apps/web/AGENTS.md | tr -d '`' | grep '/' | while read -r p; do
  [ -e "$p" ] || [ -e "apps/web/$p" ] || echo "missing: $p"
done

Lisez la sortie au lieu d’intégrer cette vérification à la CI. Elle signale également les globs tels que src/**/*.ts et les URL que vous avez citées, car les deux contiennent une barre oblique et aucun des deux ne correspond à un fichier sur le disque.

Le symptôme pendant une session. L’agent lit le fichier, essaie d’ouvrir src/api/client.ts parce que le fichier le lui demande, puis l’outil renvoie :

No such file or directory

Il fait donc ce qui est logique et écrit son propre wrapper fetch. C’est le véritable coût d’un fichier obsolète. L’agent n’ignore pas votre documentation. Il la suit, arrive sur un chemin qui a été supprimé il y a trois mois, puis recrée du code que vous avez déjà. Une compétence telle que Ponytail, qui oblige l’agent à effectuer le plus petit changement fonctionnel, rend cette tendance à recréer du code moins fréquente, mais elle ne peut pas trouver un helper vers lequel votre fichier indiquait le mauvais chemin.

Claude Code lit-il les fichiers AGENTS.md ?

Non, et il est important de le préciser, car la structure imbriquée en dépend. En août 2026, la documentation indique : « Claude Code lit CLAUDE.md, pas AGENTS.md. » Le modèle fonctionne toujours, mais vous devez placer un CLAUDE.md à côté de chaque AGENTS.md.

La forme avec import convient lorsque vous voulez ajouter des lignes propres à l’outil aux lignes communes. Placez ceci dans services/worker/CLAUDE.md :

@AGENTS.md

## Claude Code

Use plan mode for changes under `services/worker/migrations/`.

La forme avec symlink convient lorsqu’aucune configuration spécifique à l’outil n’est nécessaire.

git ls-files '*AGENTS.md' | while read -r f; do
  ln -s AGENTS.md "$(dirname "$f")/CLAUDE.md"
done
ls -l apps/web/CLAUDE.md

ln n’affiche rien en cas de succès. Vérifiez donc la liste avec : apps/web/CLAUDE.md -> AGENTS.md. Démarrez ensuite une session et exécutez /context. Les fichiers chargés apparaissent sous Memory files. Sous Windows, la création d’un symlink nécessite les droits Administrator ou le Developer Mode. Utilisez donc plutôt l’import @AGENTS.md.

Un point particulier doit être signalé. Après /compact, le fichier racine est relu depuis le disque, mais les fichiers imbriqués dans les sous-répertoires ne sont pas réinjectés. Ils réapparaissent la prochaine fois que l’agent lit un fichier dans ce répertoire. Si une règle propre à un répertoire semble cesser de s’appliquer au milieu d’une longue session, c’est généralement la cause. Touchez alors n’importe quel fichier du répertoire pour la réactiver.

Paramètres qui indiquent aux autres agents d’utiliser AGENTS.md

Codex lit nativement AGENTS.md. À chaque niveau, il recherche d’abord AGENTS.override.md. Cela permet de définir une surcharge locale pour un répertoire sans modifier le fichier partagé. La fusion s’arrête lorsque la taille combinée atteint 32 KiB, valeur par défaut de project_doc_max_bytes. C’est une raison supplémentaire de garder le fichier racine court.

Aider le prend en charge via .aider.conf.yml avec la ligne read: AGENTS.md.

Gemini CLI le prend en charge via .gemini/settings.json avec { "context": { "fileName": "AGENTS.md" } }.

La documentation upstream décrit un renommage rétrocompatible pour les dépôts qui utilisent encore l’ancien nom au singulier : mv AGENT.md AGENTS.md && ln -s AGENTS.md AGENT.md.

Dans un très grand monorepo, le paramètre claudeMdExcludes de Claude Code ignore les fichiers des répertoires parents selon un chemin ou un glob. Cette option est utile lorsqu’un répertoire appartenant à une autre équipe se trouve au-dessus du vôtre.

En quoi cela diffère-t-il de la mémoire de l’agent ou d’une skill ?

Ces mécanismes se ressemblent, mais échouent pour des raisons complètement différentes. Il est donc utile de déterminer précisément lequel utiliser.

AGENTS.md est rédigé par vous, versionné dans git, relu dans une pull request et identique pour toutes les personnes qui clonent le dépôt. La mémoire de l’agent est écrite par l’agent, stockée en dehors du dépôt et locale à une seule machine. La documentation de Claude Code établit la même distinction : CLAUDE.md contient les « instructions et règles » que vous rédigez, tandis que la mémoire automatique contient les « enseignements et schémas » que Claude écrit ; le répertoire de mémoire n’est pas partagé entre les machines. Le test est simple. Si un fait doit être vrai pour un collègue qui effectue un clone vierge, il ne peut pas être stocké dans la mémoire. Comment la mémoire de l’agent est conservée entre les sessions couvre cette partie du sujet.

Une skill est le troisième élément. AGENTS.md fournit un contexte chargé à chaque session ; une skill fournit une procédure chargée lorsqu’elle est nécessaire. La documentation de Claude Code donne une règle utile : « Si une entrée décrit une procédure en plusieurs étapes ou ne concerne qu’une partie du codebase, déplacez-la dans une skill ou dans une règle limitée à un chemin. » La seconde partie de cette phrase correspond précisément à ce que permet un AGENTS.md imbriqué. La première concerne les skills d’agent ; lorsque la même procédure est nécessaire dans plusieurs dépôts, partagez la skill entre les dépôts au lieu de recopier les mêmes paragraphes dans dix fichiers AGENTS.md différents.

Le projet amont indique qu’« au moment de la rédaction, le dépôt OpenAI principal contient 88 fichiers AGENTS.md ». Ce nombre résume tout l’argument. Un dépôt volumineux n’a pas besoin d’un fichier plus gros. Il a besoin de davantage de petits fichiers, chacun placé à côté du code qu’il décrit et pris en charge par la personne qui a modifié ce code en dernier.

FAQ

Un fichier AGENTS.md imbriqué remplace-t-il le fichier racine ou s’y ajoute-t-il ?

Il s’y ajoute. La documentation amont indique que « le fichier le plus proche est prioritaire », ce qui décrit le comportement en cas de conflit, et non les fichiers chargés. Codex « concatène les fichiers depuis la racine vers les sous-répertoires en les séparant par des lignes vides », et Claude Code concatène chaque fichier trouvé en remontant depuis le répertoire de travail, au lieu de les remplacer. Le fichier le plus proche est prioritaire uniquement lorsque deux fichiers donnent des instructions différentes sur le même sujet. Écrivez les règles communes une seule fois à la racine et ne les répétez pas dans chaque répertoire.

Quelle doit être la taille du fichier AGENTS.md racine ?

Il doit être suffisamment court pour que vous ne voyiez aucun inconvénient à le placer au début de chaque requête envoyée dans ce dépôt, car c’est ce qui se passe. La documentation de Claude Code recommande de viser moins de 200 lignes par fichier et avertit que les fichiers plus longs « réduisent le respect des instructions ». Par défaut, Codex cesse de fusionner les fichiers d’instructions lorsque leur taille cumulée atteint 32 KiB. Si votre fichier racine documente quatre services, la majeure partie de son contenu est inutile pour une tâche donnée. Déplacez les détails dans des fichiers propres à chaque répertoire et laissez une carte de navigation à la racine.

Comment éviter que ces fichiers deviennent obsolètes ?

Ajoutez une règle dans le fichier racine : toute personne qui modifie du code dans un répertoire met à jour le fichier AGENTS.md de ce répertoire dans le même commit. Placer le fichier à côté du code rend cette règle plus facile à appliquer, car la modification apparaît alors dans la même diff de pull request qu’un humain est déjà en train de lire. Ajoutez un avertissement CI qui associe chaque chemin modifié au fichier AGENTS.md le plus proche dans son arborescence, puis comparez régulièrement git log -1 --format=%cs de chaque fichier avec la sortie de la même commande exécutée sur le répertoire qu’il documente.

Claude Code lit-il les fichiers AGENTS.md ?

Non. En août 2026, la documentation indique que « Claude Code lit CLAUDE.md, et non AGENTS.md ». Créez un fichier CLAUDE.md dans le même répertoire, avec @AGENTS.md sur la première ligne. Ce fichier charge le fichier partagé et vous permet d’ajouter ensuite des instructions propres à Claude. Un lien symbolique créé avec ln -s AGENTS.md CLAUDE.md fonctionne lorsqu’aucune instruction supplémentaire n’est nécessaire, mais Windows exige des droits d’administrateur ou le mode développeur. Exécutez /context dans une session et vérifiez que le fichier apparaît sous Fichiers de mémoire.

Où placer une règle qui ne s’applique que dans certains cas ?

Pas dans AGENTS.md. Ce fichier est chargé dans chaque session. Chaque ligne qu’il contient entre donc en concurrence avec la requête que vous avez réellement saisie. Une procédure en plusieurs étapes, nécessaire seulement à l’occasion, doit être placée dans une skill, qui est chargée à la demande. Une règle qui s’applique à un seul répertoire doit être placée dans le fichier AGENTS.md de ce répertoire. Un élément que l’agent peut lire directement dans le code, comme l’arborescence des répertoires ou la liste des dépendances, ne doit être placé ni dans l’un ni dans l’autre.