LLM メモリ
ほとんどのLLMベースのアプリケーションにはWeChatに似たチャットインターフェースがあります。AI対話プロセスの重要な機能は、以前の会話で述べられた情報を参照することです。これは人間の対話プロセスと同様で、以前の内容を繰り返すことなく自動的に記憶しています。
LLMフィールドに歴史的な会話情報を格納する機能は通常、「メモリ」と呼ばれます。これは人間が記憶する能力と同じです。LangChainは、単独で使用するか、シームレスにチェーンに統合することができる様々なメモリ機能コンポーネントをカプセル化しています。
メモリコンポーネントは、読み取りと書き込みという2つの基本的な操作を実装する必要があります。
LangChainのいくつかのChainタスクコンポーネントを使用する場合、メモリ機能を有効にすると、次のような類似のロジックが実行されます。
- 初期ユーザー入力を受け取ると、Chainタスクはメモリコンポーネントから関連する過去の情報をクエリし、その情報とユーザーの入力を連結してLLMに渡すプロンプトを作成します。
- LLMから返されたコンテンツを受け取ると、それを自動的にメモリコンポーネントに格納し、次回簡単にクエリできるようにします。
LangChainでメモリ機能を実装するプロセスは、以下のダイアグラムに示す通りです:
システムにメモリコンポーネントを統合する方法
メモリコンポーネントを使用する前に、以下の2つの質問を検討する必要があります。
- 過去のメッセージデータの保存方法
- 過去のメッセージデータのクエリ方法
保存: チャットメッセージリスト
Chatモデルを使用する場合、会話データはチャットメッセージのリストです。LangChainは、歴史的なメッセージデータを保存するためのさまざまなストレージエンジンをサポートしており、最も簡単な方法はメモリに保存することです。実際の運用では、最も一般的に使用される方法はデータベースに保存することです。
クエリ: 関連する過去の会話メッセージのクエリ方法
LLMのメモリ機能を実装するために、過去の会話コンテンツをバックグラウンド情報としてプロンプトに連結することが中心です。これにより、LLMは質問に答える際にバックグラウンド情報を参照できます。
過去のメッセージデータを保存することは比較的簡単ですが、現在の会話コンテンツに関連する過去のメッセージをクエリする方法はより難しい側面です。現在の会話に関連する過去のメッセージをクエリする必要性の主な理由は、LLMの最大トークン制限にあります。すべての過去の会話コンテンツをプロンプトに詰め込んでAIに渡すことはできないためです。
一般的な過去のメッセージのクエリ戦略には次のものがあります:
- プロンプトのバックグラウンド情報として、最近のN件のメッセージのみをクエリする
- AIを使用して過去のメッセージを要約し、その要約をプロンプトのバックグラウンド情報として使用する
- 現在の会話に類似した過去のメッセージをクエリするためにベクトルデータベースを活用する
LangChainコンポーネントの使用例
LangChainのMemoryコンポーネントを使用した例を見てみましょう。ここでは、Memoryコンポーネントとの基本的なやり取り方法を紹介します。
ますますコメントをご覧ください。
from langchain_openai import ChatOpenAI
from langchain.prompts import (
ChatPromptTemplate,
MessagesPlaceholder,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
llm = ChatOpenAI()
prompt = ChatPromptTemplate(
messages=[
SystemMessagePromptTemplate.from_template(
"あなたは素敵なチャットボットで、人間と会話しています。"
),
MessagesPlaceholder(variable_name="chat_history"),
HumanMessagePromptTemplate.from_template("{question}")
]
)
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
conversation = LLMChain(
llm=llm,
prompt=prompt,
verbose=True,
memory=memory
)
conversation({"question": "こんにちは"})