0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIの記憶を設計したら「忘れさせる」が一番難しかった

0
Posted at

「引き継ぎプロンプト」という手法が流行っている。チャットが長くなったら要約を作り、新しいセッションに貼り付けて続行する。手軽で効果がある。

ただ、Claude Codeである程度の規模のプロジェクトを回していると、引き継ぎプロンプトでは解決できない問題にぶつかる。セッションをまたぐ記憶の管理、過去の指示と現在の指示の矛盾、蓄積された情報の陳腐化。

ここ数週間、Claude Codeのメモリ機能を使い倒して記憶管理を設計し直した。結果として3層構造に落ち着いたのだが、設計過程で気づいたことがある。AIの記憶管理で最も難しいのは「覚えさせる」ではなく「忘れさせる」だった。


引き継ぎプロンプトの限界はどこにあるか

引き継ぎプロンプトが解決するのは「セッション間の状態転送」だ。前のセッションで何をしていたか、次に何をすべきかを伝える。これは有効だし、短期的なタスクの継続には十分機能する。

問題は、プロジェクトが1週間、2週間と続いたときに起きる。

3日前に「Aの方法でやって」と指示した。翌日「Bの方が良さそうだからBに変更」と言った。引き継ぎプロンプトはその時点の最新状態をスナップショットとして渡すから、Bが残る。ここまでは正しい。

だが1週間後、別の文脈でAの方法論が必要になったとする。引き継ぎプロンプトからはAの存在自体が消えている。なぜBを選んだのかの経緯もない。スナップショットは「今の状態」を伝えるが、「なぜ今の状態に至ったか」は保存しない。

もう一つ。引き継ぎプロンプトに過去の指示や判断基準を全部載せると、どんどん肥大化する。肥大化した引き継ぎプロンプトの中で、今も有効な指示と既に撤回した方針が並列に存在する状態になる。AIはどちらも均等に参照する。人間なら「あれは先週の話でしょ」と判断できるが、AIにはその時間感覚がない。

これが、引き継ぎプロンプトの構造的限界だと認識した起点だった。


人間とAIの記憶は構造的に逆

気づいたのは、人間の記憶とAIの記憶が根本的に逆の構造をしていることだ。

人間は最新の意見を重視する。3ヶ月前に言ったことは正直あまり覚えていないし、覚えていても「あの時はそう思っていた」という過去形で処理する。新しい情報が来れば、古い判断は自然に上書きされる。心理学で言う「系列位置効果」の新近性効果 — 直近の情報ほど優先されるという、人間に普遍的な認知特性だ。

AIは違う。CLAUDE.mdに書いた1行目も、50行目も、100行目も同じ重みで参照する。1週間前に追加したフィードバックも、今日追加したフィードバックも等価に扱う。AIには「最近言われたことだから重要」という時間重み付けが存在しない。

この非対称性が、長期プロジェクトで不具合を引き起こす。

たとえば自分のケースでは、Claude Codeに記事の書き方についてフィードバックを蓄積していた。初期に「もっと丁寧に書いて」と指示し、中期に「丁寧すぎるから断定的に書いて」と修正した。両方がメモリに残っている状態で、Claudeは文脈によってどちらかを選択するが、その選択基準が人間の期待と一致しない。人間の感覚では「断定的に書いて」が今の正解なのに、AIは両方を有効な指示として保持し続ける。

人間は忘却を前提に記憶を運用している。AIは忘却がない前提で記憶を運用している。 この構造の差に、引き継ぎプロンプトは対応していない。


3層メモリアーキテクチャ

ここから先は、Claude Codeのauto memory機能をベースにした実装の話になる。Claude Codeは会話からメモリファイルを自動生成し、次のセッションのコンテキストに注入する仕組みを持っている。

この機能をそのまま使うと、メモリファイルが増え続けて全てが等重みで参照される状態になる。前述の問題がそのまま発生する。そこで、メモリを3層に分離した。

Layer 1: Active(指示として機能する)

MEMORY.md に登録されたメモリのみがこの層に属する。Claude Codeの仕様上、MEMORY.md はセッション開始時に自動読み込みされる。つまりLayer 1に置いたものだけが「今この瞬間のAIの行動」を規定する。

# Memory Index (Active Only)
> Archive protocol: Archived memories → MEMORY_ARCHIVED.md (reference only)

- [feedback_writing_style.md](feedback_writing_style.md) — 断定的に書く、AI的な語尾を避ける
- [feedback_article_focus.md](feedback_article_focus.md) — 1記事1テーマ、複数テーマを詰め込まない
- [user_profile.md](user_profile.md) — ハードウェア×AI専門、日英バイリンガル

目安は20〜40エントリ。これ以上増えると後述する肥大化問題が起きる。ここがAIの「今の人格」を決める。

Layer 2: Archived(エビデンスとして保管)

過去には有効だったが、現在は指示として機能させたくないメモリ。MEMORY_ARCHIVED.md で別管理する。

---
name: 過去の方針X
status: archived
archived_at: 2026-03-30
archived_reason: 新方針Yに統合済み。証拠として保持。
---

重要なのは、ファイルを削除しないこと。なぜその判断をしたかのエビデンスは、将来また必要になる可能性がある。消すのではなく、意思決定への影響を遮断する。

Layer 3: Vectorized Reference(検索でのみ到達可能)

メモリが50件を超えてくると、Layer 1への取捨選択コストが上がる。そこで、過去のメモリや記録をベクトルDB(ChromaDBなど)に入れて検索可能にする構想がある。

ただし、ここには設計上の重要な制約がある。Layer 3のデータは意思決定に使わない。 参考情報として検索結果に出てくるが、AIの行動を規定する力は持たせない。

理由は単純だ。ベクトル化されたデータの中で、現在も有効なものと既に撤回されたものを区別するのが極めて難しい。コサイン類似度は内容の近さを返すが、そのメモリが今も「活きているか」は判定できない。status: archived のようなメタデータをベクトルに持たせても、検索結果のランキングにはメタデータが反映されにくい。

結果として、Layer 3から引いた情報をAIが「これは今も有効な指示だ」と解釈するリスクが残る。だからLayer 3は「読み物」であって「指示」ではない、という原則を置いた。


「忘れさせる」の設計が最も難しい理由

3層構造の設計で最も時間を使ったのが、Layer 1からLayer 2への移行 — つまり「忘れさせる」操作の設計だった。

単純に削除すれば忘れる。だが削除すると、なぜその指示が存在したかの記録が消える。1ヶ月後に「前はどういう方針だったっけ」と振り返りたくなったとき、何も残っていない。

かといって、Layer 1にフラグを付けて active: false とするのは危険だ。AIはファイルの中身を全部読む。active: false と書いてあっても、その指示内容自体はコンテキストに入る。読んだ以上は影響を受ける。

Layer 2への分離が必要だったのは、物理的にコンテキストから外す必要があったからだ。MEMORY.mdからエントリを消し、別ファイル(MEMORY_ARCHIVED.md)に移す。Claudeのコンテキスト読み込みでは MEMORY.md しか参照されないから、Layer 2のファイルはセッション開始時に見えない。

この「物理的な遮断」が意外と難しい。人間のフォルダ整理と同じで、「これはまだ使うかもしれない」と思うと移せない。結果としてLayer 1が肥大化し、矛盾する指示が混在する状態に戻る。

運用してわかったコツを一つ。移行の判断基準を「最新の指示に統合されたか」にする。 「まだ使うかもしれない」ではなく、「この指示の意図は、別の現行指示でカバーされているか」で判断する。カバーされていればアーカイブ。されていなければ残す。


設計から見えた、人間側の仕事

この設計を通じて一番理解が変わったのは、AIの記憶管理は結局「人間側の設計責任」だということだ。

引き継ぎプロンプトは、AIに「覚えていて」と頼む行為だ。メモリファイルも、AIに「これを参照して」と指示する行為だ。どちらも「AIの記憶力」に依存している。

だが実際にやるべきだったのは、AIの記憶力を補強することではなく、人間が記憶の構造を設計することだった。何を覚えさせ、何を忘れさせ、何をエビデンスとして保管するか。この判断はAI側にはできない。なぜなら、指示の優先度は指示を出した人間にしかわからないからだ。

認知心理学でいう「メタ認知」 — 自分の認知プロセスを監視・制御する能力 — が、そのままAIの記憶管理にも必要になる。自分が何をAIに覚えさせていて、そのうちどれが今も有効かを、人間側が把握し続ける必要がある。

面倒ではある。だが、この面倒を引き受けたほうが、長期的には「なぜか前と違う挙動をする」「同じ指示を何度も出し直す」という問題が減る。引き継ぎプロンプトを毎回書き直すコストと比較すれば、初期設計の投資は回収できる。


実装のテンプレート

最後に、自分が実際に使っている構成を共有する。Claude Codeを前提にしているが、考え方自体は他のツールにも適用可能だと思う。

project_root/
├── CLAUDE.md              # プロジェクト指示(不変に近い)
└── .claude/
    └── memory/
        ├── MEMORY.md              # Layer 1 インデックス
        ├── MEMORY_ARCHIVED.md     # Layer 2 インデックス
        ├── feedback_*.md          # ユーザーフィードバック
        ├── user_*.md              # ユーザープロファイル
        └── project_*.md           # プロジェクト状態

各メモリファイルのfrontmatter:

---
name: writing_style
description: 記事の文体指示(断定的、AI語尾禁止)
type: feedback
---

アーカイブ時に追加するフィールド:

---
name: old_policy
status: archived
archived_at: 2026-03-30
archived_reason: 新方針に統合済み。エビデンスとして保持。
---

MEMORY.mdの各行は150文字以内にする。Claude Codeが読み込む際のコンテキスト消費を抑えるためだ。メモリの詳細は個別ファイルに書き、インデックスはポインタに徹する。


次にやりたいこと

Layer 3のベクトル化はまだ構想段階だ。メモリが50件を超えたあたりから、Layer 1に何を残すかの判断コストが体感で上がる。ここを自動化 — たとえば一定期間参照されなかったメモリを自動でアーカイブ候補にする — ができると、運用コストがかなり下がるはずだ。

もう一つ、メモリ間の矛盾検出。Layer 1に矛盾する指示が共存していると、AIの挙動が不安定になる。新しいメモリを追加するときに、既存メモリとの整合性をチェックする仕組みがあれば、Layer 1の品質を維持しやすくなる。

いずれにせよ、AIの記憶管理は「AIの問題」ではなく「設計の問題」だという認識が起点になる。その認識さえあれば、具体的な実装は環境に合わせて変えればいい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?