SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-26

Pourquoi votre agent de code ignore vos instructions

Votre fichier d’instructions dit d’arrêter, mais l’agent continue. Apprenez à distinguer contexte absent, règle vague, conflit et oubli après compaction.

Pourquoi les agents de programmation ignorent vos instructions

Les agents de programmation ignorent vos instructions pour quatre raisons, et aucune ne tient au fait que vous avez été trop poli. La règle n’a jamais été présente dans la fenêtre de contexte. La règle était trop vague pour permettre de vérifier une action par rapport à celle-ci. Un autre élément du contexte la contredisait, généralement le code que l’agent venait de lire. Ou bien la règle est toujours chargée, mais se trouve trop loin derrière dans le tour en cours, et l’agent s’appuie sur les éléments les plus proches.

Chaque cause a son propre correctif. La première étape consiste donc à les distinguer. Les majuscules et le mot IMPORTANT ne permettent pas d’établir un diagnostic. Les mécanismes décrits ci-dessous prennent Claude Code comme exemple, car son chargement des fichiers et son comportement lors de la compaction sont documentés en détail en août 2026. Les autres outils présentent des différences de détail, mais leur fonctionnement général est similaire.

Commençons par deux termes. La fenêtre de contexte est le bloc de texte que le modèle voit lors d’un tour donné : le system prompt, vos fichiers d’instructions, la conversation et chaque fichier lu par l’agent. Le harness est le programme qui entoure le modèle, celui qui lit les fichiers sur le disque et assemble ce bloc. Presque toutes les plaintes formulées dans cet article concernent en réalité le harness, et non le modèle.

Votre fichier d’instructions est un message, pas un paramètre

Un fichier d’instructions n’est pas une configuration. Rien, dans le runtime, ne lit CLAUDE.md et ne l’applique. Le harness lit le fichier sur le disque, puis colle son contenu dans la conversation. Dans Claude Code, ce contenu est transmis sous la forme d’un message utilisateur placé après le system prompt. Le modèle voit donc vos règles de la même manière que le reste de votre texte.

Cela entraîne une conséquence gênante. Vos règles sont en concurrence avec tous les autres textes présents dans la fenêtre, sur un pied d’égalité. Une règle est une affirmation. Le fichier que l’agent vient d’ouvrir est un élément de preuve. Lorsque les deux sont en désaccord, les éléments de preuve l’emportent souvent. Aucune erreur n’est alors signalée, car, du point de vue du modèle, rien ne s’est mal passé.

La documentation officielle l’indique clairement : les fichiers d’instructions sont traités comme du contexte, et non comme une configuration appliquée. Pour bloquer une action quelle que soit la décision du modèle, vous avez besoin d’un hook, pas d’une phrase. Retenez cette distinction. La plupart des corrections présentées à la fin de cet article consistent à appliquer cette distinction à un cas précis.

Quels fichiers d’instructions sont chargés, et quand

Claude Code remonte l’arborescence depuis le répertoire dans lequel vous l’avez lancé. Chaque fichier CLAUDE.md et CLAUDE.local.md situé entre la racine du système de fichiers et votre répertoire de travail est entièrement chargé au démarrage. Ces fichiers sont concaténés dans cet ordre. Le fichier le plus proche du répertoire depuis lequel vous avez lancé Claude Code est donc lu en dernier. Dans un même répertoire, le fichier .local est ajouté après le fichier principal.

Les fichiers situés dans les sous-répertoires sous votre répertoire de travail se comportent différemment. Ils ne sont pas chargés au démarrage. Ils le sont lorsque l’agent lit un fichier situé dans ce répertoire. Il en va de même pour les règles limitées à un chemin dans .claude/rules/ qui contiennent un champ de frontmatter paths: : elles sont ajoutées au contexte lorsqu’un fichier correspondant est lu, et non à chaque tour.

Cette différence explique une grande partie des échecs signalés. Vous placez une règle dans packages/api/CLAUDE.md, vous posez une question sur l’API et l’agent répond sans jamais ouvrir de fichier sous packages/api/. La règle n’a pas été ignorée. Elle n’était jamais présente dans le contexte. Si votre dépôt répartit les consignes dans des fichiers d’instructions par package dans un monorepo, c’est le premier point à vérifier, à chaque fois.

Il existe un autre piège lié au chargement. C’est la cause la plus fréquente du message « l’agent a ignoré mes instructions » : Claude Code lit CLAUDE.md, et non AGENTS.md. Un dépôt standardisé sur AGENTS.md, sans fichier CLAUDE.md, ne fournit donc aucun fichier que Claude Code puisse charger. Le mécanisme pris en charge consiste à utiliser un fichier CLAUDE.md dont la première ligne est @AGENTS.md. Cette ligne importe le fichier au démarrage. Vous pouvez ajouter dessous des notes spécifiques à Claude. Un lien symbolique convient également si vous n’avez rien d’autre à ajouter. Déterminer ce qui doit figurer dans ce fichier est une question distincte, traitée dans la séparation des instructions pour l’agent et de la documentation destinée aux utilisateurs.

Confirmez le chargement du fichier avant de le réécrire

Ne modifiez pas le texte avant d’avoir la preuve que l’agent peut voir le fichier. Deux vérifications sont possibles. Commencez par la plus simple.

Exécutez /context dans la session. Cette commande affiche la fenêtre courante par catégorie, et la liste Memory files indique le nom de chaque fichier d’instructions effectivement chargé. Si un fichier n’apparaît pas dans cette liste, il ne fait pas partie de la conversation. Rien de ce que vous écrivez à l’intérieur ne peut donc être pris en compte. /memory répertorie les emplacements des fichiers et les ouvre pour modification, y compris ceux qui n’existent pas encore.

Pour obtenir une réponse plus précise, journalisez les chargements. L’événement hook InstructionsLoaded se déclenche chaque fois qu’un CLAUDE.md ou qu’un fichier de règles est ajouté au contexte. Son matcher indique la raison du chargement : session_start, nested_traversal, path_glob_match, include ou compact. Placez ceci dans .claude/settings.json :

{
  "hooks": {
    "InstructionsLoaded": [
      {
        "matcher": "nested_traversal",
        "hooks": [
          {
            "type": "command",
            "command": "cat >> /tmp/instructions-loaded.log"
          }
        ]
      }
    ]
  }
}

Le hook reçoit sa charge utile au format JSON sur l’entrée standard. cat ajoute donc l’enregistrement complet. Surveillez-le avec tail -f /tmp/instructions-loaded.log pendant votre travail. Le code de sortie de cet événement est ignoré. Le hook peut donc uniquement observer, sans bloquer. Si votre fichier imbriqué n’apparaît jamais dans ce journal au cours d’une session où vous vous attendiez à son chargement, arrêtez de reformuler le texte. Le problème vient de son emplacement.

L’effet d’une longue session sur vos règles

Deux effets distincts s’appliquent ici et nécessitent des réponses différentes.

Distance. Une règle énoncée au tour 1 se trouve encore dans la fenêtre au tour 90, mais elle est désormais en concurrence avec 90 tours de texte plus récent et plus spécifique à la tâche en cours. Vous ne pouvez pas supprimer cet effet par la configuration, mais vous pouvez le mesurer. Exécutez la même tâche dans une nouvelle session. Si la règle est respectée dans cette session, mais cesse de l’être au cours d’une longue session, la distance est en cause.

Compactage. Lorsque la fenêtre est pleine, le harness résume la conversation jusque-là, puis reprend à partir de ce résumé. Les éléments conservés sont ceux que le résumeur a jugés importants, ce qui ne correspond pas nécessairement à ce que vous considérez comme important. Claude Code documente le résultat pour chaque mécanisme, et les différences sont importantes. Le répertoire racine du projet CLAUDE.md et les règles sans portée sont réinjectés depuis le disque après un compactage. L’auto-mémoire est réinjectée depuis le disque. Les règles dont le frontmatter contient paths: sont perdues jusqu’à la nouvelle lecture d’un fichier correspondant. Les fichiers CLAUDE.md imbriqués dans des sous-répertoires sont perdus jusqu’à la lecture d’un fichier situé dans ce sous-répertoire.

Classez vos instructions selon ce tableau : l’ordre de fragilité apparaît immédiatement. Une règle saisie uniquement dans le chat est l’élément le plus fragile de la session : elle ne persiste que si le résumé l’a conservée. Une règle dans packages/api/CLAUDE.md vient ensuite, car elle a été chargée une fois, supprimée par le résumé, puis ne réapparaît qu’à la prochaine lecture dans ce répertoire. Une règle dans le fichier racine du projet est la plus durable, car elle est relue depuis le disque à chaque fois.

Si une instruction doit s’appliquer pendant toute la session, placez-la dans le fichier racine du projet, sans frontmatter paths:. Pour le reste, choisissez volontairement le compromis approprié. Gérer les éléments conservés dans la fenêtre de contexte couvre /compact avec un argument de focus et /clear entre des tâches sans rapport, deux facteurs qui modifient la fréquence à laquelle le résumeur peut décider du contenu de vos règles.

Pourquoi le code environnant l’emporte sur la règle

C’est l’échec le plus souvent décrit et le moins souvent diagnostiqué. Votre fichier indique que l’accès à la base de données doit passer par la couche repository. L’agent écrit un handler qui appelle directement l’ORM (object relational mapper). Il n’a pas ignoré votre consigne pour des raisons de style. Les éléments concrets l’ont emporté.

Une règle décrit une préférence. Le code en démontre une. Lorsque l’agent ouvre trois fichiers du module qu’il va modifier et que les trois appellent directement l’ORM, le contexte contient d’un côté une phrase abstraite et, de l’autre, trois exemples concrets, récents et adaptés à la tâche. Reproduire le pattern local est généralement le bon comportement. C’est incorrect ici uniquement parce que vous savez quelque chose que le contexte ignore : ces fichiers sont du code legacy.

Indiquez-le donc dans la règle. Les règles qui mentionnent leur propre contre-évidence résistent mieux à l’utilisation dans un repository réel. Celles qui énoncent une simple préférence ne le font pas.

Tout nouvel accès à la base de données passe par app/repositories/. Les fichiers sous app/legacy/ appellent encore directement l’ORM. Il s’agit d’ancien code, pas du pattern à suivre. Ne le copiez pas.

La deuxième phrase fait le travail. Elle indique à l’agent ce qu’il va trouver et comment l’interpréter, avant qu’il ne le trouve. La même correction s’applique à toute règle que votre repository contredit manifestement : un style de commit que votre historique ne suit pas, une organisation des tests ignorée par la moitié de votre suite, une convention d’import appliquée uniquement au nouveau code. Lorsque le code contredit le fichier, indiquez cette contradiction dans le fichier.

Une règle vague ne peut pas être vérifiée et ne peut donc pas être appliquée

« Écrivez du code propre. » « N’en faites pas trop. » « Restez simple. » « Soyez prudent avec les migrations. » Aucune de ces règles ne peut être vérifiée à partir d’une action précise, ni par l’agent ni par vous. Un agent qui reçoit une règle qu’il ne peut pas vérifier sur sa propre sortie devine, et vous évaluez cette supposition au ressenti.

Voici le test à appliquer à chaque ligne de votre fichier. Écrivez la commande shell qui se terminerait avec un code différent de zéro si la règle était enfreinte. Si vous ne pouvez pas écrire cette commande, la règle n’est pas vérifiable. Comparez ces paires :

  • Non vérifiable : « Gardez les fonctions courtes. » Vérifiable : « Toute fonction de plus de 60 lignes doit être précédée d’un commentaire expliquant pourquoi. »
  • Non vérifiable : « Testez vos modifications. » Vérifiable : « Exécutez npm test et indiquez le nombre d’échecs avant de considérer la tâche comme terminée. »
  • Non vérifiable : « Gardez les fichiers organisés. » Vérifiable : « Les gestionnaires HTTP se trouvent dans src/api/handlers/. Aucun autre élément ne doit se trouver dans ce répertoire. »
  • Non vérifiable : « Formatez correctement le code. » Vérifiable : « Utilisez une indentation de 2 espaces dans les fichiers .ts. »

« N’en faites pas trop » est la règle à laquelle les utilisateurs renoncent en premier, car sa correction ne consiste pas à raccourcir la phrase, mais à la rendre plus longue : préciser ce que signifie concrètement la plus petite modification fonctionnelle donne à l’agent des critères auxquels il peut comparer son propre diff.

La taille pose le même problème sous une autre forme. Les recommandations de Claude Code ciblent moins de 200 lignes par fichier d’instructions et indiquent directement que les fichiers plus longs réduisent le respect des consignes. Un fichier de 700 lignes ne contient pas des instructions plus fermes. Il contient 700 affirmations qui risquent davantage de se contredire, et il est comptabilisé dans votre fenêtre à chaque tour, ce qui se reflète directement dans votre utilisation des tokens. Structurer le fichier afin que chaque règle figure sous un titre qu’un lecteur peut parcourir rapidement est traité dans la rédaction d’un fichier d’instructions que l’agent peut appliquer. Mieux encore, supprimez les parties qui décrivent au lieu de donner des instructions : une présentation des répertoires indiquant où se trouvent les gestionnaires et les modèles est une structure que l’agent peut consulter à la demande dans une carte analysée du dépôt au lieu de la conserver dans la fenêtre à chaque tour.

Comment diagnostiquer le problème en dix minutes

Exécutez ces commandes dans l’ordre. Passer directement à la dernière étape conduit souvent à accumuler un long fichier de règles formulées de manière impérative, sans pour autant résoudre le problème.

  1. Vérifiez que le fichier a été chargé. Exécutez /context et consultez la liste Memory files. Si le fichier n’y figure pas, corrigez son emplacement et arrêtez-vous là. Le reste de cette liste ne s’applique pas encore.
  2. Reproduisez le problème dans une nouvelle session. Démarrez une nouvelle session et donnez la tâche la plus simple qui devrait déclencher la règle. Si la règle fonctionne ici mais échoue dans une session longue, le problème vient probablement de la distance ou de la compaction. Si elle échoue aussi ici, le problème vient de la règle elle-même.
  3. Supprimez la concurrence. Demandez la même modification dans un répertoire dont le code existant respecte déjà la règle. Si le respect de la règle revient, le code environnant prenait le dessus sur votre formulation.
  4. Recherchez un conflit. Deux fichiers qui donnent des consignes différentes pour le même comportement constituent un échec documenté : le modèle peut en choisir un arbitrairement, sans vous indiquer qu’il l’a fait.
  5. Rendez la règle vérifiable, puis testez-la de nouveau. Réécrivez la règle avec un chemin concret et une condition. Une forte amélioration du respect de la règle indique que le problème venait de sa formulation.

L’étape 4 tient en une commande. Recherchez le sujet dans toutes les sources d’instructions, et pas seulement dans le fichier que vous étiez en train de modifier :

grep -rni "migration" --include="CLAUDE.md" --include="CLAUDE.local.md" .
grep -rni "migration" .claude/rules/ ~/.claude/CLAUDE.md ~/.claude/rules/ 2>/dev/null

Si deux fichiers contiennent des consignes différentes, vous avez trouvé le problème. Supprimez-en une. N’essayez pas de les hiérarchiser avec une formulation plus forte : aucun moteur de classement ne permet de le faire.

Les correctifs, par ordre d’efficacité

Chaque étape ci-dessous a plus d’effet que la précédente, mais demande davantage de travail de mise en place. Commencez en haut lorsqu’une règle est facile à reformuler. Descendez dès qu’une règle est suffisamment importante pour que des oublis occasionnels ne soient plus acceptables.

  1. Rendez la règle concrète. Indiquez un chemin, une commande ou une condition. Ajoutez les éléments contraires que l’agent trouvera dans le dépôt, comme indiqué précédemment. Cette méthode ne coûte rien et corrige un nombre étonnamment élevé de cas.
  2. Rapprochez-la de ce qu’elle régit. Utilisez un CLAUDE.md imbriqué, une règle limitée à un chemin dans .claude/rules/ ou un commentaire en tête du fichier lui-même. La règle est alors lue en même temps que le code auquel elle s’applique. Acceptez le compromis : tout ce qui est chargé de cette manière disparaît lors de la prochaine compaction et revient à la prochaine lecture correspondante.
  3. Déplacez l’application de la règle dans un hook. La prose demande. Un hook décide. Les hooks s’exécutent comme du code lors d’événements fixes du cycle de vie et s’appliquent quel que soit le résultat auquel le modèle aboutit.
  4. Confiez la règle à un outil déterministe et supprimez la prose. Formatage, ordre des imports, longueur des lignes, imports interdits, format des messages de commit. ruff format, prettier --write, eslint, un hook pre-commit. Le formatter donne toujours le bon résultat et ne coûte aucun token. La phrase est correcte la plupart du temps et consomme des tokens à chaque tour.

Étape 3 en détail. Supposons que les fichiers de migration ne doivent jamais être modifiés par l’agent. Ajoutez ceci dans .claude/settings.json :

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-migrations.sh"
          }
        ]
      }
    ]
  }
}

Et ceci dans .claude/hooks/guard-migrations.sh :

#!/usr/bin/env bash
set -euo pipefail

path=$(jq -r '.tool_input.file_path // empty')

case "$path" in
  */migrations/*)
    echo "Files under migrations/ are written by hand. Stop and ask first." >&2
    exit 2
    ;;
esac

exit 0

Exécutez chmod +x .claude/hooks/guard-migrations.sh, puis démarrez une nouvelle session et demandez à l’agent de modifier un fichier sous migrations/. La modification est refusée et votre message lui est renvoyé comme motif. Le code de sortie 2 de PreToolUse bloque l’appel de l’outil avant son exécution, et votre texte stderr est transmis au modèle comme message de blocage. ${CLAUDE_PROJECT_DIR} correspond à la racine du projet. Le hook fonctionne donc quel que soit le répertoire courant de l’agent. L’agent n’a pas besoin d’être d’accord avec la règle, de s’en souvenir ni de l’avoir encore dans son contexte. La modification n’a pas lieu.

Pour une interdiction simple qui ne contient aucune logique, permissions.deny dans vos paramètres remplit le même rôle sans script à maintenir. Les modes d’autorisation déterminent ce qui s’exécute sans vous le demander au préalable. Si une instruction doit réellement se trouver au niveau du system prompt plutôt que dans un message utilisateur, --append-system-prompt l’y place. Elle doit toutefois être transmise à chaque invocation, ce qui convient mieux aux scripts qu’au travail interactif.

Ce que vous ne pouvez pas imposer par des instructions

Soyez clair sur la partie qui vous revient. L’emplacement, la formulation, les conflits entre fichiers et la taille du fichier relèvent de l’auteur, qui doit les corriger. Le reste relève du comportement du modèle, et une meilleure formulation ne le supprimera pas.

L’accord n’est pas l’obéissance. Un agent peut reconnaître une règle, vous la reformuler correctement, puis l’enfreindre deux appels d’outil plus tard. Cette reconnaissance ne coûte rien et ne permet aucune prédiction. Ne la considérez pas comme une correction et ne la comptez pas comme un test.

Certaines habitudes persistent. Ajouter des commentaires, ajouter une gestion défensive des erreurs, rédiger un récapitulatif final, exécuter la commande évidente suivante. Ces comportements réapparaissent lorsqu’une règle les interdit, mais moins souvent, et non jamais. Vous pouvez mesurer votre propre taux : exécutez la même tâche dix fois dans de nouvelles sessions et comptez les infractions. Lorsque ce nombre doit être égal à zéro, la règle doit sortir du prompt. Déclarer une tâche terminée alors qu’une partie reste inachevée relève de la même habitude. La correction doit être structurelle et non verbale : la compétence unlazy remplace la phrase par un arbre de profondeur et des fichiers de contrôle que l’agent doit valider avant de pouvoir déclarer la tâche terminée.

Votre session devient elle-même un exemple. Si l’agent a enfreint la règle au tour 12 et que vous avez laissé passer cette infraction, elle figure désormais dans le contexte comme démonstration, et elle est bien plus récente que la règle. Corrigez une infraction dès que vous la voyez. Une infraction non corrigée influence le reste de la session.

Un fichier d’instructions n’est pas une frontière de sécurité. Il oriente le comportement, mais ne l’impose pas. Tout ce dont l’échec coûte cher, comme les identifiants ou les commandes destructrices, doit relever des permissions ou d’un hook. Garder les secrets hors de portée d’un agent applique le même principe aux données : ne demandez pas à un agent de ne pas lire un fichier ; faites en sorte que le fichier ne soit pas lisible.

En bref : vérifiez que le fichier a été chargé, rendez la règle vérifiable, placez-la à côté de l’élément qu’elle régit et, lorsque le taux d’échec reste important, sortez-la de la prose. Une règle qu’un agent ne peut pas ignorer est une règle qui ne lui a jamais été demandée.

FAQ

Pourquoi Claude Code ignore-t-il mon fichier CLAUDE.md ?

Vérifiez d’abord qu’il a été chargé avant de conclure qu’il a été ignoré. Exécutez /context et consultez la liste Memory files ; un fichier qui n’y figure pas ne fait pas partie de la conversation. Les fichiers d’instructions sont transmis dans un message utilisateur après le prompt système. Ils sont donc traités comme du contexte et non comme une configuration imposée. Il n’y a aucune garantie stricte de respect. Dans la plupart des cas, l’une de ces quatre situations se présente : le fichier se trouve dans un sous-répertoire que l’agent n’a jamais lu, deux fichiers se contredisent et le modèle en a choisi un arbitrairement, la règle est trop vague pour permettre de vérifier une action, ou le code environnant montre l’inverse de ce que dit la règle.

La modification du fichier d’instructions pendant la session change-t-elle quelque chose ?

Pas pour la copie déjà présente dans la conversation. Les fichiers situés au-dessus de votre répertoire de travail sont entièrement chargés au démarrage. Le texte conservé par le modèle est donc celui qui était présent au lancement. Pour prendre en compte une modification, démarrez une nouvelle session ou demandez à l’agent de lire le fichier avec ses outils de gestion de fichiers habituels. La version actuelle sera alors ajoutée à la conversation dans un nouveau message. Après une compaction, le fichier racine du projet est relu depuis le disque. La nouvelle version est donc également chargée à ce moment-là.

Quel fichier est prioritaire lorsqu’un CLAUDE.md racine et un fichier imbriqué sont contradictoires ?

Aucun de manière fiable. Les fichiers détectés sont concaténés dans le contexte au lieu de se remplacer les uns les autres. Ils sont ordonnés de la racine du système de fichiers jusqu’à votre répertoire de travail. Le fichier le plus proche est donc simplement lu en dernier. Il n’existe aucun moteur de priorité pour résoudre les contradictions. La documentation de Claude Code indique que les règles contradictoires peuvent être résolues arbitrairement. Rédigez les fichiers imbriqués comme des ajouts qui indiquent le chemin auquel ils s’appliquent, et supprimez la contradiction au lieu d’essayer de lui donner la priorité.

Mes instructions sont-elles conservées après /compact ?

Cela dépend de la manière dont elles ont été chargées. Le fichier racine du projet CLAUDE.md, les règles sans périmètre et la mémoire automatique sont réinjectés depuis le disque après une compaction. Les règles avec des métadonnées frontmatter paths: et les fichiers CLAUDE.md imbriqués dans des sous-répertoires sont perdus jusqu’à ce qu’un fichier correspondant soit de nouveau lu. Tout ce que vous avez uniquement saisi dans le chat est conservé seulement si le résumeur l’a inclus. Si une règle doit s’appliquer pendant toute la session, placez-la dans le fichier racine du projet, sans métadonnées frontmatter paths:.

Quand une règle doit-elle devenir un hook plutôt que rester une instruction en prose ?

Lorsqu’il est possible de vérifier la règle de manière déterministe et que le coût d’un oubli est supérieur à celui de l’écriture d’un petit script. Les restrictions sur les chemins de fichiers, les commandes obligatoires avant un commit et les appels d’outils interdits sont de bons exemples. Un hook PreToolUse qui se termine avec le code d’état 2 bloque directement l’appel de l’outil et transmet son texte stderr au modèle comme explication. La règle s’applique donc même si elle ne figure plus dans le contexte. Tout ce qu’un formatter ou un linter peut décider doit être géré par cet outil, puis supprimé entièrement du fichier d’instructions.