第1章 CLAUDE.md の書き方 — AIへの「就業規則」を網羅的に

CLAUDE.md ってなに?

CLAUDE.md は、Claude Code がセッション開始のたびに自動で読み込む指示書です。プロジェクトの約束事・コマンド・禁止事項をここに書いておくと、AI は毎回それを前提に働きます。

たとえるなら新人向けのオンボーディング資料 + 就業規則です。AI は毎セッション記憶ゼロで出社してくるので、口頭で伝えたことは残りません。CLAUDE.md に書いたことだけが「チームの文化」として毎回伝わります。

📝 Claude Code 以外のAIツール(Codex、Cursor など)と共通化したい場合は、業界で合意が進んでいる AGENTS.md という共通ファイル名もあります。まずは CLAUDE.md で考え方を掴めば、中身はほぼ流用できます。

置き場所 — グローバルとプロジェクトはまったく役割が違う

場所 効く範囲 何を書くか
~/.claude/CLAUDE.md(グローバル) 自分のマシンの全プロジェクト 自分の普遍的な流儀: パッケージマネージャ、git の作法、コーディング哲学
リポジトリ直下 CLAUDE.md(プロジェクト) そのプロジェクトのチーム全員 プロジェクト固有: コマンド、アーキテクチャ、プロジェクトのルール
リポジトリ直下 CLAUDE.local.md そのプロジェクトの自分だけ(.gitignore に入れる) 自分専用のメモ・ローカル環境の事情
サブディレクトリの CLAUDE.md その配下を触るとき モノレポの一部パッケージ固有のルールなど

グローバルとプロジェクトの違いを一言でいうと:

  • ~/.claude/CLAUDE.md は「自分の道具箱」 — git 管理されず、チームには影響しません。どのプロジェクトでも持ち歩く自分の流儀(「yarn を使う」「勝手に commit しない」)を書きます
  • リポジトリの CLAUDE.md は「チームの公式ルール」 — git にコミットして共有し、チーム全員(の AI)に効きます。PR でレビューされながら育っていく、コードと同格の資産です

両方あるときは両方読まれます。迷ったら「チームメイトの AI にも守ってほしいルールか?」で判定 — Yes ならプロジェクト、No(自分の好み)ならグローバルです。自分の好みをプロジェクト側に書くとチーム全員に強制されてしまいます。

💡 ゼロから書く必要はありません。Claude Code の /init コマンドがコードベースを解析して下書きを生成してくれるので、それを育てるのが早道です。また @docs/git-instructions.md のような @パス 記法で別ファイルを取り込むこともできます。


書き方の7原則

実運用されている CLAUDE.md(後述の実例2つ)と、Anthropic 公式のベストプラクティス(Best practices for Claude Code)で共通しているポイントです。

1. 短く、具体的に — そして「CLAUDE.md に書くべきものだけ」を書く

CLAUDE.md は毎リクエストのプロンプトに含まれます。長いほどコスト(トークン)がかかるうえ、指示が多すぎると1つ1つの効きが薄まります。「削れる行はないか」を常に問うこと。

  • ❌ 「コードはできるだけきれいに、保守しやすく書いてください」— 抽象的で効かない。公式ガイドも「”write clean code” のような自明の心がけは書くな」と明言しています
  • ⭕ 「新しいヘルパー関数を書く前に docs/shared-utils.md を確認し、既存があればそれを使う」— 具体的な行動として書いてある

もう1つ、見落とされがちな大事な判断があります。機械で判定できるルールは、CLAUDE.md ではなく lint に書くのが正解です。

たとえば「関数は20行以下」。これを CLAUDE.md に書いても、指示はしょせん「お願い」なので、守られたり守られなかったりします。ESLint の max-lines-per-function(第2章)にすれば破ること自体ができなくなり、CLAUDE.md の行数も節約できます。ルールを思いついたら、まずどこに置くべきか仕分けます:

ルールの性質 置き場所 例
機械で判定できる lint / formatter / 型(第2章) 関数の長さ、any 禁止、ネストの深さ、整形
行動・手順・判断が要る CLAUDE.md(この章) 「ヘルパーを書く前にカタログを確認」「仕様を変えたら docs も更新」
絶対に破らせたくない操作 フック・権限(第4章) commit 前の全チェック、破壊的コマンドの禁止

CLAUDE.md に残すのは「lint やフックでは書けないルール」だけ。この仕分けをするだけで、CLAUDE.md は自然と短く濃くなります。

2. 命令形 + 強調語を使う

MUST(必須) / NEVER(禁止) / IMPORTANT(重要) のような強調は、実際に指示の遵守率を上げます。ただし乱用すると全部が「普通」になるので、本当に譲れないルールだけに使います。

- MUST use **yarn** — NEVER use npm commands
- NEVER perform git commit or push without explicit user permission

3. ルールには理由を一行そえる

AI は理由が分かっていると、ルールの「趣旨」を未知の状況にも応用できます。逆に理由のないルールは、例外的な場面で誤って適用されがちです。

- 時刻の生数字(1000, 60000)を書かない。`server/utils/time.ts` の定数を使う
  — 単位ミス(秒/ミリ秒)のバグが過去に多発したため

4. コマンド一覧は必ず書く

AI が最初に困るのは「このプロジェクト、どうやって動かすの?」です。開発・テスト・lint・ビルドのコマンドは冒頭に明記します。「変更後に必ず実行するチェック」も命令として書きます。

## コマンド
- 開発サーバー: `yarn dev` / テスト: `yarn test` / E2E: `yarn test:e2e`

**IMPORTANT**: コードを変更したら、完了と見なす前に必ず
`yarn format` → `yarn lint` → `yarn typecheck` → `yarn build` を実行すること。

5. 深い内容は docs/ に分けてリンクする

すべてを CLAUDE.md に書くとすぐ肥大化します。「常に守るルール」だけを本文に置き、「特定の作業のときだけ必要な詳細」は別ファイルにしてリンクします。AI は必要なときだけリンク先を読みます(段階的開示)。

MulmoClaude の実例(CLAUDE.md):

## この作業をするときは専用ドキュメントを読むこと

| 作業 | ドキュメント |
|---|---|
| プラグインの作成・編集 | docs/plugin-development.md |
| i18n(8言語ロックステップ)の変更 | docs/i18n.md |
| E2E テストの追加 | docs/e2e-live-testing.md |

6. 実装を確認してから書く(嘘を書かない)

存在しないコマンドや古い仕様を CLAUDE.md に書くと、AI はそれを信じて壊れた作業をします。嘘のルールはルールが無いより有害です。仕様を変えたら CLAUDE.md も同じコミットで更新します。

7. 育てる — 繰り返した注意はルールに昇格する

AI にとっては渡されたテキストがすべてです(text = context)。だから CLAUDE.md や docs/ の指示書はコードと同格の資産として git 管理し、PR でレビューして育てます。CLAUDE.md は一度書いて終わりではありません。

  • 会話中に同じ注意を2回したら、それはルール化のサイン。Claude Code なら入力欄で # から始めると、その場で CLAUDE.md に追記できます
  • 効いていないルールは、書き方を変える(具体化する・理由を足す)か、フックや lint(第2章)へ「機械的強制」に格上げする
  • AIとの振り返りをルーチンにする: 「このセッションで私が繰り返した指示はあった? CLAUDE.md に足すべき?」と聞くと、AI 自身が候補を挙げてくれます

網羅的テンプレート(Vue/React + Express 想定)

そのままコピーして、プロジェクトに合わせて削る・埋めるためのフル装備版です。全部は要りません — 「短く」の原則を思い出して、自分のプロジェクトで実際に事故った/事故りそうな項目だけ残すのが正しい使い方です。

# CLAUDE.md

このファイルは Claude Code がこのリポジトリで働くときのガイドです。

## プロジェクト概要

〇〇をするための Web アプリ。フロントは Vue 3(Composition API)+ Vite、
バックエンドは Express + TypeScript。データは PostgreSQL。

## コマンド

- 開発サーバー: `yarn dev`(client + server 同時起動)
- テスト: `yarn test` / E2E: `yarn test:e2e`(Playwright)
- lint: `yarn lint` / 整形: `yarn format` / 型: `yarn typecheck` / ビルド: `yarn build`

**IMPORTANT**: コード変更後は必ず `yarn format` → `yarn lint` →
`yarn typecheck` → `yarn build` を実行してから完了とすること。

## パッケージ管理

- MUST use **yarn**。NEVER use npm
- 依存の追加は `yarn add`(package.json を手で編集しない)

## Git

- NEVER: ユーザーの明示的な許可なく commit / push / merge しない
- MUST: 作業前にブランチを確認し、main では作業せずフィーチャーブランチを切る
- コミットメッセージは `feat:` `fix:` `refactor:` `docs:` `chore:` の prefix をつける
- rebase は使わない。merge 方式(development/git.md 参照)

## 変更範囲

- MUST: 頼まれた変更だけを行う。頼まれていない機能・パッケージ・リファクタを
  勝手に追加しない。必要だと思ったら先に提案する

## コーディングスタイル

- 機械で判定できるスタイル(関数の長さ・`any` 禁止・ネストの深さ等)は
  eslint.config.mjs で強制している。lint / 型のエラーを `eslint-disable` や
  `@ts-ignore` で黙らせない — 根本原因を直す
- 新しいヘルパーを書く前に docs/shared-utils.md を確認。既存があればそれを使う
- マジックナンバー禁止。名前つき定数に(単位も名前に入れる: `timeout_ms`)
- 純粋なデータ変換はUI・通信から分離した小さな関数に切り出す(テストしやすくするため)

## コメント

- 原則コメントは書かない。名前と型で説明する
- 書いてよいのは「なぜ」が自明でないとき(制約・回避策・ライブラリの癖)だけ
- 「何をしているか」を説明するコメントはリネームか関数抽出で解消する

## エラー処理

- fetch / API 呼び出しには MUST でエラー処理をつける:
  ネットワークエラー(try/catch)と HTTP エラー(`!response.ok`)の両方
- 外部への通信は AbortController でタイムアウトを設定する

## テスト

- 外部 API はモックする(テストは API キーなしで動くこと)
- 単体テストは正常系・境界値・空入力・null/undefined・異常系をカバーする

## Vue(フロントエンド)

- Composition API のみ(Options API 禁止)
- `v-html` 禁止(XSS リスク)
- 文言はハードコードせず vue-i18n(`$t()`)を使う

## Express(サーバー)

- ルートハンドラで直接 `fs` を触らない。`server/utils/` の I/O ヘルパーを使う
- 時刻・パス・ルート名などの定数は `server/config/` の定義を使う(生文字列禁止)

## ドキュメント

- 仕様を変えたら README.md / docs/ を同じコミットで更新する
- コマンド例・オプションが実装と一致しているか確認する

## デバッグ

- MUST: 修正の前に根本原因を特定する。ハードコードなどの応急処置で逃げない
- リグレッションは git の履歴・差分から調べる

## この作業をするときは専用ドキュメントを読むこと

| 作業 | ドキュメント |
|---|---|
| DB スキーマの変更 | docs/database.md |
| デプロイ・リリース | docs/release.md |

実例に学ぶ — 2つの「本物」の構成

実例A: プロジェクトの CLAUDE.md(MulmoClaude の実物)

数百 PR を AI と一緒に回しているプロジェクトの CLAUDE.md は、こういう構成になっています。

セクション 内容 学べること
Project Overview 3行の概要と設計哲学(「ファイルが信頼の源」) 哲学を1行で書くと、細則にない状況でも判断がぶれない
Key Commands dev/lint/test/build + 「変更後は必ず実行」 IMPORTANT 指定つき
Key Rules (always apply) 定数化・I/Oヘルパー経由・fetch のエラー処理など常時ルールだけ 「6回も同じ関数が重複実装された(#1304)」のような実際の事故が理由として書いてある
Edit-time deeper rules lint 方針、UI 規約、i18n → 各 docs/ へのリンク 本文を太らせない(段階的開示)
依存の方向(アーキテクチャ) パッケージ間の依存は一方向のみ、と図つきで AI が一番壊しやすい「構造」を明文化
タスク別ドキュメント表 「プラグインを作るなら docs/plugin-development.md」 作業の入口で正しい資料に誘導

実例B: グローバルの CLAUDE.md(個人の流儀)

全プロジェクト共通の ~/.claude/CLAUDE.md の実例は、こういう章立てです。

  • 凡例: MUST / NEVER / SHOULD / MAY の意味を冒頭で定義(ルールの強さを揃える)
  • パッケージマネージャ(yarn 固定)
  • Git 操作(許可なく commit しない、ブランチ運用、squash 禁止…)
  • 変更範囲(頼まれたことだけ)
  • デバッグ方針(根本原因を先に特定、branch 固有の再現はコード差分を疑う)
  • コード品質(変更後に format → lint → build → typecheck)
  • コーディングスタイル(20行関数、const、any 禁止、コメントは原則なし — このうち機械で判定できるものは、本シリーズでは lint への格上げを推奨。第2章参照)
  • テスト(カバーすべき入力パターンの一覧、golden test)
  • 継続学習(繰り返された指示は CLAUDE.md への追記を提案する、というメタルール)

注目してほしいのは最後の「継続学習」です。CLAUDE.md 自身を育てるルールを CLAUDE.md に書いておくと、運用が自走し始めます。


よくある失敗

失敗 何が起きるか 直し方
何でも書いて肥大化 指示が薄まり、トークンも浪費 常時ルールだけ残し、詳細は docs/ へリンク
抽象的な精神論(「きれいに」「ちゃんと」) 解釈が毎回ぶれる 具体的な行動の形に書き直す
機械で判定できるルールを書いている(「関数は20行以下」等) 「お願い」なので守られたり守られなかったりする lint に移して「破れなく」する(第2章)
全部に IMPORTANT 強調のインフレで全部無視される 本当に譲れない数個だけに
実装と食い違う記述 AI が嘘を信じて壊す 仕様変更と同じコミットで更新。定期的に棚卸し
グローバルに書くべき流儀をプロジェクトに書く チームメイトに自分の好みを強制 置き場所の3階層を使い分ける
書いたのに守られない ルールが「読み物」どまり 機械で強制できるものは lint・フックに格上げ(第2章へ)

次章では、CLAUDE.md の「約束」を機械的な強制力に変える AI向けのガチガチ lint 設定 を見ていきます。

→ 第2章 AI向けガチガチ lint — Vue/React + Express の ESLint 設定