効果的なCLAUDE.mdを書くことは、どのセクションを含めるかを知ることではありません。多くのガイドはその部分をカバーしています。難しい問題は別にあります。Claudeが確実に従う命令の書き方、実際に動作を変える命令と無視される命令の違い、そしてCLAUDE.mdをなし崩しに悪化させる典型的なミスの知識です。
CLAUDE.mdとは何か・なぜ重要かの基礎はCLAUDE.md完全ガイドを参照してください。本記事は機能する命令を書くための技法に焦点を当てます。
実際のオープンソースプロジェクトの効果的なCLAUDE.mdサンプルはギャラリーで確認できます。
ステップ1:CLAUDE.mdに何が属するかを特定する
最もよくある間違いは、Claudeがデフォルトで既にやる動作を書くことです。これはトークンを追加するだけで何も変えません。
セクションを書く前に問いかけてください:「この命令なしに、Claudeはこのプロジェクトでどこでミスをするか?」
答えが「ミスしない、Claudeはこれを正しくやる」なら、書きません。
含める内容の有用なリストを作るには、プロジェクトでClaudeを実際に使いながら動作を観察して、何が間違っているかをメモするセッションを1回設けます。そのミスに対して具体的にCLAUDE.mdのエントリを書きます。
繰り返しの修正から。 先月Claudeに何を修正しましたか?「違う、うちではYではなくXを使う」と毎回入力していれば、それがCLAUDE.mdに属する内容です。
一貫性のない出力から。 Claudeが同じタイプのタスクでセッションごとに異なる結果を出す部分はどこですか?安定した命令がないので推測していることを意味します。
プロジェクト固有の知識から。 新入りエンジニアがDay 1に知る必要があって、READMEに書かれていないことは何ですか?非自明なコマンド、驚くべきアーキテクチャの選択、コードベースの落とし穴。
含めないもの:
- Claudeが既に従っている一般的なベストプラクティス
- 品質に関する命令(「クリーンなコードを書く」)— 動作を変えるには抽象的すぎる
- 人間の読者向けドキュメント — CLAUDE.mdはチームではなくClaudeが読む
ステップ2:具体的でテスト可能な命令を書く
CLAUDE.mdの命令の重要な属性は、Claudeがそれに従っているかをテストできることです。抽象的な命令はこのテストに失敗します。
抽象的(悪い例):
保守しやすく、よく整理されたコードを書く。
これはテストできません。このコードベースで「よく整理された」とは具体的に何を意味しますか?
具体的(良い例):
ユーティリティ関数をsrc/lib/にドメイン別に整理する:
- src/lib/auth.ts — 認証ユーティリティ
- src/lib/formatting.ts — 日付、数値、通貨フォーマット
- src/lib/api.ts — APIリクエストヘルパー
ユーティリティ関数をコンポーネントファイルに直接置かない。
これはテスト可能です:新しいユーティリティ関数が正しい場所に置かれるかどうか。
ポジティブルールパターン
可能な場合は、やることを伝える命令をやらないこと命令より優先します。
ネガティブな表現:
デフォルトエクスポートを使わない。
varを使わない。
クラスコンポーネントを書かない。
ポジティブな表現:
名前付きエクスポートのみを使う。
const/letを使う、varは禁止。
フックを使った関数コンポーネントを書く。
ポジティブな表現は目標の状態を説明するため、従うことも検証することも簡単です。
禁止事項の「代替案」パターン
禁止が本当にネガティブである必要がある場合は、承認された代替案とセットにします:
## APIコール
コンポーネントで直接fetch()を使わない。
代わりに: useApi()フック(src/hooks/useApi.ts)を使う。
認証ヘッダー、エラー状態、ローディング状態を自動で処理する。
「Xを使わない」だけでは、代わりに何をすべきかClaudeが推測するしかありません。「Xを使わず、代わりにYを使う」で推測をなくします。
ステップ3:スキャンしやすい構造にする
CLAUDE.mdは線形に読まれるのではなく、スキャンされます。Claudeはファイル全体をトークン化しますが、アテンションメカニズムは冒頭に現れるコンテンツ、行の先頭に現れるコンテンツ、明確な見出しの下にあるコンテンツを優先します。
最も重要なルールを先頭に置く。 他の何より重要なことが3つあるなら、明示的にそう伝えます:
## 最も重要な3つのルール
1. データベースに直接書き込まない — src/lib/db.tsを通す
2. 全APIエンドポイントに認証ミドルウェアが必要 — src/middleware/auth.tsを参照
3. PRを提案する前にnpm testを実行する
コードパターンにはコードブロックを使う。 コードパターンは説明より表示が速いです:
## インポート規約
# 正しい
import { createUser } from "@/lib/user";
import type { User } from "@/types";
# 誤り
import createUser from "@/lib/user"; // デフォルトエクスポートは禁止
import { User } from "@/types"; // 型インポートは`import type`を使う
ステップ4:CLAUDE.mdをテストする
CLAUDE.mdはClaudeがこれらの命令でどう動くかという仮説です。完成と見なす前にテストします。
空のコンテキストテスト。 新しいセッションを開始して、CLAUDE.mdが対応するように設計されたテストタスクを書き、タスク以外のプロンプトなしにClaudeが正しく動作することを確認します。
エッジケーステスト。 2つのルールが競合する可能性がある、または書かれたルールから正しい動作が明らかでない曖昧なシナリオを見つけます。Claudeが何をするかを確認します。間違いを選んだ場合、ギャップを発見しました。
トーンチェック。 新鮮な目でCLAUDE.mdを読みます。命令は明確ですか?Claudeではなく人間のREADME向けに書かれたと思われるセクションはありますか?文体は直接的で指示的であるべきで、説明的ではいけません。
よくあるミスと修正方法
ミス1:互いに矛盾する命令
# 矛盾
全スタイリングにTailwindを使う。
...
[10セクション後]
グローバルスコープの問題を避けるためコンポーネントスタイルにCSS Modulesを使う。
2つの命令が矛盾する場合、Claudeは一方を選んで進みます。もう一方の命令は実質的に死んでいます。確定前に矛盾をチェックします。
修正: CLAUDE.md内で同じトピックが複数の場所で言及されていないかを確認します。統合して矛盾を明示的に解決します。
ミス2:解釈に外部コンテキストが必要な命令
# 曖昧
エラーハンドリングについてチームの規約に従う。
Claudeは「チームの規約」にアクセスできません(定義しない限り)。この命令は何もしません。
修正: 外部コンテキストへの参照を実際の内容に置き換えます:
## エラーハンドリング
- 全てのthrowにカスタムAppErrorクラスを使う(src/lib/errors.ts)
- エラーコードを必ず含める: throw new AppError("ユーザーが見つかりません", "USER_NOT_FOUND")
- throwする前にsrc/lib/logger.tsからlogger.error()でログを記録する
- APIレスポンスに生のDBエラーを露出しない
ミス3:全て同じ重要度の多すぎるセクション
全てが重要とマークされると、何も重要でなくなります。同等の重みを持つ30セクションのCLAUDE.mdは、何が本当に重要かのシグナルをClaudeに与えません。
修正: 階層構造を使います:
# クリティカル — まずここを読む
[Claudeが絶対に間違えてはいけない3〜5つの事項]
# 開発規約
[このプロジェクトの標準的なコーディングパターン]
# リファレンス
[必要な時に参照すべき情報、暗記する必要はない]
ミス4:実際の失敗モードを観察する前にCLAUDE.mdを書く
しばらく使ってから書く前に詳細なCLAUDE.mdを書くのは時期尚早の最適化です。何の命令が重要になるかを推測しています。
修正: CLAUDE.mdなしで1〜2週間Claude Codeを使います。全ての修正をメモします。その観察ログからCLAUDE.mdを書きます。結果として得られるファイルは、推測で書いたものより短く、ターゲットが絞られ、効果的になります。
効果的なフォーマット規約
最も重要な単語は太字:
**常に**名前付きエクスポートを使う。デフォルトエクスポートは**絶対に禁止**。
コード例にインラインコメント:
// 正しい
const user = await db.findUser(id); // DBラッパーを使う
// 誤り
const user = await prisma.user.findUnique({ where: { id } }); // Prisma直接アクセス禁止
短い文を長い文より優先。 複数の節を含む命令は、単一節のルールより信頼性が低くなります。複雑なルールは複数行に分解します:
# 解析しにくい
TypeScriptのstrictモードを使うこと。これはtsconfig.jsonで
noImplicitAny、strictNullChecks、および全ての関連するコンパイラオプションを
有効にすることを意味します。
# 解析しやすい
TypeScript: strictモード必須。
有効にする: noImplicitAny、strictNullChecks。
設定ファイル: tsconfig.json。
調整済みスターターテンプレート
本当に重要なことだけを埋めさせる最小テンプレートです:
# [プロジェクト名] — Claude Code指示
## コンテキストなしで作業するために知っておくべきこと
[このプロジェクトが特殊または難しい理由を3〜5文で]
## 非自明なセットアップ
- ビルド: [コマンド]
- テスト: [コマンド]
- [この言語/フレームワークの典型的な規約と異なる点]
## 規約
### コードスタイル
[言語デフォルトと異なるルールのみ — Claudeを修正することになる内容]
### アーキテクチャ
[ファイル構造、モジュール境界、使うべき/避けるべきパターン]
### テスト
[テストフレームワーク、何をテストするか、何をテストしないか]
## 絶対にやらないこと
- [プロジェクトを壊す行為1] → 代わりに[代替案]をすること
- [行為2]
- [行為3]
このテンプレートから始めて、Claudeが間違いを犯したときだけ追加します。ターゲットを絞った効果的なルールを持つ200トークンのCLAUDE.mdは、Claudeが既に従っている命令で満たされた3,000トークンのCLAUDE.mdを上回ります。
本番プロジェクトの実際のCLAUDE.mdサンプルはギャラリーで確認できます。CLAUDE.mdが成長するにつれてトークン効率を保つ方法についてはトークン最適化ガイドを参照してください。