CLAUDE.mdの書き方ガイド|実運用で分かった設計パターンとアンチパターン
CLAUDE.mdを3ヶ月間毎日運用して見えた書き方のコツ。読み込み階層、フォーマットと遵守率の関係、Progressive Disclosure、Auto Memoryとの使い分けを解説。
エンジニアのゆとです。
Claude Codeを日常的に使っている人なら、プロジェクトルートにあるCLAUDE.mdというファイルを見たことがあるはず。/initで自動生成して放置している人も多いんじゃないだろうか。
自分はこのCLAUDE.mdを3ヶ月間、毎日のように書き換えながら運用してきた。その過程で「書き方ひとつでClaude Codeの挙動が明確に変わる」ことを実感している。
この記事では、公式ドキュメントの情報に加えて、実運用で見えてきた設計パターンとアンチパターンをまとめる。「/initで生成したまま放置している」人にも、「もっとClaude Codeを使いこなしたい」人にも役立つ内容にしたつもりだ。
CLAUDE.mdは「システムプロンプト」ではない
最初に、多くの人が誤解しているポイントから。
CLAUDE.mdはシステムプロンプトとしてではなく、ユーザーメッセージとしてClaude Codeに渡される。具体的には、セッション開始時に「このコンテキストがタスクに高度に関連していない限り反応しなくてよい」という条件つきでプロンプトに含まれる。
これが意味するのは、CLAUDE.mdに書いた内容はアドバイザリー(助言)であって、絶対命令ではないということ。Claudeは文脈に応じて「今のタスクに関係ない」と判断した指示を無視することがある。
逆に言えば、CLAUDE.mdに汎用的すぎる内容や、今のタスクと関係の薄い情報を大量に書くと、まとめて無視される確率が上がる。
CLAUDE.md: ユーザーメッセージとして渡される。コンテキスト次第で無視されることがある。チームで共有しやすい(Gitに含めるため)。
settings.json の instructions: CLAUDE.mdとは異なる経路で渡されるため、より確実に従われる。絶対に守らせたいルールはこちらに書くのも手。
使い分け: 「知っておいてほしい情報」はCLAUDE.mdに、「必ず従ってほしいルール」はsettings.jsonのinstructionsに。
読み込み階層を理解する
CLAUDE.mdは1つだけではない。4つのスコープがあり、すべてが読み込まれる。
| スコープ | 配置場所 | 共有範囲 | 用途 |
|---|---|---|---|
| Managed | /Library/Application Support/ClaudeCode/CLAUDE.md(macOS) | 全ユーザー | IT部門が全社ルールを強制 |
| User | ~/.claude/CLAUDE.md | 自分のみ | 個人のグローバル設定 |
| Project | ./CLAUDE.md または ./.claude/CLAUDE.md | Gitでチーム共有 | プロジェクト固有のルール |
| Local | ./CLAUDE.local.md | 自分のみ(.gitignore対象) | 個人的なプロジェクト設定 |
全スコープのCLAUDE.mdが結合されてプロンプトに含まれる。つまり、User + Project + Localの内容が全部載る。
重要なのは親ディレクトリの挙動。Claude Codeはカレントディレクトリから上に遡って、途中にあるCLAUDE.mdもすべて読み込む(起動時にフルロード)。一方、子ディレクトリのCLAUDE.mdは、そのディレクトリのファイルを操作した時点でオンデマンドで読み込まれる。
モノレポで複数のサブプロジェクトがある場合、claudeMdExcludes設定で不要なCLAUDE.mdの読み込みをスキップできる。
// .claude/settings.json
{
"claudeMdExcludes": ["packages/legacy/**", "vendor/**"]
}
何を書くべきか、何を書くべきでないか
CLAUDE.mdに書く内容を選ぶ基準はシンプルだ。「Claudeがコードを読んでも推測できない情報」だけ書く。
書くべきもの
- ビルド・テスト・デプロイのコマンド:
npm run test:unit、make lint、cargo test -- --nocaptureなど。プロジェクトごとに違うコマンドはClaude が推測できない - デフォルトと異なるコードスタイル: 「インデントはタブ4つ」「関数名はsnake_case」など、言語のデフォルトと違う場合のみ
- プロジェクト固有のアーキテクチャ判断: 「認証は独自ミドルウェアで処理している」「DBマイグレーションはprismaではなくカスタムスクリプト」
- 非自明な落とし穴: 「
/api/v2/は廃止済みだが互換性のために残している。新規開発では/api/v3/を使う」 - ブランチ命名・PRの規約:
feature/JIRA-123-descriptionのような、チーム固有のルール - 環境固有の要件: 必要な環境変数、必須のローカルサービス(Docker、Redis等)
書くべきでないもの
- Claudeがコードを読めばわかること: ディレクトリ構成の逐一説明、各ファイルの役割説明
- 言語の標準規約: Pythonでsnake_caseを使う、GoでgofmtをかけるといったClaude が既に知っている常識
- 詳細なAPIドキュメント: リンクだけ貼れば十分。全文をCLAUDE.mdに書く必要はない
- 頻繁に変わる情報: 今月のスプリントゴール、一時的なワークアラウンドなど
- 「クリーンなコードを書いて」のような自明な指示: トークンの無駄
- チームが実際には守っていない理想のルール: Claudeがルール通りにコードを書いても、既存コードと矛盾してPRが通らない
フォーマットが遵守率を変える
CLAUDE.mdの書き方によって、Claudeがどれだけ指示に従うかが変わる。ある調査によると、以下の傾向がある。
| フォーマット | 遵守率への影響 |
|---|---|
| 箇条書き vs 散文 | 箇条書きのほうが約60%遵守率が高い |
| 命令形 vs 記述形 | 命令形のほうが約25%精度向上 |
| 150行以下 vs 150行超 | 短いほうが約25%遵守率が高い |
つまり、CLAUDE.mdは短く、箇条書きで、命令形で書くのが最も効果的。
悪い例:
私たちのプロジェクトでは、コードの品質を保つために、テストを書くことを
推奨しています。特にユニットテストは重要で、新しい機能を追加する際には
必ずテストを追加してください。テストフレームワークはVitestを使用しています。
良い例:
- テスト: Vitest。新機能には必ずユニットテストを追加する
- テスト実行: `npm run test:unit`
- カバレッジ確認: `npm run test:coverage`(80%以上を維持)
同じ内容でも、下のほうが短く、具体的で、命令形になっている。
サイズの目安
公式推奨は200行以下/ファイル。コミュニティでのコンセンサスは60〜300行程度だが、短ければ短いほどいい。
トークン消費の観点でも、肥大化したCLAUDE.md(2,000行超)は約3,000トークンを消費する。ミニマルなCLAUDE.md(100行程度)なら約500トークン。200kコンテキストの場合、約130会話ターン分の差になる。1Mコンテキスト(Opus)でもこの差は無視できない。
Progressive Disclosure — 情報を階層化する
CLAUDE.mdが200行を超えそうなら、Progressive Disclosure(段階的情報開示)を検討すべきだ。全部をCLAUDE.mdに書くのではなく、3層に分ける。
Layer 1: CLAUDE.md(毎セッション読み込み)
プロジェクトの概要、必須コマンド、他の情報ファイルへのポインタだけ書く。
# プロジェクト名
TypeScript + Next.js 15のWebアプリ。
## コマンド
- dev: `npm run dev`
- build: `npm run build`
- test: `npm run test`
- lint: `npm run lint`
## アーキテクチャ
- App Router使用。src/app/ 配下
- DB: Prisma + PostgreSQL
- 認証: NextAuth v5
- 詳細は docs/architecture.md を参照
## コードスタイル
- セミコロンなし、シングルクォート
- コンポーネントはfunction宣言(アロー関数ではなく)
- 詳細は docs/coding-standards.md を参照
これで30行以下。
Layer 2: .claude/rules/(条件付き読み込み)
特定のファイルを操作したときだけ読み込まれるルールを定義する。YAMLフロントマターで対象パスを指定できる。
<!-- .claude/rules/api-routes.md -->
---
paths:
- "src/app/api/**"
---
- APIルートはRoute Handlersで実装する
- レスポンスはNextResponse.json()を使う
- エラーハンドリングはtry-catchで囲み、適切なHTTPステータスを返す
- 認証が必要なルートは middleware.ts で処理済み
<!-- .claude/rules/database.md -->
---
paths:
- "prisma/**"
- "src/lib/db/**"
---
- マイグレーション: `npx prisma migrate dev`
- シード: `npx prisma db seed`
- スキーマ変更後は必ず `npx prisma generate` を実行
- 本番DBへの直接接続は禁止
こうすることで、APIルートを触っているときだけAPI関連のルールが読み込まれ、DB関連のファイルを触っているときだけDB関連のルールが読み込まれる。CLAUDE.mdがスリムなまま、必要な情報が必要なときに供給される。
Layer 3: .claude/skills/(オンデマンド起動)
定型作業をスキルとして定義する。スキルファイルのdescriptionだけがセッション開始時にコンテキストに入り、本体はユーザーが呼び出したときだけ読み込まれる。
<!-- .claude/skills/deploy.md -->
---
description: "本番環境へのデプロイ手順を実行する"
---
# デプロイスキル
1. `npm run build` でビルド確認
2. `npm run test` でテスト通過確認
3. `git push origin main` でデプロイトリガー
4. Vercel Dashboard で確認: https://vercel.com/team/project
5. 本番URLでスモークテスト
Auto Memoryとの使い分け
Claude Code v2.1.59以降、Auto Memory機能が追加された。Claudeが会話の中で学んだことを~/.claude/projects/<project>/memory/に自動保存する機能だ。
ここで問題になるのが、CLAUDE.mdとAuto Memoryの棲み分け。
| 項目 | CLAUDE.md | Auto Memory |
|---|---|---|
| 誰が書くか | 人間 | Claude |
| 内容 | プロジェクトのルール・規約 | デバッグの知見、設定の経緯、ユーザーの好み |
| 共有 | Gitでチーム共有 | ローカルのみ |
| 読み込み | 毎セッション | MEMORY.mdの先頭200行 + オンデマンド |
| 更新頻度 | 手動(意図的に) | 自動(会話の中で随時) |
実運用でのルール:
- チームに共有すべきルール → CLAUDE.md
- 個人の好みや経験則 → Auto Memoryに任せる
- デバッグで発見した落とし穴 → 汎用的ならCLAUDE.md、個人的ならAuto Memory
- 環境固有の設定 → CLAUDE.local.md(Gitに含めない)
Auto Memoryの中身は/memoryコマンドで確認できる。定期的にチェックして、CLAUDE.mdに昇格させるべき知見があれば移動する、という運用がおすすめ。
よくあるアンチパターン
実際に見かけた(そして自分もやった)CLAUDE.mdのアンチパターンをまとめる。
1. 全部入り型
プロジェクトのREADME、API仕様、コーディング規約、デプロイ手順を全部CLAUDE.mdに書く。500行超え。結果、Claudeが重要な指示を見落とす。
→ Progressive Disclosureで分割する。CLAUDE.mdには概要とポインタだけ。
2. /init放置型
/initで自動生成したCLAUDE.mdをそのまま使い続ける。/initが生成する内容は汎用的で、プロジェクト固有の情報が不足している。
→ /initは出発点。生成後に不要な記述を削り、プロジェクト固有の情報を追加する。
3. リンター代替型
コードスタイルのルールをCLAUDE.mdに延々と書く。「インデントは2スペース」「末尾カンマ必須」「import順序はビルトイン→外部→内部」…
→ ESLint、Prettier、Biomeに任せる。CLAUDE.mdには「lint: npm run lintで確認」とだけ書けばいい。
4. 否定だけ型
「〇〇を使うな」「△△はやるな」とだけ書いて、代替案を示さない。Claudeは何をすべきかわからず、別の不適切な方法を選ぶことがある。
→ 「〇〇ではなく△△を使う」「〇〇は廃止済み。代わりに△△(理由: )」と書く。
5. コピペ型
GitHubで見つけた有名プロジェクトのCLAUDE.mdをそのままコピペする。自分のプロジェクトとは構成も技術スタックも違うのに。
→ CLAUDE.mdはプロジェクト固有であるべき。他人のCLAUDE.mdは「構成の参考」にとどめる。
実践テンプレート
実運用から抽出したテンプレート。これをベースにプロジェクトに合わせてカスタマイズしてほしい。
# プロジェクト名
[1-2行でプロジェクトの概要]
## 技術スタック
[箇条書きで主要技術を列挙]
## コマンド
- dev: `xxx`
- build: `xxx`
- test: `xxx`(単体テスト: `xxx`)
- lint: `xxx`
- deploy: `xxx`
## アーキテクチャ
[デフォルトと異なる設計判断を箇条書き]
- 詳細: docs/architecture.md
## コードスタイル
[デフォルトと異なるルールのみ]
- lint/formatの設定ファイルに従う
## 注意事項
[プロジェクト固有の落とし穴、やってはいけないこと]
## 参照
[外部ドキュメントへのリンク]
ポイント:
- 50〜100行に収める。超えそうなら
.claude/rules/に分割 - 各セクションは箇条書き。散文は避ける
- 命令形で書く。「〜してください」ではなく「〜する」
- 理由を添える。「〇〇は使わない(理由: パフォーマンスが3倍悪化するため)」
CLAUDE.mdを育てるプロセス
CLAUDE.mdは一度書いたら終わりではない。プロジェクトとともに進化させていく。
Week 1: /initで初期生成 → 不要な記述を削除 → プロジェクト固有のコマンドを追加
Week 2-4: Claude Codeを使いながら「この情報があれば一発で正しく動くのに」と思ったことを追記。逆に「書いたけどClaude が無視している」指示は、書き方を変えるか、settings.jsonのinstructionsに移動
Month 2以降: 肥大化してきたら.claude/rules/に分割。Auto Memoryと重複している情報を整理。チームメンバーのフィードバックを反映
定期的に(月1回程度)CLAUDE.mdを見直して、古くなった情報を削除する。古い情報はClaude を混乱させる原因になる。
まとめ
CLAUDE.mdは「Claudeへの指示書」であると同時に、「プロジェクトの暗黙知を明文化する場所」でもある。
書き方のポイントを整理すると:
- CLAUDE.mdはシステムプロンプトではなくユーザーメッセージ。だから短く、具体的に、命令形で
- Claudeがコードから推測できない情報だけ書く
- 200行を超えたらProgressive Disclosureで分割する
- Auto Memoryとの棲み分けを意識する。チーム共有のルールはCLAUDE.md、個人的な知見はAuto Memory
- 定期的にメンテナンスする。古い情報はノイズになる
CLAUDE.mdの質を上げると、Claude Codeとの作業効率が目に見えて変わる。毎回同じことを説明する手間がなくなり、プロジェクト固有のルールを自然に守ってくれるようになる。
まだ/initで生成したまま放置しているなら、この記事を参考に一度見直してみてほしい。
