SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-26

コーディングエージェントが指示を無視する4つの理由

命令ファイルに「停止」と書いても無視される理由を解説します。Claude Codeの2026年8月時点の仕様をもとに、ルール未読、曖昧さ、矛盾、コンテキストの距離を切り分ける診断方法を紹介します。

コーディングエージェントが指示を無視する理由

コーディングエージェントが指示を無視する理由は4つあります。丁寧すぎたことが原因ではありません。ルールがそもそもコンテキストウィンドウに含まれていなかった可能性があります。ルールが曖昧で、行動と照合できなかった可能性もあります。コンテキスト内の別の内容、通常はエージェントが直前に読んだコードが、ルールと矛盾していた可能性もあります。また、ルールは読み込まれていても現在のターンから遠く、エージェントが近くにある内容を基に処理している可能性があります。

原因ごとに対処法は異なります。そのため、最初に原因を見分ける必要があります。大文字や IMPORTANT という語を使っても、原因の特定にはなりません。以下では、具体例として Claude Code を使用します。2026年8月時点では、その読み込みとコンパクションの動作が詳しく文書化されているためです。ほかのツールは細部が異なりますが、全体としては同じように動作します。

まず、2つの用語を確認します。コンテキストウィンドウとは、特定のターンでモデルが参照するテキストのまとまりです。system prompt、指示ファイル、会話、エージェントが読み込んだすべてのファイルが含まれます。ハーネスとは、モデルの周囲で動作するプログラムです。ディスク上のファイルを読み込み、そのまとまりを組み立てます。この投稿にある不満のほとんどは、実際にはモデルではなくハーネスに対する不満です。

命令ファイルは設定ではなくメッセージです

命令ファイルは設定ではありません。ランタイムが CLAUDE.md を読み取り、強制適用することはありません。ハーネスはディスク上のファイルを読み込み、そのテキストを会話に貼り付けます。Claude Code では、その内容は system prompt の後に置かれる user message として渡されます。つまり、モデルには、入力した他のテキストと同じようにルールが表示されます。

ここから不都合な結果が生じます。ルールは、ウィンドウ内の他のすべてのテキストと同じ土俵で競合します。ルールは主張です。エージェントが直前に開いたファイルは証拠です。この2つが食い違うと、証拠が優先されることがよくあります。その場合もエラーは発生しません。モデルから見ると、問題は何も起きていないためです。

公式ドキュメントにも明記されています。命令ファイルは、強制される設定ではなくコンテキストとして扱われます。モデルの判断に関係なく操作をブロックするには、文ではなく hook が必要です。この点を覚えておいてください。この記事の最後に示す修正の多くは、この原則を特定のケースに適用したものです。

読み込まれる指示ファイルと、そのタイミング

Claude Code は、起動したディレクトリからディレクトリツリーを上方向にたどります。ファイルシステムのルートから作業ディレクトリまでにあるすべての CLAUDE.md と CLAUDE.local.md は、起動時に完全に読み込まれます。これらはその順序で連結されるため、起動元に最も近いファイルが最後に読み込まれます。また、同じディレクトリ内では .local ファイルがメインのファイルの後に追加されます。

作業ディレクトリより下のサブディレクトリにあるファイルは、動作が異なります。起動時には読み込まれません。エージェントがそのディレクトリ内のファイルを読み込んだ時点で読み込まれます。.claude/rules/ にある paths: frontmatter フィールド付きのパススコープルールも同じです。すべてのターンで読み込まれるのではなく、条件に一致するファイルが読み込まれた時点でコンテキストに追加されます。

この違いだけで、報告される問題の多くを説明できます。packages/api/CLAUDE.md にルールを記述し、API について質問したところ、エージェントが packages/api/ 配下のファイルを一度も開かずに回答したとします。ルールが無視されたのではありません。最初から存在していなかったのです。モノレポでパッケージごとに指示ファイルを分ける構成では、毎回まずここを確認してください。

もう1つ、読み込みに関する落とし穴があります。これは「エージェントが指示を無視した」とされる原因として最も一般的です。Claude Code が読み込むのは CLAUDE.md であり、AGENTS.md ではありません。AGENTS.md を標準にしていて CLAUDE.md がないリポジトリでは、Claude Code が読み込めるものは何もありません。サポートされている橋渡し方法は、1行目が @AGENTS.md になっている CLAUDE.md です。これにより、ファイルが起動時に読み込まれ、その下に Claude 固有の補足を記述できます。追加する内容がない場合は、シンボリックリンクでも構いません。そもそもそのファイルに何を記述するかは別の問題であり、エージェント向け指示と人間向けドキュメントの分離で説明します。

書き換える前にファイルが読み込まれたことを確認する

エージェントがファイルを参照できるという証拠を得るまで、文言を変更しないでください。確認方法は2つあります。まず、簡単な方法から試します。

セッション内で /context を実行します。現在のウィンドウの内容がカテゴリ別に表示され、Memory files リストには実際に読み込まれたすべての指示ファイルが示されます。このリストにないファイルは会話に含まれていないため、そのファイル内に何を書いても反映されません。/memory ではファイルの場所が一覧表示され、まだ存在しないファイルも含めて編集用に開けます。

より確実に確認するには、読み込みをログに記録します。InstructionsLoaded フックイベントは、CLAUDE.md またはルールファイルがコンテキストに入るたびに実行されます。matcher には、読み込みが発生した理由として session_start、nested_traversal、path_glob_match、include、compact のいずれかが示されます。次の内容を .claude/settings.json に配置します。

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

フックは標準入力から JSON としてペイロードを受け取るため、cat でレコード全体を追記できます。作業中は tail -f /tmp/instructions-loaded.log で監視します。このイベントの終了ステータスは無視されるため、フックにできるのは監視だけで、処理をブロックすることはできません。読み込みを想定していたセッション中に、入れ子にしたファイルがそのログに一度も現れない場合は、文言の修正を中止してください。原因は配置です。

長時間のセッションがルールに与える影響

ここでは、別々の影響が2つあります。それぞれに異なる対応が必要です。

距離。 turn 1 で示したルールは turn 90 でもコンテキストウィンドウ内に残っています。ただし、より新しく、現在の作業により具体的な90ターン分のテキストと競合する状態になります。これを設定で解消することはできませんが、測定は可能です。新しいセッションで同じタスクを実行してください。新しいセッションではルールが適用され、長時間のセッションの後半で適用されない場合、原因は距離です。

コンパクション。 ウィンドウがいっぱいになると、ハーネスはそれまでの会話を要約し、その要約を基に処理を続けます。残る内容は、要約作成側が重要と判断したものです。これは、あなたが重要と考える内容とは一致しません。Claude Code では、仕組みごとの結果が文書化されており、その違いは大きくなります。プロジェクトルート CLAUDE.md とスコープ指定のないルールは、コンパクション後にディスクから再注入されます。自動メモリもディスクから再注入されます。paths: フロントマターを持つルールは、対応するファイルが再度読み込まれるまで失われます。サブディレクトリ内の入れ子になった CLAUDE.md ファイルは、そのサブディレクトリ内のファイルが再度読み込まれるまで失われます。

この表に従って指示を順位付けすると、壊れやすさの順序が明確になります。チャットに入力しただけのルールは、セッション内で最も壊れやすいものです。要約にたまたま残った場合にだけ維持されます。packages/api/CLAUDE.md 内のルールは次に壊れやすいものです。1度読み込まれた後に要約で失われ、そのディレクトリで次に読み込みが行われたときだけ戻ります。プロジェクトルートのファイルに記述したルールは、毎回ディスクから再読み込みされるため、最も確実に維持されます。

したがって、セッション全体で適用する必要がある指示は、paths: フロントマターを付けずにプロジェクトルートのファイルへ記述してください。それ以外は、目的に応じて意識的に選択する必要があります。コンテキストウィンドウに残す内容の管理では、フォーカス引数を使用する /compact と、無関係なタスク間での /clear を扱っています。どちらも、要約作成側がルールの内容を判断する頻度を変えます。

周辺のコードがルールに勝る理由

これは、最も頻繁に説明される一方で、原因の特定が最も少ない失敗です。ファイルには、データベースアクセスはリポジトリ層を経由すると書かれています。しかし、エージェントは ORM(オブジェクトリレーショナルマッパー)を直接呼び出すハンドラーを作成します。これは、スタイル上の理由で指示を無視したのではありません。根拠の強さで負けたのです。

ルールは、望ましい方針を示します。コードは、その方針の実例を示します。エージェントが編集対象のモジュールで 3 つのファイルを開き、そのすべてが ORM を直接呼び出している場合、コンテキストの一方には抽象的な文が 1 つあり、もう一方には具体的で新しく、今回のタスクに合った例が 3 つあります。通常、ローカルのパターンをコピーするのが正しい動作です。ただし、ここでは誤りになります。あなたはコンテキストにない情報を知っているからです。そのファイルはレガシーコードです。

そのため、その情報をルールに書き込みます。反証となるコードを自分で明示するルールは、実際のリポジトリでも機能します。単なる好みを述べるだけのルールは機能しません。

新しいデータベースアクセスは app/repositories/ を経由します。app/legacy/ 配下のファイルは、現在も ORM を直接呼び出しています。これは古いコードであり、標準パターンではありません。コピーしないでください。

効果を生むのは 2 文目です。エージェントがそのコードを見つける前に、何を見つけることになるのか、そしてそれをどう解釈すべきかを伝えています。同じ修正は、リポジトリが目に見える形で矛盾しているあらゆるルールに適用できます。たとえば、履歴に従っていないコミット形式、テストスイートの半分が無視しているテスト配置、新しいコードでしか守られていない import 規約などです。コードとファイルの内容が食い違う場合は、その食い違いをファイルに明記してください。

確認できない曖昧なルールは、従うこともできません

「クリーンなコードを書く」「過剰に設計しない」「シンプルに保つ」「マイグレーションには注意する」。これらは、エージェントもあなたも、特定の操作に対して検証できません。自分の出力に照らして確認できないルールを与えられたエージェントは推測するしかなく、あなたはその推測を感覚で評価することになります。

ファイル内のすべての行に、次のテストを適用してください。ルールに違反したときに終了ステータスが 0 以外になる shell コマンドを書きます。そのコマンドを書けないなら、そのルールは検証可能ではありません。次の組み合わせを比較してください。

  • 検証不可: 「関数を小さく保つ」 検証可能: 「60 行を超える関数の上には、その長さが必要な理由を説明するコメントを置く」
  • 検証不可: 「変更をテストする」 検証可能: 「タスクを完了とする前に npm test を実行し、失敗数を貼り付ける」
  • 検証不可: 「ファイルを整理して保つ」 検証可能: 「HTTP ハンドラーは src/api/handlers/ に置く。それ以外のものはそのディレクトリに置かない」
  • 検証不可: 「コードを適切にフォーマットする」 検証可能: 「.ts ファイルでは 2 スペースのインデントを使用する」

「過剰に設計しない」は、最初に諦められやすいルールです。修正方法は短い文にすることではなく、長い文にすることだからです。実際に機能する最小の変更が何を意味するのかを明記することで、エージェントが自分の差分と照合できる基準を与えられます。

サイズも、別の形で同じ問題になります。Claude Code のガイダンスでは、1 つの指示ファイルを 200 行未満にすることを目標とし、ファイルが長いほど指示への準拠率が下がると明記しています。700 行のファイルは、より強い指示ではありません。互いに矛盾する可能性が高い主張が 700 行並んでいるだけです。しかも、すべてのターンでウィンドウの容量を消費するため、トークン使用量に直接現れます。各ルールを読者が確認しやすい見出しの下に配置する方法については、エージェントが実行できる指示ファイルの書き方で説明しています。さらに良い方法は、指示ではなく説明になっている部分を削ることです。ハンドラーやモデルの場所を列挙するディレクトリ案内は、毎回ウィンドウに保持するのではなく、解析済みのリポジトリマップからエージェントが必要なときに参照できる構造です。

10分で診断する方法

次の手順を順番に実行します。最後の手順にいきなり進むと、強い表現のルールを長いファイルに追加しても、動作しないままになることがあります。

  1. 読み込まれていることを確認します。 /context を実行し、Memory files の一覧を確認します。ファイルがなければ、場所を修正して停止します。この一覧の他の手順は、まだ適用できません。
  2. 新しいセッションで再現します。 新しいセッションを開始し、ルールが適用されるはずの最小限のタスクを実行します。ここでは適用されるのに、長いセッションでは失敗する場合、距離または圧縮が原因です。ここでも失敗する場合は、ルール自体に問題があります。
  3. 競合する要因を取り除きます。 既存のコードがそのルールに従っているディレクトリで、同じ変更を依頼します。遵守されるようになった場合は、周囲のコードがルールの文より強く影響していました。
  4. 競合を検索します。 同じ動作について異なる指示を出す2つのファイルがあると、既知の失敗が発生します。モデルはどちらかを任意に選ぶ可能性があり、そのことを通知しません。
  5. 確認可能にして再テストします。 具体的なパスと条件を含むようにルールを書き換えます。遵守率が大きく向上した場合は、表現が原因でした。

手順4では1つのコマンドを実行します。編集していたファイルだけでなく、すべての指示ソースから対象のトピックを検索します。

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

異なる内容を示すファイルが2つ見つかった場合、それが問題です。片方を削除します。より強い表現で優先順位を付けようとしてはいけません。優先順位を判定する仕組みはありません。

効果の大きい修正から順に

以下の各手順は、1 つ上の手順より効果が大きく、設定にもコストがかかります。ルールの文言を簡単に変更できる場合は、上から始めてください。たまに見落とされるだけでも許容できないほど重要になった時点で、下の手順へ進みます。

  1. ルールを具体化する。 パス、コマンド、または条件を明示します。前述のように、エージェントがリポジトリ内で見つける反証も追加します。コストはかからず、驚くほど多くのケースを解決できます。
  2. ルールを適用対象の近くへ移す。 ネストした CLAUDE.md、.claude/rules/ 内でパスを対象にしたルール、またはファイル自体の先頭に置くコメントなどです。これにより、ルールは適用対象のコードと同じ読み取りで渡されます。ただし、次のコンパクションでその方法により読み込まれた内容が外れ、次に一致する読み取りで再び渡される点に注意してください。
  3. 適用をフックへ移す。 文章は要求するだけですが、フックは判断します。フックはライフサイクル上の固定イベントでコードとして実行され、モデルの判断に関係なく適用されます。
  4. ルールを決定的なツールに任せ、文章を削除する。 フォーマット、import の順序、行の長さ、禁止された import、コミットメッセージの形式などです。ruff format、prettier --write、eslint、pre-commit フックを使用します。フォーマッタは常に正しく、トークンも消費しません。文章はほとんどの場合は正しいものの、ターンごとにトークンを消費します。

ステップ 3 の全体像を示します。エージェントが migration ファイルを決して編集してはならないとします。.claude/settings.json に次の内容を記述します。

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

そして .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

chmod +x .claude/hooks/guard-migrations.sh を実行してから、新しいセッションを開始し、migrations/ 配下のファイルを編集するようエージェントに依頼します。編集は拒否され、その理由としてメッセージが返されます。PreToolUse の終了ステータス 2 により、ツール呼び出しは実行前にブロックされます。また、標準エラー出力のテキストがブロック理由としてモデルに渡されます。${CLAUDE_PROJECT_DIR} はプロジェクトルートに解決されるため、エージェントがどのディレクトリにいてもフックは機能します。エージェントがルールに同意したり、ルールを記憶したり、コンテキスト内にルールを保持したりする必要はありません。編集は実行されません。

ロジックを含まない単純な禁止であれば、設定内の permissions.deny でも、保守するスクリプトなしで同じことができます。また、権限モードにより、事前の確認なしで実行される処理が決まります。指示をユーザーメッセージではなくシステムプロンプトのレベルに置く必要が本当にある場合は、--append-system-prompt で指定できます。ただし、呼び出しのたびに渡す必要があるため、対話的な作業よりもスクリプトに適しています。

指示だけではなくせないこと

この問題のうち、どこまでが自分の責任かを明確にしてください。配置、表現、ファイル間の競合、ファイルサイズは作成者の問題であり、作成者が修正するものです。それ以外はモデルの挙動に関する問題で、表現を改善してもなくなりません。

同意は遵守ではありません。 エージェントはルールを認め、正しく言い直したうえで、2 回後のツール呼び出しで破ることがあります。同意にはコストがなく、予測材料にもなりません。修正と見なさず、テスト結果にも数えないでください。

一部の習慣は残り続けます。 コメントを追加する、防御的なエラーハンドリングを書く、最後に要約する、次に行うべき明らかなコマンドを実行する、といった習慣です。これらは、禁止するルールがあっても、発生率が下がるだけでゼロにはなりません。同じタスクを新しいセッションで 10 回実行し、違反数を数えれば、自分の発生率を測定できます。その数をゼロにする必要がある場合、そのルールをプロンプトから外す必要があります。作業の一部がまだ終わっていないのに完了と判断するのも、同じ種類の習慣です。修正方法は文言ではなく構造にあります。unlazy skill はその一文を Depth Tree に置き換え、完了を主張する前にエージェントが通過する必要のある gate file を設けます。

自分のセッション自体が実例になります。 エージェントが turn 12 でルールを破り、それを見逃した場合、その違反はコンテキストに実例として残ります。しかも、ルールよりはるかに新しい情報です。違反を見つけたら、その場で訂正してください。訂正されなかった違反は、セッションの残りの部分に教訓として伝わります。

指示ファイルはセキュリティ境界ではありません。 指示ファイルは挙動を方向付けるだけで、強制はしません。認証情報や破壊的なコマンドなど、失敗時の影響が大きいものは、権限または hook で制御してください。エージェントの手の届かない場所に Secret を置くという原則は、データにも同じように適用されます。エージェントにファイルを読まないよう求めるのではなく、そのファイルを読み取れない状態にしてください。

要点は簡単です。ファイルが読み込まれたことを確認し、ルールを検証可能にし、対象のすぐ近くに配置してください。それでも違反率が問題になる場合は、ルールを文章から外してください。エージェントが無視できないルールは、最初からエージェントに求めるルールではありません。

FAQ

Claude Code が CLAUDE.md を無視するのはなぜですか?

無視されたと判断する前に、読み込まれているか確認してください。/context を実行し、Memory files の一覧を確認します。そこに記載されていないファイルは、会話に含まれていません。命令ファイルは system prompt の後に user message として渡され、強制設定ではなくコンテキストとして扱われるため、厳密に従う保証はありません。実際には、主に4つの原因があります。ファイルが agent の読み取り対象にならないサブディレクトリにある、2つのファイルの内容が食い違っていてモデルが一方を任意に選んだ、ルールが曖昧でアクションと照合できない、または周囲のコードがルールと反対の実装例になっている、のいずれかです。

セッション中に命令ファイルを編集すると、何か変わりますか?

すでに会話に読み込まれた内容には影響しません。作業ディレクトリより上位にあるファイルは起動時にすべて読み込まれるため、モデルが保持するテキストは起動時点の内容です。編集内容を反映するには、新しいセッションを開始するか、通常のファイルツールで agent にファイルを読み込ませてください。これにより、現在の内容が新しいメッセージとして会話に追加されます。compaction 後は project root のファイルがディスクから再読み込みされるため、その時点で新しい内容も追加されます。

root の CLAUDE.md とネストしたファイルの内容が食い違う場合、どちらが優先されますか?

どちらも確実には優先されません。検出されたファイルは上書き関係ではなく、filesystem root から作業ディレクトリに向かう順序でコンテキストに連結されます。そのため、最も近いファイルが最後に読み込まれるだけです。矛盾を解決する precedence engine はありません。Claude Code のドキュメントにも、矛盾するルールは任意に解決される場合があると記載されています。ネストしたファイルは、適用対象のパスを明記した追加ルールとして記述し、優先順位で上回ろうとせず、矛盾する記述を削除してください。

命令は /compact 後も維持されますか?

読み込まれ方によって異なります。Project root の CLAUDE.md、スコープ指定のないルール、auto memory は、compaction 後にディスクから再注入されます。paths: frontmatter を持つルールと、サブディレクトリ内の CLAUDE.md ファイルは、対応するファイルが再度読み込まれるまで失われます。チャットに入力しただけの内容は、要約処理が保持した場合に限り残ります。セッション全体で維持する必要があるルールは、paths: frontmatter のない project root のファイルに記述してください。

ルールを文章ではなく hook にするのは、どのような場合ですか?

チェックが決定的で、見落としの損失が小さなスクリプトを書くコストを上回る場合です。ファイルパスの制限、commit 前に必須のコマンド、禁止する tool call などが該当します。status 2 で終了する PreToolUse hook は tool call を直ちにブロックし、stderr の内容を理由としてモデルに返します。そのため、ルールがコンテキスト内に残っているかどうかに関係なく適用できます。formatter や linter で判定できる内容は、そのツールに任せ、命令ファイルから完全に削除してください。