「さっき説明したのに、また同じことを聞いてくる」。Claude Codeを使い込んでいるエンジニアなら、一度はこの不満を感じたことがあるはずだ。
セッションが切れるたびに文脈がリセットされる。プロジェクトのアーキテクチャも、チームの命名規則も、前回までに決めた方針も、すべてゼロから説明し直しになる。
これはLLMの記憶が「セッション単位」で閉じているために起きる問題だ。この記事では、Claude Codeに長期記憶を持たせる3つの方法を紹介する。
なぜClaude Codeは「忘れる」のか
LLMには永続的な記憶がない。Claude Codeが認識できる情報は、そのセッション中にコンテキストウィンドウに載っている情報だけだ。
セッションが終わればコンテキストも消える。翌日同じプロジェクトで作業を再開しても、Claude Codeにとっては「はじめまして」の状態だ。毎朝記憶を失う同僚がチームにいるようなものである。
この問題の解決策は、外部ファイルに記憶を書き出し、セッション開始時に読み込ませることだ。要は「記憶の外部化」である。
方法1: CLAUDE.md による静的記憶
一番手っ取り早い方法だ。
CLAUDE.mdはClaude Codeがセッション開始時に自動で読み込むファイルである。プロジェクトルートに配置すると、そのプロジェクトで作業するたびにClaude Codeが参照する。
# CLAUDE.md
## プロジェクト概要
Next.js 14 + TypeScript + Prisma + PostgreSQLのWebアプリケーション。
Repository Patternでデータアクセス層を分離している。
## コーディングルール
- 型定義は src/types/ に集約する
- any型は禁止。unknownを使う
- テストはArrange-Act-Assertパターンで書く
- コミットメッセージはConventional Commits形式
## 現在の作業状態
- 認証機能のリファクタリング中(src/auth/)
- v2.0マイグレーションの準備段階
CLAUDE.mdの本質は「自分の取扱説明書」だ。チームに新しいメンバーが入ったとき、最初に渡すオンボーディング資料に近い。
メリット: セットアップが簡単。ファイルを1つ置くだけ。Gitで管理でき、チーム全員が同じ文脈を共有できる。
限界: 手動で更新する必要がある。情報が古くなっても自動では更新されない。セッション中に学んだことは次のセッションに引き継がれない。
CLAUDE.mdはグローバル(~/.claude/CLAUDE.md)とプロジェクト単位の2階層で配置できる。個人の作業スタイルはグローバルに、プロジェクト固有のルールはプロジェクトルートに書くと整理しやすい。
方法2: MEMORY.mdによる動的記憶
CLAUDE.mdの「更新されない」という限界を補うのがMEMORY.mdパターンだ。
Claude Codeの自動メモリ機能を使うと、セッション中に学んだ情報をファイルに書き出し、次のセッションで自動的に読み込む仕組みを構築できる。
# MEMORY.md
## ユーザープロファイル
- 専門領域: TypeScript, Next.js, Context Engineering
- 作業スタイル: 段階的実装を好む
- 説明の好み: コード例を含む実践的な説明
## 継続中のプロジェクト
### 認証リファクタリング
- 状況: Phase 2(トークン管理の移行)
- 決定事項: JWTからセッションベースに変更(2026-04)
- 残タスク: ミドルウェアの書き換え、テスト追加
## 重要な決定事項
- 2026-04-15: Repository PatternからService層を分離する方針に変更
- 2026-04-20: E2EテストはPlaywright、単体テストはVitest
CLAUDE.mdが「チームの共通ルール」なら、MEMORY.mdは「個人の作業日誌」だ。セッションごとに蓄積される決定事項や進行状況がここに記録される。
更新ルールの設定が重要だ。 何でもかんでも記録するとファイルが肥大化してコンテキストウィンドウを圧迫する。以下のような基準を設けておくとよい。
| 記録するもの | 更新頻度 | 例 |
|---|---|---|
| 重要な設計判断 | 発生時に即記録 | 「JWTからセッションベースに変更」 |
| 作業の好み | 3回以上同じパターンで | 「コード例を先に出す説明を好む」 |
| プロジェクト状況 | 週1回以上 | 「Phase 2完了、Phase 3着手」 |
| 6ヶ月以上前の詳細 | 要約 or 削除 | 古い決定事項を1行に圧縮 |
方法3: メモリアーキテクチャの段階的導入
規模の大きいAIエージェントシステムでは、4種類のメモリアーキテクチャを状況に応じて使い分ける。
| アーキテクチャ | 仕組み | コスト | 適する場面 |
|---|---|---|---|
| バッファ | 直近N回の会話をそのまま保持 | 低 | 短いセッション |
| サマリー | 古い会話をLLMで要約して保持 | 中 | 長時間の作業 |
| エンティティ | 人物・概念をプロファイル化 | 高 | 顧客対応、CRM連携 |
| 知識グラフ | エンティティ間の関係性も記録 | 最高 | 複雑なドメイン知識 |
この中で最もコストパフォーマンスが高いのはサマリーメモリだ。バッファの「古い情報が消える」問題を解決しつつ、エンティティや知識グラフほどの実装複雑性がない。
サマリーメモリの動きを擬似コードで示す。
# 設計パターンの擬似コード
class SummaryMemory:
def __init__(self):
self.current_summary = "" # 過去の要約
self.recent_buffer = deque(maxlen=5) # 直近5件の詳細
def add_interaction(self, user_input, response):
self.recent_buffer.append({
"user": user_input,
"assistant": response
})
# 10回ごとに要約を更新
if len(self.recent_buffer) == 5:
self._update_summary()
def _update_summary(self):
"""既存サマリー + 直近の会話 → 新サマリー"""
prompt = f"""
既存サマリー: {self.current_summary}
最近の会話: {self.recent_buffer}
→ 重要な決定事項・進行状況を中心に要約
"""
self.current_summary = llm.generate(prompt)
古い会話の詳細を要約に圧縮し、直近の会話だけ生データで保持する。情報は失われるが、コンテキストウィンドウの使用量は一定に保たれる。
メモリアーキテクチャの選択で迷ったら、まずバッファから始めるのが正解だ。バッファで「古い情報が消えて困る」場面が実際に発生してから、サマリーへの移行を検討すればよい。最初から知識グラフに手を出すと、実装コストだけが膨らむ。
コンテキスト障害の4パターン
記憶を持たせると、新たな問題が生まれる。コンテキストが長くなるほど発生しやすい4つの障害モードがある。
| 障害モード | 症状 | 対策 |
|---|---|---|
| 汚染 | 誤情報がコンテキストに混入し回答が歪む | 情報の交差検証、信頼度スコアリング |
| 散漫 | 無関係な情報が多く焦点がぼける | 関連性スコアでフィルタリング |
| 混乱 | 複数トピックが混在し文脈を取り違える | トピック別のセクション分け |
| 衝突 | 矛盾する情報が共存し回答が不安定に | 新しさ・信頼性に基づく優先順位 |
特に「衝突」は見落としやすい。2ヶ月前のMEMORY.mdに「JWTを使う」と書いてあるのに、先週「セッションベースに変更」と決定した場合、両方の情報がコンテキストに載る。AIは矛盾する指示の間で揺れ動き、出力が不安定になる。
対策はシンプルだ。MEMORY.mdの定期的な「棚卸し」を行い、古い決定事項は上書きするか削除する。月に一度でいい。5分で終わる作業だが、これを怠るとAIの出力品質がじわじわ劣化していく。私も棚卸しを3ヶ月サボった結果、同じ質問にClaude Codeが毎回違う回答を返すようになり、原因を調べたらMEMORY.mdの中で方針が3回変わっていた。AIが混乱するのも無理はない。
3つの方法を組み合わせる実践パターン
ここまでの3つの方法は排他的ではない。組み合わせることで、段階的に記憶の精度を上げていける。
Phase 1: CLAUDE.mdだけで始める
プロジェクトのルール、アーキテクチャ、命名規則をCLAUDE.mdに書く。これだけで「毎回説明し直す」問題の8割は解決する。実際に私のプロジェクトでも、CLAUDE.mdを置いただけでセッション開始時の説明時間が半分以下になった。ただし、最初は張り切って200行超のCLAUDE.mdを書いてしまい、逆にClaude Codeが情報過多で混乱するという本末転倒をやらかした。10行から始めるのが正解だ。
Phase 2: MEMORY.mdを追加する
セッション跨ぎの決定事項を記録する仕組みを入れる。「前回決めたこと」をAIが覚えているようになる。週次で棚卸しを行い、古い情報を整理するのがコツだ。
Phase 3: メモリアーキテクチャを検討する
複数エージェントが協調するシステムを組む場合に、バッファやサマリーの仕組みを導入する。ほとんどのプロジェクトではPhase 2までで十分だ。Phase 3が必要になるのは、複数のAIエージェントが協調動作するシステムや、数百セッション分の文脈を保持する必要があるケースに限られる。
Anthropicの公式Cookbookでも「context engineering: memory, compaction」としてメモリ設計のベストプラクティスが公開されている。Phase 3に進む前に参照するとよい。
まとめ
Claude Codeの「忘れる」問題は、記憶の外部化で解決できる。
- CLAUDE.md: チームの共通ルールを静的に管理。セットアップは1分
- MEMORY.md: セッション跨ぎの決定事項を動的に記録。「前回の続き」が可能に
- メモリアーキテクチャ: バッファ → サマリー → エンティティの段階的導入
- 棚卸し: 古い情報の定期的な更新で、コンテキスト障害を防ぐ
まずはCLAUDE.mdを1つ書くところから始めてみてほしい。10行でいい。「毎回説明し直す」ストレスから解放されるだけでも、開発体験は大きく変わる。
Context Engineeringの全体像を掴みたい方へ。Zenn Book「Context Engineering」では、メモリ設計に加えて、Few-shot Examples、RAG、MCP連携まで、LLMの出力品質を制御する技術をひと通りカバーしています。
https://kenimoto.dev/ja/books/context-engineering?utm_source=qiita&utm_medium=article&utm_campaign=q8a6540
