概要
Claude CodeのCLAUDE.md(プロジェクトルートに置く指示ファイル)は、最初から完璧なものが書けるわけではない。私の場合、本番システムで発生した392件のインシデントを分析し、その教訓を1つずつCLAUDE.mdに反映していった結果、460行の「生きたドキュメント」に育った。
本記事では、インシデントの分類、CLAUDE.mdへの反映プロセス、そして「AIが同じ間違いを繰り返さない仕組み」の構築方法を記録する。
なぜ「指示書」が必要なのか
AIは文脈を忘れる
Claude Codeは1つのセッション内では優秀だ。しかしセッションが変わると、前回の決定事項を知らない。
1セッション1: 「この設計パターンはやめましょう」→ OK、採用しません2セッション2: 「この機能を実装してください」→ セッション1で却下したパターンで実装この問題の対策がCLAUDE.mdだ。プロジェクトルートに置いておくと、Claude Codeが毎回読み込む。ここに「やってはいけないこと」「守るべきルール」を書いておけば、セッションをまたいでも一貫性を保てる。
最初のCLAUDE.mdは20行だった
プロジェクト開始時のCLAUDE.mdは、以下のような内容だった。
1## Overview2Python製の自動化プロジェクト。PostgreSQL + TimescaleDB。3## Build & Test4pytest tests/ -v5## Architecture6_calcAnalyticsDatas/ → _putProcessDatas/ → 実行エンジンこれでは不十分だ。AIは「やっていいこと」と「やってはいけないこと」の境界を知らない。
392件のインシデント分析
どうやって392件集めたか
約2週間の運用期間(2025年9月末〜10月中旬)で発生した全エラーログ、Slack通知、手動修正の記録を集計した。1件のインシデントは「人間の介入が必要になった事象」と定義した。
5つのカテゴリ
| 原因分類 | 件数割合 | 具体例 |
|---|---|---|
| データパイプライン変更 | 30% | カラム追加時にDB DDL変更漏れ、Parquetスキーマ不整合 |
| テスト不足 | 20% | datetime JSON serialization未テスト、NULL値処理漏れ |
| デプロイミス | 20% | 環境変数未設定、plistパス誤り |
| モジュールインポート失敗 | 20% | 相対インポートがlaunchd環境で失敗 |
| launchd設定問題 | 10% | plist構文エラー、スケジュール設定ミス |
最も多かった「データパイプライン変更」
全体の30%を占めた最大カテゴリだ。典型的な発生パターン:
11. 分析プログラムに新しいカラムを追加22. 下流のDB挿入プログラムのDDLを更新し忘れる33. 本番で ArrowInvalid: Column X not found in schema エラー44. パイプライン全体が停止AIに「この分析プログラムに新しいカラムを追加してください」と依頼すると、指示通りカラムを追加する。しかし、そのカラムを使う下流プログラム(データベース挿入、レポート生成、Slack通知)への影響を自発的に調査してくれるとは限らない。
CLAUDE.mdへの反映プロセス
ステップ1:インシデントの根本原因を特定する
例えば「相対インポートがlaunchd環境で失敗」というインシデントの場合:
1表面的原因: ModuleNotFoundError: No module named 'core'2根本原因: 相対インポート(from core.shared.X import Y)が、3 launchd経由の実行ではPYTHONPATH未設定で解決できない4再発条件: launchd plistにPYTHONPATHが未設定 + 相対インポート使用ステップ2:ルールとして言語化する
1### インポートパターン(CI/CD自動検証・BLOCKING)2# 正しい絶対インポート3from _dataProcessingEngine.core.shared.metrics_risk_manager import MetricsRiskManager4
5# 相対インポート(CI BLOCKING失敗)6from core.shared.metrics_risk_manager import MetricsRiskManagerステップ3:教訓として文脈を残す
ルールだけでは「なぜこのルールがあるか」がわからない。教訓(背景)も併記する。
1> **教訓(2026-02-28〜03-06 Dry-Run全停止事故)**: `_dataProcessingEngine/core/` 内の2> `from core.shared.X import Y` という相対インポートが、別施策のデプロイによる3> インポートチェーン変化で顕在化し、7日間トリガーファイル生成が全停止した。4> **修正**: インポートブロックにload_dotenv()を追加。この「教訓」セクションが重要だ。AIは「なぜ禁止されているか」を理解すると、類似のパターンでも自発的に注意を払うようになる。
CLAUDE.mdに入れるべき5種類の情報
392件の分析から、CLAUDE.mdに記載すべき情報を5種類に整理した。
1. 絶対にやってはいけないこと(BLOCKING)
1#### 統合分析アーキテクチャの保護 破壊禁止2unified_analyzer.py に条件判定を追加しない。3トリガー条件は *TriggerFileGenerator.py に実装する。「やるな」と明示されていないと、AIは良かれと思って変更する。
2. よくあるエラーと解決策
1### よくあるエラー2| エラー | 解決策 |3|--------|--------|4| ModuleNotFoundError | export PYTHONPATH=... |5| ERR-5012 Invalid API-KEY | .env確認、外部APIキーを使用 |6| システム障害確率 > 5% | AI分析品質保証プロトコル適用(8項目チェック) |AIが同じエラーに遭遇したとき、無駄な試行錯誤を省ける。
3. デプロイ前チェックリスト
1### デプロイ前必須チェックリスト21. PYTHONDONTWRITEBYTECODE=1 が全plistに設定されているか32. PYTHONPATH が完全設定されているか43. __pycache__ クリア済みか54. plist 構文検証済みか(plutil -lint)65. テスト実行済みか(4,000+テスト)7...(全13項目)これをCLAUDE.mdに書いておくと、AIがデプロイ関連の作業をする際に自動的にチェックリストを参照する。
4. 過去のインシデントの教訓
1> **教訓(2026-03-24 リソース監視16日間無効化事故)**: monitor_resources.py が2> os.getenv("API_KEY") でAPIキーを取得していたが、launchd plistに未設定だったため、3> クライアントがNullのまま16日間リソース監視が全て無効化。4> **修正**: インポートブロックにload_dotenv()を追加。5. AI品質保証プロトコル
これは392件分析の中で最も重要な発見だ。AIが「システム障害確率が高い」「処理を停止すべき」と誤った結論を出すインシデントが複数発生した。
1#### AI分析品質保証プロトコル 重大判断前必須2
3**発動条件**:4- 本番運用の停止・変更推奨時5- システム障害確率 > 5% の結果報告時6- 過去検証の無効化判断時7
8**必須チェック(8項目)**:9スクリプト妥当性・CLI引数・データ期間・ファイル読み込み数・10過去検証・ベースライン比較・複数視点検証・ユーザー確認11
12**3秒ルール**: 「停止すべき」「緊急」「全て無効」等のフレーズを13使う前に8項目チェック必須。AIが「危険なので停止を推奨します」と言ったとき、それが正しいか検証するプロトコルだ。AIの分析結果を鵜呑みにしないための仕組みでもある。
460行のCLAUDE.mdの構成
最終的なCLAUDE.mdは以下の構成になった。
1Quick Start(開発環境のセットアップ) ~50行2Build & Test Commands(テスト実行方法) ~60行3Documentation Structure(ドキュメント配置) ~30行4Architecture(サブプロジェクト構成・パイプライン)~100行5Project Configuration(3環境の設定) ~50行6Critical Rules(最重要ルール6項目) ~80行7デプロイ前チェックリスト(13項目) ~50行8デプロイ後チェックリスト(4項目) ~20行9Git-Flowブランチ戦略 ~40行10Key References(関連ドキュメントへの参照) ~20行11合計: ~460行「最重要ルール」の6項目
- AI分析品質保証プロトコル --- 重大判断前の8項目チェック
- 統合分析アーキテクチャの保護 --- 特定ファイルへの条件判定追加禁止
- データパイプライン変更時の必須手順 --- 影響範囲分析の強制
- 絶対インポートパターン --- 相対インポートのCI BLOCKING
- launchd plistの環境変数ルール --- os.getenvとload_dotenvの使い分け
- plist生成の形式ルール --- plistlib.dump()のみ使用
6項目すべてが「過去のインシデントから生まれたルール」だ。抽象的なベストプラクティスではなく、実際に痛い目にあって追加した項目だ。
実際の効果
定量的な効果
| 指標 | Before | After |
|---|---|---|
| インシデント再発率 | --- | 96%削減(期待値) |
| Phase 1(ドキュメント整備)のみ | --- | 50%削減 |
| Phase 2(自動検証)追加 | --- | 85%削減 |
| Phase 5(mypy型チェック)追加 | --- | 90%削減 |
| P0-P2対策完了 | --- | 96%削減 |
定性的な効果
- AIが「この変更はデータパイプラインに影響しますので、IMPACT_ANALYSISを作成します」と自発的に言うようになった
- デプロイ前にAIが自動的にチェックリストを実行するようになった
- 「3秒ルール」により、AIの誤った分析結果による運用停止が0件になった
学んだこと
1. CLAUDE.mdは「育てる」もの
最初から完璧なCLAUDE.mdを書こうとしても無理だ。運用しながらインシデントが発生するたびに追記していく。20行から始めて460行になるのに約4ヶ月かかった。
2. 「教訓」の記載がルールの実効性を高める
「やるな」だけではなく「なぜやってはいけないか」を書く。AIは理由を理解すると、記載されていない類似パターンにも対処できるようになる。
3. AI品質保証プロトコルは「AIへの不信感」ではなく「仕組み」
AIの出力を信頼しないのではなく、「重大な判断をする前に検証する」プロセスを設けること。人間のエンジニアのコードレビューと同じ発想だ。
4. チェックリストは13項目が限界
チェックリストが長すぎると形骸化する。13項目(デプロイ前)は「多いが全項目確認可能」なギリギリのラインだと感じている。
まとめ
CLAUDE.mdをインシデントから育てるプロセスで重要なのは以下の3点だ。
- インシデント分析 → ルール化: 392件の障害を5カテゴリに分類し、再発防止策をルールとして言語化。「やるな」だけでなく「なぜやるな」を記載
- 段階的な効果: ドキュメント整備だけで50%削減、自動検証で85%、型チェックで90%、品質保証プロトコルで96%。一度に全部やる必要はない
- AI品質保証プロトコル: AIの分析結果を鵜呑みにしない仕組み。8項目チェックと「3秒ルール」で誤判断を防止
CLAUDE.mdは「AIへの指示書」であると同時に、「プロジェクトの運用知識のデータベース」だ。インシデントが起きるたびに賢くなるこのファイルが、AI駆動開発の安定性を支えている。