AIエージェント(Claude Code)の MEMORY.md に「6本のPRが未反映、リリース推奨」と書かれていました。それを信じて cherry-pick を始めたら、6本すべて既に反映済みでした。30分の作業がムダになりました。
原因は、MEMORY.md の1行サマリと本体の実態が乖離していたこと。本記事はこの構造的問題と、対策として導入した運用ルールを整理します。
状況:「未反映6本」を信じて作業開始
ある日の朝、MEMORY.md を確認すると以下のエントリがありました。
1- [PR Backlog](pr_backlog.md) — 53コミット未反映、第1陣6本推奨(#157-#162)「第1陣6本推奨」を信じて、6本を1本ずつ pre 環境に cherry-pick する計画を立てました。
1git cherry-pick abc1234 # PR#1572# → 衝突発生衝突解決を始めましたが、なぜか単純なtypo修正のはずなのに3箇所も衝突する。違和感がありました。
真相:6本すべて既に反映済みだった
調査のため git log pre --grep="(#157)" を実行した結果、
1* abc1234 PR title (#157) ← 既に存在!慌てて他のPRも確認。
1git log pre --grep="(#157)" --oneline # → ヒット2git log pre --grep="(#158)" --oneline # → ヒット3git log pre --grep="(#159)" --oneline # → ヒット4git log pre --grep="(#160)" --oneline # → ヒット5git log pre --grep="(#161)" --oneline # → ヒット6git log pre --grep="(#162)" --oneline # → ヒット6本すべて既に反映済み。30分間、不要な cherry-pick で衝突解決していました。
構造的問題:「索引」と「本体」の更新タイミングが違う
なぜ MEMORY.md は嘘をついていたのか。会話ログを遡って原因を特定しました。
MEMORY.md(索引)
1- [PR Backlog](pr_backlog.md) — 53コミット未反映、第1陣6本推奨(#157-#162)pr_backlog.md(本体)
最終更新: 2026-04-15。本体には「2026-04-15 時点で53コミット未反映」と書かれていました。
しかしその後、別セッションで PR#157-#162 が pre に cherry-pick されていました。
問題は、
- 本体ファイル: cherry-pick 完了時に更新が忘れられた
- 索引(MEMORY.md): 1行サマリは「最終更新時点のスナップショット」で、その後の変更を反映していない
つまり、索引は本体の鮮度を超えられないわけです。本体が古ければ、索引も古い。
さらに悪いこと:AIは索引を強く信用する
Claude Code は会話開始時に MEMORY.md を 自動でシステムプロンプトに注入します。1行サマリは AI が最初に読む情報源です。
つまり、
- AI は索引を読む → 「未反映6本」を信用する
- 本体ファイルを読みに行く前に、行動計画を立てる
- 結果、誤った前提で cherry-pick を開始する
索引が誤っていると、AI は最も強く誤誘導されます。
対策1: cherry-pick 着手前の必須実機検証
最も即効性のある対策は、着手前に実機 git log で必ず確認するルールです。
1# cherry-pick 開始前のチェック2for pr in 157 158 159 160 161 162; do3 if git log pre --grep="(#$pr)" --oneline | grep -q .; then4 echo "PR#$pr: 既反映 → スキップ"5 else6 echo "PR#$pr: 未反映 → cherry-pick 候補"7 fi8doneこれを cherry-pick-audit skill として実装し、MEMORY.md の情報より実機検証を優先するように Claude Code のワークフローに組み込みました。
対策2: MEMORY.md エントリに「最終検証日」を明示
各エントリに、いつ実機検証したかを書きます。
1- [PR Backlog](pr_backlog.md) — 53コミット未反映、第1陣6本推奨 [verified: 2026-04-15]verified 日付が古ければ AI は再検証してから動く、というルールです。
1ルール: verified 日付から 7日以上経過したエントリは、2 実行前に必ず実機検証する対策3: 「サマリは劣化する」を前提にする運用設計
そもそも、索引のサマリは劣化します。これを前提にした設計が必要です。
鮮度の高い情報のみを索引に書く
- 「現在進行中の施策」「未解決の問題」など、本人が能動的に管理する情報 → 書く
- 「リリース予定6本」のような、外的状態(git履歴)に依存する情報 → 書かない
外的状態は 実機コマンドで取得するべきで、索引にスナップショットを書いてはいけません。
完了したら即削除
完了した施策の索引行は、その日のうちに削除します。残しておくと「現在進行中」と誤解されます。
1# 完了したエントリを archive に退避2mv pr_backlog.md archive/3# MEMORY.md からも該当行を削除教訓:AIメモリの3原則
この経験から導いた、AIエージェントの記憶設計の3原則です。
原則1: 外的状態を索引に書かない
git log で確認できる情報、ファイル一覧、API レスポンスなど、実行時に取得すべき情報は索引に書きません。書いた瞬間に劣化が始まります。
原則2: 索引は本体の鮮度を超えられない
本体ファイルが2週間更新されていなければ、索引のサマリも2週間古いものです。本体の更新を伴わない索引追記は意味がありません。
原則3: 着手前検証をワークフロー化
AI に作業させる前に、実機検証を必ず挟むこと。skill / hook / 確認質問 のいずれかで強制します。
まとめ
- MEMORY.md の「未反映6本」を信じて cherry-pick したら、6本全て既反映だった
- 索引と本体の更新タイミングが違うため、サマリは劣化する
- 対策: 着手前実機検証、verified 日付明示、外的状態を索引に書かない
- AI メモリは「最新の話題のヘッドライン」であるべきで、外的状態のスナップショットを書いてはいけない
索引は嘘をつく前提で運用する。これが AI 駆動開発のメモリ設計の出発点です。