mybook

第4章 — CLAUDE.md: プロジェクトの憲法

ミサキの教え

「CLAUDE.md は、プロジェクトの"憲法"だと思って」

ミサキはホワイトボードに大きく「CLAUDE.md」と書いた。

「憲法って、日常の法律より上位にあるでしょ? すべての判断の基盤になる。CLAUDE.md も同じ。AI エージェントがコードを書くとき、最初に読むのがこのファイル。ここに書かれたルールが、すべての出力を方向づける」

ユウキは手元のプロジェクトを開いた。CLAUDE.md は空だった。

「何もない……」

「そう。手綱なしの馬に乗ってたってこと」

CLAUDE.md の読み込み階層

Claude Code は CLAUDE.md を複数の場所から読み込む。この階層構造を理解することが、ハーネス設計の第一歩だ。

Loading diagram...
ファイルスコープ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 を誤った方向に導く」

Loading diagram...

実践: ユウキの 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 禁止)
Loading diagram...

アンチパターン集

ミサキはユウキに、よくある失敗パターンも教えた。

アンチパターン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 は混乱する。階層の責務を明確に」

まとめ: 憲法は短く、明確に

Loading chart...

良い CLAUDE.md の5原則を意識すれば、AI エージェントは驚くほど一貫した出力を返すようになる。

ユウキは CLAUDE.md を書き上げた翌日、Claude Code に同じ「ユーザーダッシュボードを作って」と指示してみた。

今度は zod バリデーション付き、repository パターン経由の DB アクセス、named export のコンポーネントが生成された。

「これだ……! 同じ指示なのに、出力が全然違う」

「それがハーネスの力よ」とミサキは笑った。「でもまだ序章。次は Hooks——自動で品質を守る仕組みを教えるわ」