Claudeが指示を無視する理由(そしてCLAUDE.mdで直す方法)

Dev.to / 2026/4/18

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical UsageModels & Research

要点

  • この記事では、Claudeがユーザーの指示を「無視する」ように見える主な要因は、長い会話の中で初期のルールが注意の焦点から外れていく「コンテキストドリフト」だと説明しています。
  • さらに「指示の曖昧さ」も挙げており、「シンプルにして」といった表現が、学習データや文脈に基づいてモデル側で別の意味に解釈され得ると述べています。
  • ただプロンプトを長くして詳細を増やしても効果が薄い理由として、注意の減衰という根本原因ではなく出力の症状に対処しているだけだと主張します。
  • Claude CodeのCLAUDE.mdファイルを使った「エンフォースメントフック」方式を提案しており、毎回のやり取りの開始時に読み直されるためルールが劣化しにくいと説明しています。
  • 著者はテストを通じて、ドリフトを防ぐのに有効だとして「CLAUDE.mdの3つのパターン」を紹介しています。

Claudeはあなたの指示を無視する(そしてCLAUDE.mdで直す方法)

あなたは明確な指示を書きます。Claudeはそれを読みます。すると、まったく別のことをします。

間違い、というわけではありません。……ただ、あなたが求めたものではないだけです。あなたが要求していないdocstringを追加します。あなたが「触らないで」と言ったコードをリファクタします。「改善」しようとして、問題ない部分に手を入れます。あなたが直すと、謝罪します。そして3つ目のプロンプトあたりで、また少しずつ逸れていきます。

これはバグではありません。大規模言語モデルがコンテキストを処理する仕組みです。そして、そのメカニズムを理解すれば、たった1つのファイルで修正できます。

なぜLLMはあなたの指示から逸れていくのか

大規模言語モデルは、あなたが会話を覚えるようには、指示を「覚えて」いません。代わりに、コンテキストウィンドウ(システムプロンプト、あなたのメッセージ、モデル自身の応答を含む固定サイズのテキストブロック)を処理します。

問題はここです。会話が長くなるほど、あなたが最初に書いた指示は、実際に生成が行われる地点からどんどん遠ざかっていきます。モデルの注意は直近のコンテキストへ移ります。丁寧に書いたルールは、ただの背景ノイズになってしまうのです。

これはコンテキストのドリフトと呼ばれ、長いコーディングセッションなら必ず起きます。モデルが意図的に無視しているわけではありません。あなたの指示は、より新しいトークンに対する注意の取り合いで負けているだけです。

もう1つの問題があります:指示の曖昧さです。「シンプルにして」と言うと、Claudeは学習データに基づいて解釈します。「シンプル」の定義には、型アノテーション、エラーハンドリング、コメントの追加が含まれるかもしれません。役に立ちそうに見えますが、あなたが意図したものではありません。

チャット上の口頭指示は、本質的に情報が失われます。新しいメッセージが増えるたびに劣化します。

パッシブなルール vs 強制フック

多くの開発者は、プロンプトを長くしてドリフトを直そうとします。より詳細に、より多くの例を、より強調して。ですが、これはうまくいきません。原因(注意の減衰)ではなく、症状(悪い出力)を扱ってしまうからです。

AIの振る舞いを制御するには、根本的に異なる2つのアプローチがあります:

パッシブなルールは、プロンプトやシステムメッセージに書く指示です。会話の最初では効きますが、時間とともに劣化します。自分自身をもう一度主張し直す仕組みがありません。

強制フックは構造的なものです。会話だけでなく、環境側に存在します。Claude CodeのCLAUDE.mdファイルは強制フックです。会話の長さに関係なく、すべてのやり取りの開始時にコンテキストへ読み込まれます。再読込されるので減衰しません。「覚える」のではなく「読み直す」からです。

この違いは重要です。パッシブなルールは「コメントを追加するな」と言います。強制フックは「コメントを追加するな」と言い、それをClaudeがあなたのコードに作用するたびに毎回読み直すファイルの中で定義します。

実際に定着する 3 つの CLAUDE.md パターン

多数の設定をテストした結果、これらの3つのパターンが一貫してドリフトを防ぎます。

パターン1:正の指示の前に負の制約を置く

Claudeは「役に立とうとする」学習上のバイアスがあります。つまり、何かを足してしまうのです。明確な禁止事項を最初に置いて、それを相殺しましょう。

Before(約5回のやり取り後に逸れる):

## ルール
- 簡潔なコードを書く
- 既存のパターンに従う
- TypeScriptを使う

After(長いセッションでも維持される):

## ルール
# やってはいけない(DO NOT)
- あなたが書いていないコードにコメントやdocstringを追加しない
- 現在のタスクに関係ないコードをリファクタしない
- 明示的に依頼されない限りエラーハンドリングを追加しない
- 承認なしに新しい依存関係を導入しない

# やること(DO)
- コードベースの既存パターンに従う
- 簡潔なコードを書く(行数が少ないほど良い)
- strict modeでTypeScriptを使う

なぜ効くのか:負の制約は「強い境界線」を作ります。曖昧な正のガイダンス(「十分に簡潔か?」)よりも、モデルが評価しやすいからです(「コメントを追加した?はい→削除」)。

パターン2:タスクの境界でスコープをアンカーする

ドリフトは、Claudeがあなたの頼んだ範囲を超えてタスクを広げるときに起きます。スコープを明確に固定しましょう。

Before:

- 変更は最小限にする

After:

## スコープルール
- 現在の依頼に直接関係するファイルのみを変更する
- 1つのレスポンスにつき論理的な変更は1つだけにする。タスクが複数の変更を必要とする場合は、列挙して承認を待つ
- 現在のスコープ外のバグや改善に気づいた場合は言及するが、修正はしない
- テストタスクが明示的にテストを含む場合を除き、テストファイルを変更しない

重要なのは「言及するが、修正はしない」という点です。これによりClaudeに「逃げ道(プレッシャーリリーフバルブ)」ができます。問題を作業に反映せずとも、指摘してフラグを立てることができるため、助けようとする学習は満たしつつ、あなたのタスクを壊しません。

パターン3:具体例でフォーマットを強制する

抽象的なスタイルルール(「簡潔に」)は解釈し直されます。具体例はそうなりません。

Before:

- 良いコミットメッセージを書く

After:

## コミットメッセージ
形式: <type>: <description in lowercase, max 72 chars>
タイプ: fix, feat, refactor, test, docs

例:
  fix: resolve race condition in websocket reconnection

NG:
  Fixed the race condition bug that was causing websocket reconnection issues
  Updated websocket handler to fix race condition and improve reliability

間違った出力を示すのは、正しい出力を示すのと同じくらい重要です。Claudeはパターンマッチングで学習されています。正のルールだけを与えるより、ネガティブな例を示したほうが強いシグナルになります。

Before と After:実際のセッション

これらのパターンを使わない場合と使う場合で、典型的なコーディングセッションがどう見えるかです。

CLAUDE.mdなし:

あなた:「APIクライアントにリトライ機構を追加して」

Claude:リトライロジックを追加し、エラーハンドリングをリファクタし、3つの関数にJSDocコメントを追加し、新しいRetryConfig型を作り、さらにクライアントを別モジュールへ移すことを提案する

あなたが1つ頼んだのに、5つの変更です。

CLAUDE.mdあり(3つすべてのパターンを使用):

あなた:「APIクライアントにリトライ機構を追加して」

Claude:既存のfetchラッパーに指数バックオフ付きのリトライロジックを追加する。メモ:「エラーハンドリングは簡略化できることに気づきましたが、それは現在のスコープ外です。別途対応しましょうか?」

変更は1つ。メモは1つ。ドリフトなし。

修正の裏にある仕組み

CLAUDE.md が機能するのは、指示が存在する場所を変更するからです。会話のコンテキスト(時間とともに劣化するもの)に存在するのではなく、プロジェクト構造(持続するもの)の中に指示が存在します。Claude Code があなたのプロジェクトを読み込むたびに、CLAUDE.md を読み直します。あなたのルールは、直近のコンテキストと競合しません——毎回のやり取りごとにリセットされるからです。

これは、誰かにルールを一度だけ伝えるのと、働く場所の壁に掲示するのとの違いです。

希望ではなく「構造」から始めよう

Claude があなたの指示を無視しているなら、より長いプロンプトを書かないでください。明確な否定的制約、スコープ境界、具体的なフォーマット例を含んだ CLAUDE.md ファイルを作成してください。

私は本番環境でのテストを経た 40 以上のルールを、導入してすぐ使える CLAUDE.md ファイルとしてパッケージ化しました。そこには、スコープ制御、コードスタイルの強制、コミット形式、ドリフト防止が含まれています。既製の出発点が欲しいなら:CLAUDE.md Rules Pack

Cursor を使っている場合も、同じ構造的な原則が .cursorrules ファイルに適用されます。これ用の別パックも用意しています:Cursor Rules Pack v2

AI が覚えていてくれることに期待するのはやめましょう。読み直させてください。