「書いたのに守られない」を卒業する
Claude Codeを本格運用しはじめたチームが必ず通る通過儀礼があります。 CLAUDE.md に「テストはこう書いて」「このAPIは使わないで」と書いたのに、 数日後には平然と無視される、あるいは半年後にCLAUDE.mdが600行に膨れ上がって誰も読まなくなる ── という現象です。
原因の8割は「モデルが言うことを聞かない」ことではなく、 ルールの書き方と運用設計が悪いことにあります。 人間の新メンバーに対して「就業規則の600ページを毎朝読み直してから仕事して」と要求しないのと同じで、 Claudeに対しても「読みやすく、優先度が明確で、寿命管理されたルール」を渡す必要があります。
この記事では、「Claude Code設定のベストプラクティス」が"場所と種類"の話だったのに対し、 ここでは"ルールという情報をどう設計し、どう育てるか"に絞って整理します。 対象はClaude Codeを想定しますが、原則の大半はClaude Agent SDKや他のAIエージェント運用にも応用できます。
なぜルールは守られないのか
「CLAUDE.mdに書いたのに守られない」と感じるとき、 実際に起きているのはほぼ次の5パターンのいずれかです。 モデルを責める前に、ルール側に問題がないか棚卸ししてみましょう。
| 失敗モード | 症状 | 根本原因 |
|---|---|---|
| 抽象すぎる | 「丁寧に書いて」が守られない | 具体的な数値・形式・例がない |
| 否定形だらけ | 「使わないで」と書いたAPIをむしろ多用する | 否定対象に意識が引きずられる |
| 埋もれている | 600行のCLAUDE.mdの中盤に書かれている | コンテキスト後半は注意が薄れる |
| 競合している | AとBの指示が暗黙に矛盾している | 優先順位が明示されていない |
| 条件が広すぎる | PR用の指示が普段のチャットでも適用される | Skill/Hookで条件分岐すべきものを常時ロードに混ぜている |
ルールの3階層 — どこに何を置くか
ルールは置き場所によって「いつロードされるか」「誰に効くか」「Git管理されるか」が変わります。 正しい階層に置かないと、本来不要な場面でもコンテキストを食い、 本当に必要な場面で読まれない、という両方の失敗が同時に起きます。
graph TB
subgraph "Tier 1: 常時ロード(コア)"
A["~/.claude/CLAUDE.md<br/>個人共通指示"]
B["{root}/CLAUDE.md<br/>プロジェクト不変ルール"]
end
subgraph "Tier 2: 条件付きロード"
C[".claude/rules/*.md<br/>領域別ルール"]
D["Skill/Agent定義<br/>用途特化ルール"]
end
subgraph "Tier 3: 実行時強制"
E["Hooks (settings.json)<br/>機械的に守らせる"]
F["Permissions<br/>そもそも実行不可にする"]
end
A --> B
B --> C
B --> D
C --> E
D --> E
E --> F
classDef t1 fill:#3b82f6,stroke:#1e40af,color:#fff
classDef t2 fill:#8b5cf6,stroke:#6d28d9,color:#fff
classDef t3 fill:#10b981,stroke:#047857,color:#fff
A:::t1
B:::t1
C:::t2
D:::t2
E:::t3
F:::t3
Tier 1は毎セッション必ず読まれるのでコンテキストコストが高い。 ここに置けるのは「全タスクに通底する不変の前提」だけです。 逆にTier 3はモデルの解釈を介さない強制力があるため、 「本当に守らせたい」ものはルールではなくHookやPermissionに昇格させるのが最も確実です。
| 置き場所 | 何を書く | 書いてはいけないもの |
|---|---|---|
~/.claude/CLAUDE.md | 言語設定・個人の応答スタイル・全プロジェクト共通の癖 | プロジェクト固有情報・チーム規約 |
{root}/CLAUDE.md | 技術スタック・主要コマンド・全タスクで意識すべき不変ルール | 一部のタスクでしか使わない手順・3ヶ月後に消える可能性のあるルール |
.claude/rules/*.md | テスト規約・PR運用・特定領域の設計指針など条件付きルール | 常に効かせたい不変ルール(CLAUDE.mdに書く) |
.claude/skills/*/SKILL.md | 特定ワークフロー専用の手順・テンプレ・チェックリスト | プロジェクト全体の不変ルール |
settings.json Hooks | 「絶対に」やらせたい/やらせたくない処理(lint、commit前のテスト等) | 柔軟な判断が必要なもの |
良いルールの5原則
どの階層に置くにせよ、ルール本文の書き方には共通の原則があります。 Anthropic公式のClaude Code/Agent SDKドキュメントと、 Tier 1企業の運用知見に共通して登場する5つを整理します。
| 原則 | 悪い例 | 良い例 |
|---|---|---|
| 1. 肯定形で書く | 「絵文字を使わないで」 | 「絵文字は省略する。必要な場合のみ user が明示的に求める」 |
| 2. 数値で書く | 「コメントは控えめに」 | 「コメントは1関数につき最大1行。WHYのみ書きWHATは書かない」 |
| 3. WHYを併記する | 「any型禁止」 | 「any型禁止 — 過去にプロダクトで型崩れ起因のP1障害が3件発生したため」 |
| 4. 例を1つ載せる | 「コミットメッセージは英語の動詞始まり」 | 「Add user invite endpoint のように動詞始まり。updated xのような過去形は不可」 |
| 5. 適用範囲を明示する | 「テストを書く」 | 「src/components/quiz/**/*.tsxを編集した場合は同名の*.test.tsxを更新する」 |
特に重要なのは"WHY"を書くこと
5原則のうち、運用上もっとも効くのが「3. WHYを併記する」です。 理由は単純で、WHYがあるルールは時間が経っても削除判断ができるからです。 「なぜか書いてある禁止事項」は、誰も理由を知らないので消すに消せず、 10個20個と溜まって最終的にCLAUDE.mdの肥大化要因になります。
# Bad(理由なし。半年後に誰も触れなくなる)
- API呼び出しは fetch ではなく axios を使う
# Good(廃止判断ができる)
- API呼び出しは fetch ではなく axios を使う
- Why: タイムアウト設定とリトライハンドリングを共通化する社内ラッパー @company/http が
axios前提で実装されているため
- Apply: src/server/**/*.ts と src/lib/api/**/*.ts に対して適用
- Sunset: @company/http が fetch ベースに移行する 2026 Q3 で見直し 条件付きルールはオンデマンドで注入する
領域別のルール(テスト規約・PR運用・セキュリティチェックリストなど)を すべてCLAUDE.mdに書くと、毎セッションでコア200行を超えます。 解決策は「条件が成立したときだけロードする」設計です。 Claude Code/Agent SDKでは主に3つの仕組みが使えます。
| 仕組み | いつロードされるか | 向いている用途 |
|---|---|---|
| サブディレクトリのCLAUDE.md | そのディレクトリ内のファイルを読み書きしたとき | 領域別の暗黙ルール(例: src/server/CLAUDE.mdでAPI規約) |
| .claude/rules/*.md + 参照 | CLAUDE.mdから明示的に参照したとき、または手動添付 | 長くなるテスト規約・運用Runbookの分離 |
| Skill (SKILL.md) | スキル名がトリガーされたとき(user指示 or 自動) | 記事生成・レビューなどワークフロー特化の手順 |
特にSkillは「手順とテンプレートをルールごとパッケージ化」できる強力な仕組みです。 たとえばPRレビューSkillに「セキュリティ7項目チェックリスト」を埋めておけば、 CLAUDE.mdからはそのチェックリストを完全に外して、レビュー時のみコンテキストに乗せられます。
sequenceDiagram
participant U as User
participant C as Claude
participant CM as CLAUDE.md (Tier1)
participant S as Skill (.claude/skills/)
participant R as rules/*.md (Tier2)
Note over CM: 起動時に常時ロード
U->>C: 「PRレビューして」
C->>CM: コアルール参照
C->>S: review Skillをトリガー
S-->>C: チェックリスト+手順を注入
C->>R: 関連rule.mdを参照
R-->>C: テスト規約をロード
C->>U: レビュー結果ルールにはライフサイクルがある
ルールは「書いて終わり」ではありません。 人間のチームに新人が入るたびにオンボーディング資料が更新されるように、 Claudeに対するルールも追加→運用→更新→廃止のサイクルを回す必要があります。
追加 — 失敗から書き始める
Claudeが3回以上同じ失敗をしたら初めてルール化する。1回目はモデルに直接フィードバック、2回目で気をつける、3回目以降で再現性のあるパターンとして採録。最初からルールで縛るとノイズが増える。
検証 — 効いているか観測する
ルール追加後、同じ条件で5〜10回タスクを回して遵守率を見る。半分以上守られないなら「具体性が足りない」「Hook化すべき」のどちらか。書き直すか実行時強制に昇格させる。
運用 — 周辺ルールとの整合をとる
新しいルールが既存ルールと競合していないかを確認。競合があれば優先順位を明示するか、片方を統合する。CLAUDE.mdが増える方向ではなく、再構成する方向で動く。
棚卸し — 死んだルールを消す
四半期ごとに全ルールを「Why(なぜ書いたか)」「直近で破られたか」「ライブラリ/方針が変わって不要になっていないか」の3軸でレビュー。Sunsetを過ぎたものや形骸化したものを削除する。
構造刷新 — 階層を見直す
年に1回、Tier 1/Tier 2/Tier 3 の配分を見直す。Tier 1が肥大化しているなら条件付きへ降格、頻繁に破られるルールはHookへ昇格。CLAUDE.mdは"洗練された薄い層"を保ち続ける。
ルールとメモリーは別物
Claude Codeにはメモリー機能(自動メモリー、またはmemory/ディレクトリ)もあり、
「これってルールに書くべき?メモリーに保存すべき?」と迷う場面が増えています。
両者は性質が異なる別レイヤーと捉えるのが正しい設計です。
| 観点 | ルール(CLAUDE.md / rules/) | メモリー |
|---|---|---|
| 性質 | 規範(こう書くべき・こう振る舞うべき) | 事実(過去にこうだった・ユーザーはこう) |
| 共有範囲 | チーム全員(Git管理) | 個人セッション固有 |
| 更新頻度 | 低い(四半期〜年単位) | 高い(会話のたびに追加) |
| 典型例 | 「テストは正常系+異常系+境界値で最低3ケース」 | 「ユーザーは音声AI領域に詳しい」「先週Vercelに移行した」 |
| 失敗時のリスク | チーム全体に波及 | そのセッションのみ |
実務では「規範はルール、事実はメモリー」と覚えると迷いません。 ユーザーの好みや過去の決定事項を全部CLAUDE.mdに書くのは肥大化のもとですし、 逆にチーム規約をメモリーに入れるとチーム全員に伝わらず属人化します。
運用アンチパターン
典型的な失敗を最後にまとめます。これらは「ルール本文の書き方」ではなく、 運用設計レベルでの失敗なので、いくら個別ルールを磨いても効果が出ません。
| アンチパターン | なぜ起きるか | 処方箋 |
|---|---|---|
| CLAUDE.mdが600行を超えている | 「念のため書く」を繰り返した結果 | 50%カット目標で棚卸し。条件付きルールはrules/かSkillに移す |
| "why"のないルールが並んでいる | 書き手が異動・退職して理由が失われた | why不明のルールは1ヶ月の猶予を経て削除(or 確認) |
| 同じ趣旨のルールが2箇所に書かれている | CLAUDE.mdとrules/で別の人が別タイミングで書いた | rules/を正本に統一しCLAUDE.mdからは参照のみ |
| ルールが矛盾している | 段階的に追加した結果、暗黙に競合 | ルール追加時に必ず「これは既存のどれを上書きするか」を明示する |
| Hookで実現できるものをルールにしている | まずCLAUDE.md、が反射になっている | 「これは判断不要で機械的に強制すべきか?」を毎回問う |
| 個人の好みがCLAUDE.mdに混ざっている | グローバル設定との切り分け不徹底 | 個人指示は~/.claude/CLAUDE.mdかCLAUDE.local.mdへ |
チームへの導入 — 巻き込みのコツ
ルール運用が本当に難しくなるのは、自分一人ではなくチーム全体で運用するときです。 個人で書いたルールがチームに刺さらない、 チームメンバーが各自CLAUDE.mdに追記してマージ地獄といった現象が起きがちです。 運用の型を3つ紹介します。
- ルール追加はPRで提案する: CLAUDE.md / rules/ への変更はPRを必須にし、Why・Apply・Sunsetを記載必須項目にする。レビュアーは「これはCLAUDE.mdか?rules/か?Hookか?」を毎回問う。
- "AI Lead"ロールを置く: ルールとSkillの整合・棚卸しに責任を持つ役割を1人決める。テックリードと別ロールにしておくと、運用視点が独立して保たれる。
- 失敗事例を共有する場をつくる: 「Claudeにこう失敗された」「このルールが効いた/効かなかった」をSlack等で気軽に共有できる文化が、3回ルールの起点になる。
- 定例で棚卸しする: 四半期1回、30分でいいので「ルール棚卸し会」を開催し、死んだルールを葬る。これがないと一方向に肥大化する。
- 新メンバーにルール構造を説明する: 入社オンボーディングで「うちのCLAUDE.md・rules・Skillはこう分業している」を15分でも説明すると、その後の運用負荷が劇的に下がる。
まとめ — ルールは"書く"より"育てる"
Claudeのルールは、書いた瞬間が完成ではなく、書いた瞬間が始まりです。 本記事の要点を改めて整理します。
- 守られない原因はモデルではなく書き方。抽象・否定形・優先順位不明・条件範囲過大の4つを疑う
- 3階層で配置する: 常時ロード(CLAUDE.md)、条件付き(rules/・Skill)、実行時強制(Hooks・Permissions)
- 5原則で書く: 肯定形・数値化・Why併記・例の併記・適用範囲明示
- WHYとSunsetを書く。理由のないルールは廃止判断ができず、肥大化の最大要因になる
- 3回ルールで追加し、四半期で棚卸しする。書きっぱなしのルールは半年でノイズになる
- 規範はルール、事実はメモリー。両者を混ぜないことで肥大化と属人化を同時に防げる
- 守らせたいならまず実行不可にする。ルールはあくまで判断補助、強制はHook/Permissionの仕事
600行のCLAUDE.mdは、書き手の安心と引き換えに、Claudeの判断力とコンテキストを削ります。 「薄いコア + 賢い分割 + 機械的強制」の3点セットで、 ルールを"書く対象"から"育てる対象"へとアップデートしていきましょう。
理解度チェック
本記事で紹介された「良いルールの5原則」に含まれないものはどれですか?
キーボード: 1〜4 で選択、Enter で回答