AIコーディング 2026.04.18

Claude Codeで長期メモリ実装【複数セッション対応】会話履歴の活用法

タグ:Claude Code / AI開発 / 生産性 / メモリ管理 / プロンプト工夫

問題: セッションをまたぐとリセットされる

Before(問題のある状況):
  月曜: 「Next.jsでECサイトを作っています。スキーマはPrismaで...」
         → 1時間で完成した設計
  火曜: 「昨日の続きで商品一覧ページを...」
         → 「どのような設計ですか?」と最初から質問される
         → 再説明で30分無駄

After(改善後):
  CLAUDE.mdとproject_state.jsonで状態を保存
  火曜: セッション開始直後に状態ファイルを読み込み即作業開始
         → 再説明ゼロ、すぐに実装フェーズへ

解決策1: CLAUDE.mdで永続設定

# CLAUDE.md(プロジェクトルートに配置)

## プロジェクト概要
ECサイト「MyShop」
技術: Next.js 14 + TypeScript + Prisma + PostgreSQL + Vercel

## 現在の進捗
- ✅ 認証機能(Auth.js設定済み)
- ✅ 商品モデル(Prismaスキーマ完成)
- 🔄 商品一覧ページ(進行中)
- ⏳ カート機能(未着手)

## 設計上の重要な決定事項
- ルーティング: App Router(Pages Routerは使わない)
- スタイリング: Tailwind CSS + shadcn/ui(CSS Modulesは使わない)
- 画像: next/image必須(<img>は使わない)

## 禁止事項
- any型の使用禁止
- .envへの直書き禁止
- git push --force禁止

解決策2: state-as-filesで作業状態を保存する

# session_memory.py
# セッション終了時に状態を保存してセッション再開時に引き継ぐ

import anthropic
import json
from pathlib import Path
from datetime import datetime

client = anthropic.Anthropic()
STATE_FILE = Path("project_state.json")

class SessionMemory:
    def __init__(self):
        self.state = self._load_state()
    
    def _load_state(self) -> dict:
        if STATE_FILE.exists():
            return json.loads(STATE_FILE.read_text())
        return {"sessions": [], "todos": [], "decisions": []}
    
    def save_session_summary(self, session_work: str) -> None:
        """セッション終了時にClaude Haikuで要約を生成して保存"""
        response = client.messages.create(
            model="claude-haiku-4-5-20251001",  # 要約はHaikuで安く
            max_tokens=200,
            messages=[{
                "role": "user",
                "content": f"以下の作業内容を2行で要約してください:\n{session_work}"
            }]
        )
        
        summary = response.content[0].text
        cost = (response.usage.input_tokens * 0.80 + response.usage.output_tokens * 4.00) / 1_000_000
        
        self.state["sessions"].append({
            "date": datetime.now().isoformat()[:10],
            "summary": summary,
            "cost_usd": round(cost, 5)
        })
        
        STATE_FILE.write_text(json.dumps(self.state, ensure_ascii=False, indent=2))
        print(f"状態を保存しました(要約コスト: ${cost:.5f})")
    
    def get_context_for_new_session(self) -> str:
        """新セッション開始時のコンテキストを生成する"""
        if not self.state["sessions"]:
            return "初回セッションです(前のセッション履歴なし)"
        
        recent = self.state["sessions"][-3:]  # 直近3セッションを使用
        context = "前のセッション要約:\n"
        for s in recent:
            context += f"- {s['date']}: {s['summary']}\n"
        
        return context
    
    def ask_with_context(self, question: str) -> str:
        """セッション間の文脈を引き継いで質問する"""
        context = self.get_context_for_new_session()
        
        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=1024,
            system=f"プロジェクトコンテキスト:\n{context}",
            messages=[{"role": "user", "content": question}]
        )
        return response.content[0].text

# 使用例
memory = SessionMemory()

# 新セッション開始
print("コンテキスト:", memory.get_context_for_new_session())
answer = memory.ask_with_context("商品一覧ページの続きを作ってください")

# セッション終了時
memory.save_session_summary("商品一覧ページのServer Component実装、Prismaクエリ最適化完了")

あわせて読みたい

参考ソース