Claude Codeを継続運用していると、同じ種類の不具合が繰り返し発生することに気づきます。AIエージェントは会話が終わるとコンテキストを失うため、前回の失敗を覚えていません。この問題に対し、「不具合発生 → 根本原因分析 → CLAUDE.mdへのルール追記 → ルールの書き方自体の改善」というサイクルを回すことで、AIエージェントに組織知を蓄積する運用パターンを実践しています。2週間で20件以上のインシデントに基づくルールを蓄積した実体験から、このパターンの具体的な回し方、陥りがちな罠、そして最終的に到達した「メタルール」の概念を解説します。
基本サイクル: 不具合 → 教訓 → ルール追記
サイクルの流れ
1不具合発生2 │3 ├── 1. 根本原因の特定4 │ 何が起きた? なぜ起きた? なぜ防げなかった?5 │6 ├── 2. 再発防止策の策定7 │ コード修正 + 運用ルール追加8 │9 ├── 3. CLAUDE.mdへのルール追記10 │ Critical Rule として教訓付きで記録11 │12 └── 4. 既存の監視・チェックリストで防げたはずなら追加13 デプロイ前チェック、ヘルスチェック、ログ監視に反映具体例1: 修正後の意図検証を怠った
不具合: スクリプトのログディレクトリパスを修正した後、AIがスクリプトを実行せずにcommitしました。実行すると既存バグ(特定値を取得失敗と誤判定する条件分岐の問題)が発覚。さらにそのバグ修正で別の設定値が意図せず変更される副作用が発生しました。
問い: 「意図通りに動くかテストするよう指示があったのに、なぜ守れなかったのか?」
AIの反省: 「修正した箇所が正しく動くか」というコードレベルの確認で満足してしまい、「このスクリプトは何のために存在し、修正後にその目的を果たせるか」を検証しませんでした。
追加したルール(Critical Rule 9):
1### Critical Rule 9: 意図検証2修正したスクリプトは commit 前に必ず実行し、以下を確認する:31. exit code だけでなく、生成物・副作用を確認42. 修正が他のコンポーネントに波及していないか確認5
6**必須ゲート**: Edit/Write でコードを変更したら、Bash で動作確認を行い、7結果をユーザーに報告してから commit に進むこと。8「修正が単純だから動くはず」という判断で検証を省略してはならない。具体例2: スケジュール順序の見落とし
不具合: あるジョブ(07:00起動)が、データ生成ジョブ(07:10-07:14)の前に実行されていました。さらに別のジョブ(07:30)がデータファイルを処理後に削除するため、ファイルが存在しないタイミングで参照する状態が発生しました。
追加したルール(Critical Rule 10):
1### Critical Rule 10: launchdスケジュール設定はパイプラインの実行順序を考慮する2新しいジョブのスケジュールを設定する際は、データの Producer/Consumer 関係を確認し、3Consumer は Producer の完了後に実行されるよう時刻を設定すること。メタルールの誕生 — 「ルールの運用方法に関するルール」
具体例2の対応時、ユーザーから決定的な指摘がありました。
「不具合・サイレント障害が起きたとき、必ず再発防止策やデプロイ手順の見直しを行い、CLAUDE.mdに記録すること。すでにCLAUDE.mdに記載があるにもかかわらず守れなかった場合は、なぜルールを守れなかったか再度考え、CLAUDE.mdの記載内容を必ず再考すること。」
これにより**Critical Rule 11(再発防止プロセス)**が誕生しました。これは個別のコーディングルールではなく、**ルールの運用方法に関するルール(メタルール)**です。
1### Critical Rule 11: 再発防止プロセス21. **再発防止策の策定と記録**: 根本原因特定 → CLAUDE.mdに記録32. **運用プロセス全体の見直し**: デプロイ前チェック・ヘルスチェック・ログ監視で4 防げたはずなら追加53. **既存ルール違反の場合はルール記載内容を再考**:6 - なぜ守れなかったか分析7 - 抽象的 → 具体化8 - 埋もれている → 目立つ位置へ9 - 発動条件が不明確 → 条件を明示10
11原則: 「同じ障害を二度起こさない。ルールは『書いてある』だけでは不十分で、12『守れる形で書いてある』ことが重要。」メタルールが機能した例: ルールの書き直し
あるジョブが24時間以上継続しゾンビ化した障害で、最初に追記されたルールは不十分でした。
初版(不十分):
1メインループに15:30デッドラインのセーフティネットを追加すること改訂版(メタルール適用後):
1### 3つの根本原因の連鎖:2(a) 延長区間のエントリーに `is_processing_hours()` ガードを入れること3(b) `datetime.time()` の比較は日またぎで無効化される(Rule #7参照)4(c) 6時間以上動く可能性があるジョブにはPIDロック必須初版は「何を追加するか」だけでしたが、改訂版は「なぜ3つの原因が連鎖したか」を構造的に記述し、既存ルールへの相互参照も追加しています。
陥りがちな罠: ルールの蓄積 → 肥大化 → 遵守率低下
このサイクルには構造的な問題があります。2週間で20件のインシデントに対応すると、CLAUDE.mdに20個のCritical Rulesが追加されます。教訓のblockquote付きで各ルール15-30行 x 20個 = 300-600行です。
筆者のプロジェクトでは、CLAUDE.mdが726行 / 86KBに達しました。
皮肉なことに、ルールが増えすぎるとAIはルールを守れなくなります。コンテキストウィンドウの中で重要なルールが大量のテキストに埋もれ、結果として「ルールに書いてあるのに守れなかった」という事象が増えます。
対処: 教訓の分離と構造化
最終的に、以下の構造に落ち着きました。
CLAUDE.md(198行): ルール本文 + 安全パターンのみ
1### Critical Rule #7: 日時比較は日またぎを考慮する2→ 詳細: .claude/docs/CRITICAL_RULES_DETAILS.md分離ファイル: 教訓の詳細、過去の障害記録、具体的なコード例
これにより、AIは毎回198行のルール本文だけを読み、詳細が必要なときだけ分離ファイルを参照します。
このパターンの効果
2週間の運用で、以下の変化が見られました。
定量的:
- Critical Rules: 0 → 20個(教訓付き)
- デプロイ前チェックリスト: 15 → 29項目
- 同種障害の再発: 0件(追記済みルールに該当する障害の再発なし)
定性的:
- AIが「前回も同じパターンの障害がありました」と過去の教訓を引用するようになりました
- コードレビューの観点が増えました(例: PIDファイルのパス分離、
__pycache__クリア確認) - ルールの書き方自体が改善されました(抽象的 → 具体的、条件不明確 → 発動条件明示)
実践のポイント
1. ルールは「守れる形」で書く
悪い例: 「テストを十分に行うこと」 良い例: 「Edit/Writeでコードを変更したら、commitの前にBashで実行し、exit codeと生成物を確認してからcommitに進むこと」
2. 教訓は構造化する
1### Critical Rule #N: [タイトル]2[ルール本文(1-3行)]3
4> **教訓(日付)**: [何が起きたか1行]5> **根本原因**: [なぜ起きたか1行]6> **安全パターン**: [どうすれば防げるか1行]3. 肥大化したら分離する
目安として、CLAUDE.mdが200行を超えたら教訓の本文を分離ファイルに退避します。ルール本文と参照先だけをCLAUDE.mdに残します。
4. 既存ルールへの相互参照を追加する
新しいルールが既存ルールと関連する場合、「Rule #7参照」のように相互参照を入れます。AIがルール間の関係を理解しやすくなります。
まとめ
「不具合 → 教訓 → CLAUDE.md追記」のサイクルは、AIエージェントにチームの暗黙知を蓄積する有効なパターンです。しかし、蓄積だけでは肥大化して機能しなくなります。
最も重要な学びはメタルールの概念です。「ルールに書いてあるのに守れなかった」場合、ルールの内容ではなくルールの書き方に問題があります。抽象的なルールは具体化し、埋もれたルールは目立つ位置に移動し、発動条件が曖昧なルールは条件を明示します。
人間のチームマネジメントと同じで、「ルールを増やす」のではなく「守れるルールに育てる」ことが本質です。