2,000行の CLAUDE.md はナレッジベースではない。負債だ。
このファイルは、セッションが始まる前にClaudeにプロジェクトのコンテキストを渡すために存在する。しかしClaude Codeはその全内容をコンテキストウィンドウの一部として処理する。十分な長さになると、三つのことが起きる。コンテキストが早く埋まる、Claudeがファイルをアクティブな指示としてではなくバックグラウンドノイズとして扱い始める、そして最悪のことに——何かを変更しなければならないときに自分自身がファイルを読まなくなる。
情報を失わずに解決する方法を紹介する。
長いCLAUDE.mdが機能しなくなる理由
Claude Codeは、すべてのセッション開始時と、重要なツール呼び出しの前に CLAUDE.md ファイルを読み込む。内容はシステムレベルの指示としてコンテキストウィンドウに直接注入される。
それがメカニズムだ。以下が失敗のパターンだ。
CLAUDE.md が2,000行あると、実際の作業が始まる前に利用可能なコンテキストのかなりの部分を消費してしまう。20万トークンのモデルで複雑なコードベースなら管理できるかもしれない。コンテキストがより制約されたモデルや、すでに長いタスクの深いところにあるセッションでは、ファイルが実際の作業とスペースを奪い合い始める。
より現実的な問題として、長いファイルは何も削除せずに追記し続けることで肥大化する。6ヶ月後には以下のようになっている:
- 現在のコーディング規約(有用)
- 移行済みのフレームワークの規約(古い)
- 3月に修正されたバグの詳細な説明(無関係)
- 3人がファイルを読まずに編集したことで生じたAPIエラー処理に関する三つの矛盾するルール
ファイルは信頼できないものになる。Claudeは読む。エンジニアは読まない。何が最新かは誰もわからない。
おそらく使っていない階層型システム
Claude Codeは、プロジェクトルートだけでなくサブディレクトリの CLAUDE.md ファイルもサポートしている。これが大規模なコードベースを管理可能にする重要な機能だ。
ルールは以下のとおり:
- Claudeはまずルートの
CLAUDE.mdを読む - Claudeがサブディレクトリに移動すると(ファイルの読み取り、ツールの実行、またはそこへの誘導によって)、そのディレクトリの
CLAUDE.mdを自動的に読む - 子の
CLAUDE.mdファイルはルートを補完する——置き換えるのではなく
つまり、フロントエンドとバックエンドを持つモノレポは次のような構造にできる:
project-root/
├── CLAUDE.md # グローバル: 規約、アーキテクチャ概要、横断的ルール
├── packages/
│ ├── frontend/
│ │ └── CLAUDE.md # Reactの規約、コンポーネントパターン、CSSアプローチ
│ └── backend/
│ └── CLAUDE.md # API設計、データベースパターン、認証フロー
└── scripts/
└── CLAUDE.md # ビルドスクリプト、CIヘルパー、デプロイ手順
Claudeが packages/frontend/ で作業しているとき、グローバルコンテキストとフロントエンド固有のコンテキストの両方を持つ。packages/backend/ にいるときは、グローバルコンテキストとバックエンド固有のコンテキストを持つ。必要のないコンテキストを読み込むことはない。
ほとんどのプロジェクトで、これだけでルート CLAUDE.md の実効サイズを60〜70%削減できる。ルートは常に関連するものだけに絞られる。それ以外はあるべき場所に置かれる。
Importディレクティブ: 断片化せずに分割する
Claude Codeは CLAUDE.md での明示的なインポートもサポートしている。別のファイルを参照でき、Claudeはその内容を指示の一部として含める:
# プロジェクトのコンテキスト
サービスがどう接続しているかの背景はアーキテクチャ概要を参照。
@./docs/architecture.md
@./docs/api-conventions.md
@./scripts/CLAUDE.md
@./path/to/file 構文は、参照されたファイルの内容をインラインで含めるようClaude Codeに指示する。CLAUDE.md ファイルだけでなく、任意のテキストファイルで動作する。
これは二つのパターンに有用だ:
パターン1: ドキュメントをCLAUDE.mdと同期させる
アーキテクチャドキュメントは、開発者も必要とするため docs/architecture.md に置かれている。CLAUDE.md はそれを複製せずにインポートする。アーキテクチャが変わったら、一つのファイルを更新すれば両方の用途が最新に保たれる。
パターン2: フラットなリポジトリのトピックベースの分割
すべてのプロジェクトがサブディレクトリの境界が明確なモノレポというわけではない。単一パッケージのライブラリには、サブCLAUDE.mdファイルを置く明確な場所がないかもしれない。インポートを使えばトピックで分割できる:
project-root/
├── CLAUDE.md # 他すべてをインポート; 自身の内容は最小限
├── .claude/
│ ├── conventions.md # コーディング標準、命名、フォーマット
│ ├── testing.md # テストパターン、フィクスチャ、モックアプローチ
│ ├── deployment.md # ビルド方法、パイプラインの内容
│ └── known-issues.md # 現在のバグ、回避策、注意点
ルートの CLAUDE.md はインデックスになる:
# プロジェクト: Acme API
Acmeプラットフォームを提供するREST API。Node.js + Express + PostgreSQL。
@./.claude/conventions.md
@./.claude/testing.md
@./.claude/deployment.md
@./.claude/known-issues.md
各インポートファイルは独立して更新できる。ルートは安定したままだ。
ルートに置くものとサブファイルに置くものの判断基準
判断ルールはシンプルだ: ルートは普遍的なもの、サブファイルはコンテキスト依存のもの。
ルートCLAUDE.md: 常に関連するコンテキスト
ルートのコンテンツは、Claudeが何に取り組んでいるかに関わらず、すべてのClaude Codeセッションで真実かつ有用であるべきだ:
- プロジェクト名、目的、技術スタック(30秒の概要)
- リポジトリ構造(何がどこにあるか、トップレベルのディレクトリの意味)
- ローカルでプロジェクトを実行する方法(常に機能するコマンド)
- どこにでも適用される絶対的なルール(シークレットをコミットしない、パブリックAPIには必ずテストを書く、など)
- より具体的なコンテキストへのリンクやインポート
目標の長さ: 200行以下。そこに到達できないなら、コンテキスト依存のコンテンツがルートに含まれている。
サブファイル: コンテキスト固有の知識
コードベースの特定の部分で作業するときにのみ重要なすべてのもの:
<!-- packages/frontend/CLAUDE.md -->
# フロントエンドパッケージ
## スタック
React 18 + TypeScript + Tailwind CSS。バンドルはVite。
## コンポーネントの規約
- コンポーネントは src/components/ に置く
- 1ファイル1コンポーネント
- propsのインターフェースはコンポーネントの上、同じファイルに定義する
- デフォルトエクスポートなし — 名前付きエクスポートのみ使用
## 状態管理
グローバル状態にはZustandを使用。コンポーネントレベルの関心事にはuseStateによるローカル状態でOK。Reduxは追加しないこと — 移行済み。
## テスト
Vitest + Testing Library。テストはコンポーネントの隣に置く(Component.test.tsx)。
スナップショットテストは禁止 — スタイル変更のたびに失敗し、シグナルを提供しない。
## やってはいけないこと
- ../../packages/backend からインポートしない — パッケージは別デプロイメント
- CSSモジュール(レガシー)を使わない — 新しいコードはTailwindのみ
これはClaudeがフロントエンドで作業しているときに非常に有用だ。バックエンドやscriptsディレクトリにいるときには無関係なノイズだ。サブディレクトリの CLAUDE.md に置くことで、必要なときだけ読み込まれる。
既存の肥大化したCLAUDE.mdを診断する
分割する前に、中身を監査する。簡単な分類:
エバーグリーン(ルートに保持):
- アーキテクチャ概要とコアな原則
- プロジェクトの実行方法
- どこにでも適用されるチーム規約
コンテキスト依存(サブファイルに移動):
- パッケージ固有のパターンと規約
- 特定のサービスの仕組み
- デプロイメント固有の指示
- テストインフラの詳細
古い(削除):
- 使わなくなったライブラリへの参照
- 完了した移行に関するメモ
- クローズされた問題のバグレポート
- 自動化されたセットアップ手順の説明
冗長(削除):
- コード自体から明らかなこと
- リンターが強制するルール(ESLintが検出するなら、Claudeが別途知る必要はない)
- READMEやドキュメントサイトにすでに存在するドキュメント
実際のところ、肥大化した CLAUDE.md ファイルのほとんどは約30%が古いコンテンツ、30%が冗長なコンテンツ、そして40%が間違った場所にある正当に有用なコンテンツだ。
Before/Afterの例
Before — すべてが入った1,400行のルートCLAUDE.md:
CLAUDE.md (1,400行)
├── プロジェクト概要 (30行)
├── グローバル規約 (50行)
├── フロントエンド: Reactパターン (200行)
├── フロントエンド: CSSアプローチ (100行)
├── フロントエンド: テストセットアップ (150行)
├── バックエンド: API設計 (200行)
├── バックエンド: データベースパターン (150行)
├── バックエンド: 認証フロー (100行)
├── CI/CDパイプライン (120行)
├── デプロイ手順 (150行)
└── その他のメモと回避策 (150行)
After — 同じ情報を再編成:
CLAUDE.md (80行)
├── プロジェクト概要 (30行)
├── グローバル規約 (30行)
└── インポート: frontend.md, backend.md, deployment.md
.claude/frontend.md (450行)
├── Reactパターン
├── CSSアプローチ
└── テストセットアップ
.claude/backend.md (450行)
├── API設計
├── データベースパターン
└── 認証フロー
.claude/deployment.md (270行)
├── CI/CDパイプライン
└── デプロイ手順
└── 既知の問題(その他から移動)
ルートは1,400行から80行に縮小した。すべてのセッションは80行のコンテキストから始まる。Claudeがフロントエンドで作業するとき、80 + 450行を取得する。両方にまたがる作業をするとき、すべてを取得する——ただしタスクがそれを必要とするためだ。
チームでのCLAUDE.md管理
個別のCLAUDE.mdファイルを肥大化させる同じ問題がチームにより大きな影響を与える: 誰もが追加し、誰も削除せず、誰も監査しない。
いくつかの有効な実践:
サブファイルのオーナーシップを割り当てる。 フロントエンドチームは packages/frontend/CLAUDE.md を所有する。そこに何か間違いがあれば、彼らの責任だ。単一のルートファイルの所有権が分散すると、誰も所有していないことになる。
PRでCLAUDE.mdの変更をコードと同じようにレビューする。 何も削除せずに CLAUDE.md に50行を追加するPRは、理由を説明せずに50行のコードを追加するPRと同じ精査を受けるべきだ。
サイズバジェットを設定する。 ルートファイルは200行以下に保つ。PRがそれを超えようとするなら、何かを削除しなければならない。バジェットは徐々な肥大化を防ぐための強制機能だ。
四半期ごとの監査。 四半期に一度、各ファイルを確認し、90日間に触れられていないもの、参照されていないものを削除する。古いルールはルールなしより悪い——Claudeにコードベースの現在の状態について誤解させる。
チーム設定の .claude/settings.json 側の詳細——権限ルール、許可リスト、gitignoreのセットアップ——については、Claude Code settings.json in Teams: How to Prevent Conflicts and Share Config Safely を参照。
公式ドキュメントが明確に言っていないこと
Claude Codeのドキュメントは階層型システムを正確に説明しているが、サブディレクトリのファイルがいつ読み込まれるかは教えてくれない。正確な動作は以下のとおりだ:
~/.claude/CLAUDE.md— グローバルな個人ファイル、すべてのセッションで読み込まれる{project-root}/CLAUDE.md— セッション開始時に読み込まれる{project-root}/packages/foo/CLAUDE.md— Claudeがそのディレクトリで操作するときに読み込まれる
「そのディレクトリで操作する」とは: Claudeがそのディレクトリのファイルを読む、そのディレクトリのファイルを編集する、またはそのディレクトリからBashコマンドを実行するとき。抽象的な意味で「フロントエンドに取り組んで」とClaudeに伝えるだけでは読み込まれない——Claudeが実際にツールを通じてそこに移動したときに読み込まれる。
これが重要なのは、階層型システムがタスク記述に依存するのではなく、アクティブなコンテキストに依存しているためだ。フロントエンドのタスクを説明してもClaudeの最初のアクションがルートの設定ファイルを読むことであれば、Claudeが実際にフロントエンドのファイルに触れるまでフロントエンドの CLAUDE.md は読み込まれない。サブファイルの境界は、概念的なタスクカテゴリではなく、ファイルが存在する場所に基づいて計画すること。
圧倒されているときのクイックウィン
CLAUDE.md が2,000行あって、今日は全面的な再編成をする時間がない場合:
-
まず古いコンテンツを削除する。 置き換えられたライブラリ、パターン、またはアーキテクチャを参照しているものを特定する。削除する。1,400行になり、Claudeの指示は正確になる。
-
「実行方法」セクションをREADME.mdに移動してインポートする。 どのプロジェクトにもこのセクションがある。多くの場合、すでに両方の場所に存在する。正規の場所を一つ選んでインポートする。
-
known-issues.mdを作成して回避策をそこに移動する。 回避策は蓄積されて古くなる。分離することで監査と整理が容易になる。
これら三つのステップには1時間かかり、おそらくファイルを40%削減できる。完全な階層型再構成は、時間があるときに専用のセッションで行える。
Claudeが実際に従う CLAUDE.md は、Claudeが定型文として扱う包括的なものより有用だ。短く、正確で、階層的に整理されたものは、長くて完全なものに毎回勝る。