この記事はHRBrainアドベントカレンダー12日目の記事です
はじめに
AIエージェント(Claude Code、GitHub Copilot等)を活用した開発を続ける中で、私自身がある課題に直面しました。それがコンテキスト喪失問題です。
この記事では、複数フェーズに分かれたパフォーマンス改善プロジェクトで実践した「docsディレクトリを活用したドキュメント駆動開発」の手法を紹介します。Serena memoryなど他のアプローチとの使い分けを含め、実践を通じて見えてきた良さそうな運用方法をお届けします。
AIとの協働で生じたコンテキスト喪失問題
直面した課題
担当したパフォーマンス改善プロジェクトでは、Claude Codeを活用して複数フェーズに分けて調査・実装を進めていましたが、思わぬ問題に直面しました。
問題1: auto compactによる情報喪失
Claude Codeにはauto compactという機能があり、会話が長くなると自動的に要約して古い情報を圧縮します。トークン消費を抑える便利な機能ですが、過去の調査内容の詳細が要約で失われ、「なぜこの判断をしたか」を後から思い出せなくなる問題がありました。
序盤: DataDog分析 → 7つのボトルネックを特定
中盤: Phase 1実装
後日: (auto compactが発動)
→ 「序盤で何を調査したか」の詳細が失われる
→ "7つのボトルネック"の内訳がわからない
→ 再度DataDog分析から始める羽目に
重要な設計判断の根拠が消え、「なぜこの方針にしたか」が思い出せなくなりました。
問題2: レビュー時の文脈不足
AIとのやり取りで似たようなことがあり、PRレビューでも同様の問題が想定されます。たとえば、レビューを依頼すると質問が来ます。
レビュワー: 「なぜINNER JOINにしたんですか?LEFT JOINじゃダメなの?」
自分: 「確か...3つの選択肢を比較して...」
→ 正確な比較結果を思い出せない
→ PRコメントで長文説明を書く
→ それでも「なぜ」が伝わりきらない
問題3: 後日の振り返りが困難
同様に、将来別の開発者から質問を受けた際の課題も考えられます。
開発者: 「このクエリ、なぜ特定のIDでの絞り込みがないんですか?」
自分: 「あー、それは...特殊なケースへの対応で...」
→ compactされた会話履歴からは読み取れない
→ git blameしてもコミットメッセージに詳細なし
→ 30分かけて当時の記憶を掘り起こす
なぜドキュメント化が必要か
AIエージェントは「明示的な情報」がないと推測できません。人間なら「前に話した件」で通じますが、AIはcompactで要約された情報しか持っていません。
また、コードやコメントでは「何を」しているかや実装レベルの「なぜ」はわかりますが、設計判断レベルの「なぜ」(複数の選択肢からなぜこれを選んだか、どんなトレードオフがあったか)は読み取れません。この根拠が失われると、将来のメンテナンスで同じ落とし穴にはまります。
このような経験から、設計判断を記録する仕組みが必要だと感じました。
アプローチの提案: docsディレクトリの活用
基本コンセプト
私が実践してみたのは、プロジェクトごとにdocsディレクトリを作成し、調査結果や設計判断を記録する手法です。
特徴:
- コードと同じリポジトリでgit管理
- Markdown形式(AIが読みやすい)
- PRからリンク可能(レビュワーへの文脈提供)
- 変更履歴が追跡可能(git blame)
他のアプローチとの関係
情報を記録する手段は、docsディレクトリだけではありません。
Serena MCPのmemory機能を使えば、AIエージェントがローカルに情報を保存し、次回セッションで自動読み込みできます。tmpディレクトリ(git管理外) を活用すれば、センシティブな検証データを一時的に保存できます。
このアプローチは、それらを置き換えるものではありません。それぞれの特性を理解し、適材適所で使い分けるのが良さそうです。詳細は後述します。
実践例: パフォーマンス改善プロジェクト
プロジェクト概要
- 課題: 大量データの検索に時間がかかる
- 目標: 半分以下に短縮
- 規模: 複数フェーズに分けて実施
- 結果: 約60%改善を達成
ドキュメント構成の例
実際にはもっと試行錯誤がありましたが、振り返って整理するとこのような構成が良さそうです。
docs/performance_improvement/
├── README.md # プロジェクト概要、ドキュメント一覧
├── 01_performance_analysis.md # 初期分析結果(複数のボトルネックと改善案)
├── 02_improvement_plan.md # 4フェーズの段階的改善計画
├── 03_optimization_detail.md # 各フェーズの詳細設計
├── 04_design_decisions.md # 実装中に発見した問題と設計判断
└── 05_performance_results.md # 最終的なパフォーマンス測定結果
ドキュメントの運用では、重大な誤りがあれば既存ファイルを更新し、新しい問題が発見されたら追加します。ただし、無制限に増やすとドキュメントが膨れ上がるため、適度に整理することも大切です。
運用フローのイメージ
このようなパフォーマンス改善プロジェクトでの、大まかな流れとしては以下のようになります。
1. パフォーマンス分析:
DataDog等で分析し、01_performance_analysis.md に出力(ボトルネックと改善案)
2. 改善計画策定:
02_improvement_plan.md 作成(複数フェーズの計画)
3. 詳細設計:
03_optimization_detail.md 作成(実装方針、テスト方針)
4. 実装とテスト:
リファクタ前後のデグレを防ぐためのテストを追加し、実装を進める
5. 実装中に課題発見時:
04_design_decisions.md に判断根拠を記録
6. 結果計測:
05_performance_results.md に最終測定結果を記録
7. PR作成時:
PR本文に docs へのリンクを記載
docsディレクトリの活用と使い分け
docsディレクトリは万能ではありません。Serena memory、tmpディレクトリと併用し、適材適所で使い分けるのが良さそうです。
docsディレクトリの特徴
1. チーム全体での文脈共有
git管理されているため、PRからリンクでき、チーム全体で文脈を共有できる点がSerenaやtmpとの違いです。レビュワーは設計判断の背景をdocsで理解でき、実装者も詳細をdocsに記載しておくことでレビューが効率的に進みます。
2. 設計判断の記録
設計判断をドキュメント化しておくことで、将来の参考資料になります。
## 2. 特殊データ構造への対応
### 発見経緯
特定のデータパターンでエラー発生
親子関係を持つデータの場合のみ再現
### 原因分析
関連テーブル間でデータ間の参照関係が複雑なケースがあり、
最適化したクエリが失敗する
### 検討した選択肢
1. 絞り込み条件を維持、特殊ケース用に分岐処理
- メリット: クエリ効率最大化
- デメリット: 複雑化、テストコスト増
2. 絞り込み条件を緩和
- メリット: シンプル、既存動作維持
- デメリット: 一部の絞り込み効率低下
### 判断
選択肢2を採用
- 理由: パフォーマンス改善を維持、複雑化回避
- 測定結果: 他の条件で十分に絞り込める
git blameでこのドキュメントを見つければ、「なぜ特定のIDでの絞り込みがないのか」を理解できるでしょう。
3. PRでのリンク共有
PR本文でdocsにリンクすることで、レビュワーに必要な文脈を提供できます。
# パフォーマンス改善
## レビュワー向け詳細
### アーキテクチャ概要
クエリ構造の最適化
詳細: `docs/performance_improvement/03_optimization_detail.md`
### ⚠️ 重要な設計判断
特殊ケース対応のための条件緩和など、パフォーマンス改善に伴う既存動作の変更
詳細: `docs/performance_improvement/04_design_decisions.md`
### パフォーマンス結果
約60%改善を達成
詳細: `docs/performance_improvement/05_performance_results.md`
他の選択肢との比較
開発中の情報を保存する手段は主に3つあります。
選択肢1: Serena memory
- SerenaはAIエージェント向けのローカルストレージツール(MCPサーバー: AIエージェントが利用できる外部ツール)
- write_memoryでプロジェクト情報を保存
- ローカル(~/.serena/memories/)に保存
- 次回セッションで自動読み込み
- メリット: AIがファイルを読む必要がないため、context消費が少ない
選択肢2: tmpディレクトリ
- プロジェクト内のtmp/ディレクトリ
- git管理外(.gitignoreで除外)
- セッション中の一時ファイル
- メリット: Serenaと違い、生データや検証SQLなど大容量ファイルも保存可能。センシティブ情報もgitに残らない
選択肢3: docsディレクトリ
- project/docs/
- git管理、PRでリンク可能
- チーム全体で共有
- メリット: git blame可能、チームで文脈共有
| 保存先 | 使うケース | 主なメリット |
|---|---|---|
| Serena memory | 環境情報、個人メモ、進行中のタスク、頻繁に参照する情報 | context消費が少ない、git汚さない |
| tmp/ | 検証SQL、測定生データ(数MB)、中間成果物 | 大容量ファイルOK、センシティブ情報OK |
| docs/ | 設計判断、チーム共有、PR資料 | git管理でチーム共有、blame可能 |
実例:
- Serena: テスト用DB接続情報、よく使う関数の場所、進行中のタスク(context消費を抑えたい、compact対策)
- tmp: 検証SQL、測定生データ2万行(大容量でdocsには不適切)
- docs: 権限チェック動作変更の判断根拠(チームで共有すべき)
使い分けの判断基準
迷ったら「3ヶ月後の自分が見て、この判断の理由がわかる必要があるか?」を考えます。
- Yes(チームで共有すべき) → docs
- No(個人メモで十分) → Serena memory
- 大容量データ、センシティブ情報 → tmp
課題と対策
何をドキュメント化すべきか
ドキュメント化すべき: 複数の選択肢を検討した設計判断、非自明なトレードオフ、既存動作との違い
ドキュメント化不要: コードを見ればわかる実装、一時的な検証結果、中間成果物
判断が分かれるもの: パフォーマンス測定結果など。PRには必要だが、測定環境が変わると陳腐化する可能性もある。ただし「このPR時点でのパフォーマンス」という参考資料としての価値はある。tmpに置いてPR本文に記載する選択肢もある。
AIへの指示のコツ: 「すべて」ではなく、出力内容を具体的に指定する。
"ボトルネック分析結果と改善方針を01_performance_analysis.mdに出力。
測定生データはtmp/に保存。各ボトルネックは簡潔に。"
情報のライフサイクルと運用
検証中の仮説はtmpへ、結論が出たらdocsへ移します。docsディレクトリは完了した判断の記録に徹し、進行中のタスクはtmpやSerena、Issue/PRで管理します。
- 検証中: tmp/(複数の仮説を試行)
- 結論後: docs/(結果と判断理由のみ)
- 進行中: Serena(メモ)、Issue/PR(タスク管理)
設計方針が根本的に変わったら更新し、ドキュメントには作成日・最終更新日を記載します。
役割分担の目安:
- docs: 設計判断レベルの「なぜ」(複数の選択肢から選んだ理由、トレードオフ)
- コードコメント: 実装レベルの「なぜ」(なぜここでキャッシュクリアするか等)と「何を」(処理の説明)
まとめと実践的な判断基準
docsアプローチが有効なプロジェクト
推奨する場合:
- 長期にわたるリファクタリングや改善プロジェクト
- 複雑な設計判断が複数ある場合
- レビュワーが複数人、または実装者以外の場合
- AIエージェントとの協働で頻繁にセッション中断・再開がある場合
実例:
- パフォーマンス改善(本記事の例)
- 大規模リファクタリング
- アーキテクチャ変更
不要な場合:
- 小規模バグ修正(1日で完了)
- 自明な実装(設計判断が不要)
- 個人プロジェクト(レビュー不要)
Serena / tmp / docs の使い分けまとめ
情報の性質で判断:
| 情報の種類 | 保存先 |
|---|---|
| 環境情報、個人メモ | Serena memory |
| 中間成果物 センシティブ情報 |
tmp/(gitignore) |
| 設計判断、意思決定 チーム共有が必要 |
docs/(git管理) |
最後に
Serenaやtmpでローカルにコンテキストを保持するだけでなく、docsディレクトリにgit管理で記録することで、チームでの文脈共有や将来の振り返りがしやすくなります。プロジェクトの規模や性質に応じて、Serena memory、tmpディレクトリと併用しながら柔軟に使い分けると良いかもしれません。