AIに毎ターン「今、思い出すべきこと」を差し込む — 個人RAGの活性化層
はじめに
自分用のAIアシスタント運用で、過去の判断・教訓・自分についての情報を知識ベース(RAG)に貯めている。だが、貯めるだけでは足りない。AIが自分からその記憶を引きに行かなければ、貯めた教訓は一度も使われずに死蔵される。
そこで、会話の入力を毎回捕まえて、今の話題に効く記憶を自動でAIに差し込む仕組みを作った。これを「活性化層」と呼んでいる。記憶を「貯める」側の話(検索精度を数値で上げる)は 測定駆動でRAGの検索精度を上げる に書いた。この記事はその逆側——貯めた記憶を、必要な瞬間にどう思い出させるか、の話だ。
貯めるだけでは、思い出せない
記憶をいくら貯めても、それが「必要なときに手元に出てこない」なら、無いのと大差ない。人間でも、覚えているはずのことを肝心な場面で思い出せなければ、知らないのと同じ結果になる。
AIアシスタントも同じだ。過去の教訓をRAGに貯めても、AIが「今これは関係あるか」と自分から検索してくれなければ、その教訓は働かない。だが毎回「まず過去を検索して」と頼むのは続かないし、頼み忘れれば同じ失敗を繰り返す。
必要なのは検索そのものより、想起だ——今の文脈に関係する記憶を、AIが聞かれる前に、勝手に手元へ引き寄せている状態。それを仕組みで作る。
【貯めるだけ】記憶を蓄積 ─▶ (AIが自分から引かない)─▶ 死蔵・同じ失敗を反復
【想起あり】 記憶を蓄積 ─▶ 会話のたびに関連記憶を自動で差し込む ─▶ 思い出した状態で応答
会話の入力をフックして、記憶を注入する
使ったのは、AIツール(Claude Code)のフック——特定のタイミングで自分のスクリプトを差し込める仕掛けだ。ここでは「利用者が入力を送った瞬間」に走るフック(UserPromptSubmit)を使う。
流れはこうだ。利用者が何か入力すると、フックが起動し、その入力を手がかりに知識ベースから関連する記憶を集め、短いダイジェストにまとめて、AIのプロンプトの先頭に差し込む。AIは「関連する記憶を思い出した状態」で、応答を始める。
利用者が入力
│
▼
入力送信フック(UserPromptSubmit)が起動
│
├─ 知識ベースから「今の入力に効く記憶」を集める
├─ 短いダイジェストに畳む
▼
AIのプロンプト先頭に差し込む ─▶ AIは思い出した状態で応答
大事なのは、これが毎ターン自動で走ること。利用者もAIも「思い出して」と意識しなくていい。想起が、会話の下敷きとして常に効いている。
二種類の思い出し方を、混ぜずに分ける
ここが設計の芯だ。「思い出す」には性質の違う二つがあり、それを一緒くたにしてはいけない。
一つは内容で思い出す(内容想起)。直前の入力を意味のベクトルに変換し、知識ベースを意味検索して、今の話題に近い記憶を引く。これがあると、ずっと前に貯めた古い教訓でも、話題が合えば蘇る。逆にこれが無いと、AIは「最近のことしか思い出せない」——相棒が新しい記憶だけで生きる、いわば健忘に陥る。
もう一つは新しさで思い出す(新近性の強制注入)。内容に関係なく、最新のN件を無条件で差し込む。直近の決定や進行中の作業は、たとえ今の入力と語がかぶらなくても、落としてはいけないからだ。
この二つは、人の記憶でも別系統だ。「関連することを芋づるで思い出す」のと、「さっき決めたことを覚えている」のは、働きが違う。だから別のセクションとして持つ。加えて、絶対に破ってはいけない禁止事項(優先度=highの教訓)と、自分についての基本情報(プロフィール)は、内容や新しさに関係なく固定枠で毎回入れる。
差し込むダイジェスト(毎ターン組み立て)
├─ ① プロフィール(自分について) … 固定枠
├─ ② 絶対禁止(優先度=high の教訓) … 固定枠
├─ ③ 最近の教訓・結論(新しさで強制注入)… 新近性
└─ ④ 今の文脈で関連する記録(意味検索) … 内容想起
コードでは、③と④を別々に引いている。④は入力文で意味検索し、③は日付の新しい順に取る——引き方そのものが違う。
# ④ 内容想起: 直前の入力を意味検索し、今の文脈に効く記憶を引く
res = vault.query(query_texts=[prompt], n_results=TOP_N_QUERY * 2,
where={"source_type": {"$in": ["lesson", "conclusion", "knowledge"]}})
# ③ 新近性: 内容に関係なく、最新N件を無条件で差し込む
items.sort(key=lambda x: x.date, reverse=True) # 日付の新しい順
recency = items[:TOP_N_RECENCY]
そして、同じ記憶が別の枠に二重で出ないよう、先に採用した本文は後の枠から除外する。想起の枠は限られているので、重複で埋めない。
思い出しは、限られた「予算」の中で畳む
もう一つ、地味だが避けて通れないのが量の制約だ。プロンプトに差し込める文字数には上限がある(この仕組みでは約1万字)。記憶は日々増える。全部は入らない。
だから、増え続ける記憶を毎回一定量(約6千字)に畳んで差し込む。ここで効いてくる工夫が二つある。
一つは、毎ターンなるべく同じ内容に保つこと。差し込む内容が安定していれば、AI側の入力キャッシュ(同じ前置きは計算を使い回せる仕組み)が効き、無駄が減る。想起のためにコストを無限には払わない。
もう一つは、削る順番を決めておくこと。畳みきれず切り詰めが要るとき、真っ先に削るのは優先度の低い内容想起(④)だ。無条件に守るのは、絶対禁止(②)と新近性(③)——「無くても実害が小さいもの」から削り、「落とすと事故るもの」は最後まで残す。
最後に、フックが失敗しても会話は止めない。記憶の取得でエラーが出ても、入力はそのままAIへ通す。想起は「あれば効く下敷き」であって、それが無いと会話が成立しない作りにはしない。守りの仕組みが、本体を人質に取ってはいけない。
想起こそが、記憶を記憶にする
作ってみて腹落ちしたのは、記憶の価値は「貯めた量」ではなく「思い出せるかどうか」で決まる、ということだ。どれだけ良い教訓を貯めても、必要な瞬間に手元へ出てこなければ、それは記憶として働いていない。
- 記憶は、聞かれる前に差し出して初めて効く。検索を相手の意思に委ねず、会話のたびに自動で想起させる。
- 思い出し方は、内容想起と新近性を分ける。今の話題に効く古い教訓と、落とせない直近の文脈は、別の系統として両方持つ。
- 想起は、限られた予算の中で畳む。安定させてキャッシュを効かせ、削る順を決め、失敗しても本体は止めない。
貯める仕組み(RAG)は、記憶の半分でしかなかった。今の文脈に効くものを、聞かれる前に引き寄せる——この想起の層を持って初めて、貯めた記憶は「使える記憶」になる。人が経験から学べるのは、覚えているからではなく、必要なときに思い出せるからだ。AIにも、同じ想起を持たせたかった。
関連する記事
- 記憶を「貯める」側——検索精度を感覚でなく数値で上げていった話は 測定駆動でRAGの検索精度を上げる に書いた。
- この個人RAG全体の設計思想は AI に5回訂正された夜 — 個人 RAG を5年連れ添う相棒に育てる設計 にまとめた。
- 同じくフックを使い、想起ではなく「危険な操作をそもそもさせない」強制の仕組みは AIコーディングアシスタントに「やらせない」仕組みを作る — 助言から強制へ、そして関門に空いていた横穴 に書いた。