本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。
はじめに:LLMに記憶はない
LLM は、コンテキストウィンドウ(一連の会話の流れ)の中身しか知りません。ユーザが「先週の件だけど」と言っても、エージェントは先週の会話を覚えていません。LLMは原則ステートレスであって、プロジェクトのコード規約、会社の手続き、以前に見つけた知見など、必要な情報をユーザが指示内容に毎回詰め込まなければいけません。
AIを用いた製品の「記憶」はエージェントハーネスの一部で実装されます。記憶と簡単に言いますが、うまく動かすには非常に複雑で奥深い分野です。
LLMエージェントに同じことをさせるには、過去の調査結果をどこかに保存し、必要になったときにもう一度LLMへ渡さなければなりません。それが、エージェントにおける「長期記憶」です。
ただし、「この通信は安全だった」という結論だけを覚えれば、本当に危険な通信まで見逃すかもしれません。攻撃者が書いた指示を記憶に取り込み、次のセッションでも参照し続ける可能性もあります。
長期記憶はエージェントを便利にしますが、同時に、攻撃や誤判断を長持ちさせる仕組みにもなります。本記事では、現在のエージェントがどのように記憶を実装しているのかを見ながら、AI for securityで使うなら何が問題になるのかを考えます。
1. コンテキストウィンドウ
コンテキストウィンドウとはLLMが一度に扱えるコンテキスト総量です。
LLMが直接参照できるのは、そのセッションで渡されたコンテキストだけです。チャットサービスが前の会話を覚えているように見えるのは、サービス側が履歴や要約を保存し、次のセッションでモデルへ渡しているためです。
2026年現在、主要 LLM のコンテキストウィンドウは100万トークンがスタンダードです。その大きさは書籍数冊分と言われています。一見すると十分そうですが、コンテキスト中に会話、コード、ログ、チケット、社内文書をすべて入れ続けるわけにはいきません。
なぜなら、費用と待ち時間が増えるだけでなく、長いコンテキストに入れた情報が均等に使われるとも限らないからです。Liuらの「Lost in the Middle」は、コンテキストの中央付近に置かれた情報ほど回答に利用されにくくなる傾向を示しました。[^1]
[^1]: Liu, N. F. et al. (2024). Lost in the Middle: How Language Models Use Long Contexts. TACL, 12, 157–173.
2. RAG とは何か
長期記憶の話でよく出てくるのがRAG(Retrieval-Augmented Generation)です。外部データを検索し、見つけた情報をコンテキストへ加えてから、LLMに回答させます。
ベクトル検索を使うRAGは、言葉が一致していなくても、意味の近い情報を探せるのが強みです。「認証処理」という質問から、loginやsessionを含むコードを見つけられる可能性があります。一方、CVE番号、ハッシュ値、関数名を探すなら文字列の完全一致のほうが確実です。
RAGには、チャンクの切り方、Embedding Modelの性能、インデックスの鮮度といった問題もあります。しかし、より大きな論点は別にあります。
何を保存するのか。新旧の情報が矛盾したらどうするのか。誰の記憶なのか。いつ消すのか。取り出した文章を事実として扱うのか、それとも参考情報として扱うのか。RAGが主に担うのは「取り出す」ところであり、これらの判断までは引き受けてくれません。
3. 現在のスタンダード
エージェントに記憶を持たせる最も単純な方法は、テキストファイルへ書いておき、次のセッションで読ませることです。
Claude CodeのCLAUDE.md がわかりやすい例です。プロジェクト構成、ビルド手順、コーディング規約などを書いておくと、セッション開始時に読み込まれます。内容を人間が直接確認でき、間違っていれば直せます。
ただし、長いCLAUDE.md を作ればよいわけではありません。Anthropicのドキュメントでは200行未満が目安とされ、詳細な手順は別ファイルやSkillへ分けることが勧められています。Claude CodeのAuto Memoryも、起動時に読むMEMORY.md を先頭200行または25KBまでに抑え、詳しい内容は必要になったときだけ参照します。[^2]
この設計からは、「すべてを覚えておく」より「何を常に読ませるか」を絞ることのほうが難しいとわかります。
もう一つ注意したいのは、CLAUDE.md がセキュリティ設定ではないことです。「本番環境へ接続しない」と書いても、接続を技術的に禁止したことにはなりません。守らなければ困る要件は、アクセス制御、サンドボックス、ツールの許可設定などシステムレベルで強制する必要があります。
[^2]: Anthropic. (2025-2026). Claude Code documentation: Memory and CLAUDE.md.(https://code.claude.com/docs/en/memory)
4. コーディングエージェントの記憶戦略
4.1 コードベースは巨大な「外部記憶」である
コーディングエージェントにとって、プロジェクトのコードベース全体がひとつの「長期記憶」です。関数の定義、API の使い方、設定ファイルの内容——これらはすべて「ファイルのどこかにある」わけで、エージェントは必要なときに必要な場所を探し出せなければなりません。
4.2 コーディングエージェントにおける外部記憶戦略
コーディングエージェントにとって、コードベース自体が巨大な外部記憶です。関数の定義、設定値、テスト、過去の設計判断は、すでにファイルとして残っています。問題は、必要な箇所へどうたどり着くかです。
関数名やエラー文がわかっていれば、grep で探せます。現在のファイルを直接読むので、検索用インデックスの更新を待つ必要もありません。Claude Codeや Codexを愛用しているエンジニアの方はよくご存知だと思いますが、新しいセッションで指示を出すと、まずファイルの探索を grep (あるいはそれに相当するツール) で探索から始めていることを良く見かけますね。
一方、「このサービスの認証はどうなっているか」のように、探すべき名前がわからない質問では、セマンティック検索が候補を見つける助けになります。Cursorは、従来の検索ツールにセマンティック検索を加えた条件で、コードベースに関する質問の精度が平均12.5%上がったと報告しています。[^3]
[^3]: SmartScope. (2026). Settling the RAG Debate. (https://smartscope.blog/en/ai-development/practices/rag-debate-agentic-search-code-exploration/)
ここで注意したいのは、RAGを始めとするセマンティック検索が grep を置き換えたわけではないことです。名前がわかるものは文字列で探し、概念しかわからないものは意味で探す。候補が見つかったら、実際のファイルを読む。検索手法を複数組み合わせることで強力な記憶装置として利用できるようになっています。ただし、RAGの検索用インデックスを作れば、元のコードとは別のデータ資産が生まれます。削除したファイルの断片が残っていないか。リポジトリの権限変更が反映されるか。別プロジェクトのコードが混ざらないか。検索精度とは別に考える必要があります。
こういった背景から、多くのコーディングエージェントではコストに対する恩恵が薄いのか、RAGを用いた検索システムは利用されにくいです。
AI for securityの視点ではどうでしょうか。CVE番号やハッシュ値、過去の類似インシデント、資産と利用者の関係では、向いている探し方が異なります。「grepを使うか、RAGを使うか」だけを先に決めても、あまり意味はありません。
5. 汎用エージェントの記憶戦略
コーディング以外の仕事をするエージェントの記憶管理についても見てみましょう。汎用エージェントは、会話、ユーザの好み、過去の判断、問題の解き方などを扱います。コードベースのような「検索可能な外部記憶」がないぶん、エージェント自身が意識的に記憶を管理する仕組みが必要になります。現在の実装を見ると、これらを1つの仕組みへ押し込むのではなく、常に読む短い記憶、検索する履歴、圧縮した要約、再利用する手順に分けています。
5.1 OpenClaw:PC操作をほぼ自動化できる、汎用エージェント
OpenClawは、長く残す事実や判断をMEMORY.md 、日々の観測をmemory/YYYY-MM-DD.mdへ保存します。任意機能のDreamingは短期的なメモを整理し、一定の条件を満たした内容を長期記憶へ昇格させます。検索にはキーワードとベクトルの両方を使えます。[^4]
記憶の正本がMarkdownなので、何を覚えたか人間が追いやすい設計です。一方で、自動昇格の過程で出典や有効期限が落ちれば、読みやすく整理された誤情報が残ることになります。5.2 Hermes Agent:自己改善ループを持つ、汎用エージェント
Hermes Agentでは、MEMORY.mdとUSER.mdに毎回必要な情報を保存し、過去の会話は`session_search`で全文検索します。問題の解き方はSkillとして分けます。[^5]
永続記憶へ書き込む内容には、プロンプトインジェクションや認証情報の持ち出しを狙うパターンがないか検査する仕組みもあります。
[^5]: Nous Research. (2026). Hermes Agent documentation.( https://hermes-agent.nousresearch.com/ )
5.3 Mastra:Observational Memory でベンチマーク上位を取ったフレームワーク
MastraのObservational Memoryは、古い会話を検索する代わりに、ObserverとReflectorが会話を観測し、密度の高い記録へ圧縮します。Mastraには意味検索を行うSemantic Recallもありますが、Observational Memory自体は質問ごとに検索結果を差し込むRAGではありません。
MastraはLongMemEval(長期記憶を評価するLLMベンチマーク)で、GPT-4oとの組み合わせで84.23%、新しいモデルとの組み合わせでは約95%のスコアを報告しています。[^6] もっとも、セキュリティ調査で気になるのは正答率だけではなく、圧縮の中で情報の時間範囲や追加・除外条件が落ちたとき、記憶がどう振る舞うかは考える必要があります。
[^6]: Mastra. (2025). Announcing Observational Memory. ( https://mastra.ai/blog/observational-memory )
6. おわりに:記憶管理に「正解」はまだない状況
ここまで見てきたとおり、エージェントの長期記憶はまだ試行錯誤の段階です。「これが正解」と言える手法は現状存在しません。
6.1 結論だけを残さない
例えば、過去に指摘されたある脆弱性Aを今回は修正しないという決定を下したとします。これは、他に指摘された危険度の高い脆弱性Bの改修を優先し、リスクの比較的低い脆弱性は後回しになったという背景があるとします。しかし結論として、「脆弱性Aは改修しない」という結論だけが残ってしまうと、その背景が失われてしまってAIエージェントは正常な判断ができなくなります。記憶を再利用するには結論に加えてその成り立つ背景情報も重要です。逆に、すべての生ログや未整理の議事録をすべて記憶へ入れる必要があるかは別の問題です。この間をどう設計するかが、記憶システムの仕事になります。
6.2 記憶の寿命と境界を決める
「脆弱性Aをやっぱり改修することにした」といった以前の決定を変更するような記憶が入ってきたとき、時系列なども加味して記憶を整理しなければなりません。その際に記憶データを消すという作業が必要です。
記憶の元文書を消した後、仮にEmbedding、検索インデックス、応答キャッシュに内容が残っていれば、エージェントは思い出せてしまいます。現在の判断材料として検索できることは、常にフレッシュな情報であるという前提で運用しなければいけません。
6.3 おわり
おすすめ記事