💽

Claude Codeのメモリ(CLAUDE.md)の仕組み

に公開

Claude Code のメモリファイル CLAUDE.md とは

Claude Code の設定ファイルCLAUDE.mdは「メモリ」と呼ばれている。
これは、適当なファイル名で *.md ファイルを書いて自分で読み込んだ場合とは異なり、別の仕組みで動いている。

この投稿ではCLAUDE.mdの仕組みを調べた結果を記述する。
なお、公式で説明されていない内容を多分に含み、現時点(2025-07-02)の動作ということに注意。

CLAUDE.mdは、Claude Codeがプロジェクト固有の設定や指示を記憶するための特別なファイルであり、Claude Codeの動作をカスタマイズできる。
よく使う設定に次のようなものがある。

  • プロジェクト固有のコーディング規約を設定
  • よく使うコマンドやスクリプトを記憶
  • 他のドキュメントを@インポートで参照

この記述がどのように読み込まれ、どのように反映されているのかを見ていく。

基本的な仕組み

CLAUDE.mdはセッション開始時に読み込まれる。また、「@」でインポートしているファイルもこの時に読み込まれる。
読み込まれた内容はスナップショットとして内部システムが保存する。

読み込みの流れ

  • セッション開始時に読み込まれる
  • @インポートも同時に解決される
  • その後は通常の「記憶」と同等の扱いとして保持される

複数のCLAUDE.mdがある場合

Claude Codeは複数の場所からCLAUDE.mdを探索し、すべてを累積的に読み込む。

読み込み順序

  1. グローバル
  2. プロジェクトルート
  3. @インポート
  4. サブディレクトリ

どのファイルを優先するかというルールは存在しない。
Claude Codeが状況によって判断する
(今はプロジェクトの作業をしているからプロジェクトのルールを優先しよう、等)

実際の内部動作

Claude Codeが内部的に生成するsystem-reminderタグにより、読み込んだスナップショットが報告される。

<system-reminder>
As you answer the user's questions, you can use the following context:
# claudeMd
Codebase and user instructions are shown below. Be sure to adhere to these instructions.
IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written.

Contents of /home/user/.claude/CLAUDE.md (user's private global instructions for all projects):
# 共通設定
基本的な設定内容...

Contents of /home/user/projects/myproject/CLAUDE.md (project instructions, checked into the codebase):
# プロジェクト設定
プロジェクト固有の設定...

詳細は @guidelines.md を参照

Contents of /home/user/projects/myproject/guidelines.md (project instructions, checked into the codebase):
# ガイドライン
開発ガイドラインの内容...

Contents of /home/user/projects/myproject/subdir/CLAUDE.md (project instructions, checked into the codebase):
# サブディレクトリ設定
ローカルな設定...

# important-instruction-reminders
Do what has been asked; nothing more, nothing less.
NEVER create files unless they're absolutely necessary for achieving your goal.
ALWAYS prefer editing an existing file to creating a new one.
NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.

IMPORTANT: this context may or may not be relevant to your tasks. You should not respond to this context or otherwise consider it in your response unless it is highly relevant to your task. Most of the time, it is not relevant.
</system-reminder>

このように、全て統合した一つの文章という形で報告される。

CLAUDE.md読み込みのポイント

  • すべてのCLAUDE.mdが一つのシステムリマインダーに統合される
  • 各ファイルは「project instructions」として扱われる(グローバル設定を除く)
  • @インポートされたファイルも同様に含まれる
  • 最後に共通の指示が追加される

スナップショットの報告

上記system-reminderの内容は定期的に報告され、Claude Codeが忘れないようになっている。
セッション中に変更した内容は報告されないが、共通の仕組みとしてファイル変更差分通知があるので、その通知としては報告される。

auto-compact が実行された場合も、このスナップショットが報告される。

手動/compactコマンドや/clearコマンドを実行すると、CLAUDE.md@インポートファイルが再読み込みされる。

インポート機能

CLAUDE.md に @ファイル名 を書くことにより別のファイルをインポートできる。

基本的な使い方

# CLAUDE.md
プロジェクトの基本設定

詳細は @docs/guidelines.md を参照
APIドキュメントは @api/reference.md を参照

ここで「〜を参照」と書くことについて。
これは人間向けには意味があるが、AI向けには意味がない。Claude Codeは既に読み込んでいる。

コンテキスト使用量への影響

大量のドキュメントがある場合に、大量のファイルをインポートすることには注意が必要。

大量の@インポートはコンテキストを圧迫し、作業効率を低下させる。
※公式仕様は200,000トークンになっているが、セッションログでは約155,000トークンを超えるとauto-compactが発生する。

大量に文書を読み込んだ状態のClaude Codeはとても賢いので
「一つのタスクを実施」→「新規セッションで一つのタスクを実施」
ということを繰り返せば賢い状態を維持できるが、それを続けるとAPIのrate limitに引っかかる。(Max $200 プランでも)

auto-compactループの回避

大量の@インポートを使用すると、auto-compactが発生した直後でもコンテキストウィンドウが足りないという事態に陥る。
その場合は CLAUDE.mdからインポートを削除し、再読み込みさせることで会話を継続できる。

英語文書によるコンテキストの節約

現在1万行の文書があるプロジェクトで、全て読み込んだ場合に日本語と英語のトークン数がどうなるか比較をした。

指標 日本語 英語 比率(日/英)
同一内容のトークン数 136,415 110,104 1.24
文字数 245,323 324,156 0.76
文字当たりのトークン効率 低い 高い 0.61

Claude Codeを立ち上げた最初の会話で、
日本語の場合はContext left until auto-compact: 12%が表示された。
英語の場合はContext left until auto-compact: 29%だった。
結構な差がある。

言語 文字/トークン バイト/トークン 計算式
日本語 1.80 2.62 バイト数 ÷ 2.62 = トークン数
英語 2.94 3.01 バイト数 ÷ 3.01 = トークン数

バイト数とトークン数の比較。

この結果をふまえると、文書を大量に読み込むのなら英語で書いた方が良い。

ただし自分は日本語で書いている。
英語だと間違いや微妙な言い回しのズレに気付かない可能性があり、間違っている参考情報を前提に行動される方が困ることが多いからだ。

FAQ

CLAUDE.mdの内容に従ってくれない
Claude Codeは記憶を忘れる。
また、最初の一言目に複雑な依頼をした場合、メモリの内容に注意が向かないかもしれない。Claude Codeは記憶の内容より会話を優先する。

会話が進むとCLAUDE.mdの内容に従わなくなってくる
Claude Codeは記憶を忘れる。
スナップショットの内容をシステムが報告してくることは確認できているが、どういうタイミングなのかはまだ調べきれていない。
また、複雑な作業中にスナップショットが通知されても、複雑な作業を優先してCLAUDE.mdの内容に注意が向かないかもしれない。

結局、どうしたらいい?
定期的にCLAUDE.mdを覚えているかどうか確認するhooksを作った。

https://gist.github.com/nishimura/c8addf4a942fdd4fb506db90942f98cb

システムが送信する<system-reminder>を真似て、<project-reminder>を送信できるようにする。このサンプルでは会話を20往復したときに記憶の確認が入る。
今はhooksが使えるようになったところなので、これがまだ有効かどうかは分からないが、こういう方向で何とかできる可能性がある。

Discussion