Shikata Ga Nai

Private? There is no such things.

第67回:LLMアプリのメモリ管理とユーザーコンテキストの維持

Hello there, ('ω')ノ

🗣️ はじめに:「記憶するAI」はどう作る?

ChatGPTのように、

「さっき言ったこと、ちゃんと覚えててくれてる!」

と感じるAI体験を実現するには、メモリ(Memory)と呼ばれる技術が不可欠です。

これはただの一時的な履歴ではなく、
✅ 会話履歴の保持
✅ ユーザーの情報(名前・好み・履歴など)
✅ 過去の出力とのつながりの維持

…といった「ユーザーコンテキストを保ち続ける仕組み」のことを指します。


💾 1. LLMにおけるメモリ管理の目的とは?


✅ なぜメモリが必要か?

利用シーン メモリがないと… メモリがあると…
💬 会話の継続性 前回の話を毎回繰り返す必要がある 会話の文脈を理解してスムーズに応答可能
🛍️ パーソナライズ対応 毎回ゼロベースで案内 ユーザー名や関心事に応じた対応が可能
🤖 エージェントタスク管理 過去のアクション・中間結果を忘れてしまう 状況に応じて判断を継続できる(例:ステップの再実行)

🧩 2. LangChainにおけるMemoryの使い方


LangChainでは、Memoryを使って「状態の保持」が簡単にできる仕組みが整っています。

📦 メモリの種類(LangChain標準)

メモリタイプ 特徴
ConversationBufferMemory 全会話履歴を保存(もっとも基本)
ConversationSummaryMemory 要約して履歴を簡潔に保持(トークン節約型)
ConversationKGMemory 知識グラフ的に関係性を記憶(人物や出来事の関係を追跡)
VectorStoreRetrieverMemory 特定情報を検索できる形式で保存(RAGとの併用が便利)

🛠️ 3. 実装例:会話履歴を保持するLLMアプリ


✅ コード例:ConversationBufferMemory を使った基本構成

from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory

llm = ChatOpenAI(model_name="gpt-3.5-turbo")

# メモリを定義(履歴保持用)
memory = ConversationBufferMemory()

# 会話チェーンを作成
conversation = ConversationChain(llm=llm, memory=memory)

# 会話を実行
print(conversation.predict(input="こんにちは!"))
print(conversation.predict(input="さっきの話、続きをお願いします。"))

✅ 出力イメージ:

こんにちは!何かお手伝いできますか?
→ さっきの話、続きをお願いします。
→ もちろんです。先ほどお話していた内容に続けてお答えします…

🔁 4. 要約型メモリでスリムな履歴保持(トークン節約)


📉 なぜ要約が必要か?

  • 会話履歴が長くなると、トークン制限で途中の文脈が消える
  • 要点だけをまとめて保存することで、“意味は保ちつつ”軽量化できる

✅ コード例:ConversationSummaryMemory

from langchain.memory import ConversationSummaryMemory
from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(model_name="gpt-3.5-turbo")
memory = ConversationSummaryMemory(llm=llm)

conversation = ConversationChain(llm=llm, memory=memory)

print(conversation.predict(input="今までの話をまとめてください。"))

このように、AI自身に履歴を要約させて記憶させることも可能です。


🧠 5. ユーザー別コンテキストの持ち方(ID管理)


👥 ユーザーごとに状態を分けたいときは?

  • WebアプリやLINE Botなどでは、ユーザーIDごとにMemoryを分離するのが基本
  • Pythonなら辞書管理、DBならセッションIDでメモリの紐づけができます
# 例:user_idに基づいてメモリインスタンスを管理
user_memories = {}

def get_memory(user_id):
    if user_id not in user_memories:
        user_memories[user_id] = ConversationBufferMemory()
    return user_memories[user_id]

🛠️ 6. LangGraphとの組み合わせで「会話状態を持ったAIフロー」が可能に

LangGraphでは状態管理と条件分岐が得意なので、
メモリと併用することでこんな構成が可能に:

ユーザーの入力
 ↓
会話履歴を含めた処理(Memory)
 ↓
判断ノード(条件分岐)
 ↓
出力 or 別処理へ

「文脈を覚えながら会話フローを制御するAIエージェント」が実現できます!


📌 まとめ:LLMの“記憶力”を強化して、信頼されるAIへ

✅ メモリは、LLMアプリにおける「ユーザー理解・会話の継続性・状況判断」を支える基盤技術。
✅ LangChainでは複数のメモリモジュールが用意されており、用途に応じて選択可能。
✅ 要点を要約したり、ユーザーごとに分離管理することで、実用的な会話AIの構築が可能になります。

Best regards, (^^ゞ