第4章 — CLAUDE.md: プロジェクトの憲法
ミサキの教え
「CLAUDE.md は、プロジェクトの"憲法"だと思って」
ミサキはホワイトボードに大きく「CLAUDE.md」と書いた。
「憲法って、日常の法律より上位にあるでしょ? すべての判断の基盤になる。CLAUDE.md も同じ。AI エージェントがコードを書くとき、最初に読むのがこのファイル。ここに書かれたルールが、すべての出力を方向づける」
ユウキは手元のプロジェクトを開いた。CLAUDE.md は空だった。
「何もない……」
「そう。手綱なしの馬に乗ってたってこと」
CLAUDE.md の読み込み階層
Claude Code は CLAUDE.md を複数の場所から読み込む。この階層構造を理解することが、ハーネス設計の第一歩だ。
| ファイル | スコープ | Git管理 | 用途 |
|---|---|---|---|
~/.claude/CLAUDE.md | 全プロジェクト | × | 個人の作業スタイル、言語設定 |
CLAUDE.md(ルート) | プロジェクト | ○ | チームルール、技術スタック |
.claude/CLAUDE.md | プロジェクト | ○ | 同上(.claude 配下に整理したい場合) |
CLAUDE.local.md | 個人 | × | 個人の実験的設定 |
.claude/rules/*.md | パス限定 | ○ | 特定ファイル種別のルール |
WARNING
優先順位の罠: 下位の設定が上位を「上書き」するのではなく、すべてが「マージ」される。矛盾するルールを書くと AI が混乱する。階層ごとに役割を明確に分けること。
良い CLAUDE.md の5原則
ミサキはユウキに、CLAUDE.md を書くための5つの原則を教えた。
原則1: 具体的であれ
<!-- ❌ 悪い例 -->
- コードを綺麗に書いてください
<!-- ✅ 良い例 -->
- 変数名は camelCase、型名は PascalCase
- 関数は20行以内を目安に分割する
- `any` 型の使用禁止。`unknown` + 型ガードを使う「"綺麗" は人によって違う。AI にとっても曖昧すぎる。数値やパターン名で示すこと」
原則2: 検証可能であれ
<!-- ❌ 検証できない -->
- パフォーマンスに気をつける
<!-- ✅ 検証できる -->
- バンドルサイズが 200KB を超える import は使わない
- N+1 クエリを書かない。必ず JOIN か eager loading を使う「ルールは "守れたかどうか" を判定できなければ意味がない」
原則3: 理由を添えよ
<!-- ❌ 理由がない -->
- dayjs を使う。moment.js は使わない
<!-- ✅ 理由がある -->
- 日付操作には dayjs を使う(moment.js はバンドルサイズが大きすぎるため非推奨)「理由がわかると、AI は似たような判断を他の場面でも応用できる」
原則4: 階層を意識せよ
<!-- グローバル CLAUDE.md(~/.claude/CLAUDE.md)-->
- 日本語で回答する
- git commit は明示的な指示があるまで実行しない
<!-- プロジェクト CLAUDE.md -->
- スタック: Next.js 14 + TypeScript + Prisma
- テストは Vitest を使用
- コンポーネントは src/components/ に配置
<!-- .claude/rules/testing.md(paths: src/**/*.test.ts)-->
- describe ブロックはファイルごとに1つ
- mock は最小限に。実DBを使うインテグレーションテストを優先原則5: 鮮度を保て
「CLAUDE.md は生きたドキュメント。古くなったルールは AI を誤った方向に導く」
実践: ユウキの CLAUDE.md
ユウキはミサキの助けを借りて、プロジェクトの CLAUDE.md を書き上げた。
# my-startup-app
## プロジェクト概要
- SaaS の顧客管理ツール(B2B)
- スタック: Next.js 14 (App Router) + TypeScript + Prisma + PostgreSQL
- デプロイ: Vercel
## セットアップ
pnpm install && pnpm dev
## コーディング規約
- TypeScript strict mode。any 禁止
- コンポーネントは src/components/ に配置(default export 禁止)
- API ルートは src/app/api/ に配置
- DB アクセスは src/lib/db/ の repository パターン経由のみ
- 直接 prisma.xxx.findMany() を呼ばない
## テスト
- pnpm test で Vitest 実行
- 新機能には必ずテストを書く
- DB テストは testcontainers で実 PostgreSQL を使う
## セキュリティ
- ユーザー入力は zod でバリデーション必須
- SQL は Prisma 経由のみ(生SQL禁止)
- 環境変数は .env.example に型定義を書く
- API レスポンスに内部エラーの詳細を含めないパス限定ルール: .claude/rules/
CLAUDE.md が「憲法」なら、.claude/rules/ は「個別法」だ。特定のファイルパターンに対してのみ適用されるルールを書ける。
<!-- .claude/rules/api-routes.md -->
---
paths:
- "src/app/api/**/*.ts"
---
# API ルート規約
- すべてのエンドポイントで認証チェックを実施
- リクエストボディは zod スキーマでバリデーション
- レスポンスは { data, error, meta } の統一形式
- エラーは AppError クラスを throw(try-catch で握りつぶさない)<!-- .claude/rules/components.md -->
---
paths:
- "src/components/**/*.tsx"
---
# コンポーネント規約
- named export のみ(default export 禁止)
- Props 型は同ファイルで定義し export する
- クライアントコンポーネントは先頭に 'use client'
- Tailwind CSS のみ使用(CSS Modules 禁止)アンチパターン集
ミサキはユウキに、よくある失敗パターンも教えた。
アンチパターン1: 長すぎる CLAUDE.md
「200行を超えたら危険信号。AI のコンテキストウィンドウは有限。長すぎると重要なルールが埋もれる」
WARNING
CLAUDE.md は「読まれるたびにトークンを消費する」。200行超えたら、paths 付きの rules/ に分割することを検討する。
アンチパターン2: コードそのものを書く
<!-- ❌ CLAUDE.md にコードテンプレートを書く -->
新しい API ルートを作るときは以下のテンプレートを使え:
export async function GET(req: NextRequest) {
// 100行のテンプレートコード...
}「テンプレートは skills に書く。CLAUDE.md には方針だけ」
アンチパターン3: 矛盾するルール
<!-- グローバル CLAUDE.md -->
- テストには Jest を使う
<!-- プロジェクト CLAUDE.md -->
- テストには Vitest を使う「両方読み込まれるから、AI は混乱する。階層の責務を明確に」
まとめ: 憲法は短く、明確に
良い CLAUDE.md の5原則を意識すれば、AI エージェントは驚くほど一貫した出力を返すようになる。
ユウキは CLAUDE.md を書き上げた翌日、Claude Code に同じ「ユーザーダッシュボードを作って」と指示してみた。
今度は zod バリデーション付き、repository パターン経由の DB アクセス、named export のコンポーネントが生成された。
「これだ……! 同じ指示なのに、出力が全然違う」
「それがハーネスの力よ」とミサキは笑った。「でもまだ序章。次は Hooks——自動で品質を守る仕組みを教えるわ」