How to Handle Conversational Memory with LangChain LangChainを使用した会話の記憶の扱い方

LangChain で会話記憶を扱う方法を知りたい場合は、このチュートリアルを読んでみてください!

Anakin AIを無料で利用開始

How to Handle Conversational Memory with LangChain LangChainを使用した会話の記憶の扱い方

Start for free
目次

コンバーショナルAIシステムは、一貫性のあるかつ関連性のある応答を提供するために、コンテキストを維持し、前回の対話を記憶する必要があります。LangChainは、大規模言語モデル(LLM)を使用したアプリケーション構築のための人気のあるフレームワークであり、会話体験を向上させるための強力なメモリ管理機能を提供しています。この記事では、詳しい手順とサンプルコードを使用して、LangChainを使用して対話のメモリを効果的に処理する方法について説明します。

💡
制限なしでClaude 3.5 Sonnetを試してみたいですか?

あらゆるAIモデルにアクセスできるAIプラットフォームを探していますか?

それなら、Anakin AIを見逃すことはできません!

Anakin AIは、ワークフローオートメーションのためのオールインワンプラットフォームで、使いやすいノーコードアプリビルダーでパワフルなAIアプリを作成できます。Llama 3ClaudeGPT-4Uncensored LLMsStable Diffusionなどを使用して、数分で夢のAIアプリを構築しましょう!

LangChainメモリの理解

LangChainのメモリモジュールを使用することで、LLMとの対話ごとに情報を継続して保存することができます。これにより、モデルは対話の前の部分を参照し、コンテキストを維持することができます。LangChainにはさまざまなタイプのメモリがあり、それぞれが異なるユースケースに適しています。

LangChainメモリのタイプ

  1. ConversationBufferMemory:すべての以前のメッセージを保存します
  2. ConversationBufferWindowMemory:最近のメッセージのスライディングウィンドウを保持します
  3. ConversationSummaryMemory:対話の概要を維持します
  4. ConversationKGMemory:対話で言及されたエンティティのナレッジグラフを作成します
  5. ConversationEntityMemory:特定のエンティティに関する情報を追跡します

これらの異なるメモリタイプをLangChainアプリケーションで実装して使用する方法について詳しく見ていきましょう。

LangChainメモリの設定

特定のメモリタイプを実装する前に、環境を設定し、必要なモジュールをインポートしましょう:

from langchain.llms import OpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain.prompts import PromptTemplate

# 言語モデルを初期化する
llm = OpenAI(temperature=0.7)

このセットアップでは、LangChainから必要なモジュールをインポートし、OpenAI言語モデルを初期化しています。`temperature`パラメータは、モデルの出力のランダム性を制御し、より高い値はより多様な応答を生成します。

LangChainでのConversationBufferMemoryの実装

ConversationBufferMemoryは、LangChainでの最も単純なメモリ形式です。会話全体の以前のメッセージを保存し、モデルが会話履歴全体にアクセスできるようにします。

ConversationBufferMemoryの使用手順

  1. ConversationBufferMemoryインスタンスを作成する
  2. メモリを使用してConversationChainを初期化する
  3. チェーンとの対話

以下にサンプルの実装を示します:

# メモリの作成
memory = ConversationBufferMemory()

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

# チェーンとの対話
response1 = conversation.predict(input="こんにちは、私の名前はアリスです。")
print(response1)

response2 = conversation.predict(input="私の名前は何ですか?")
print(response2)

この例では、まず`ConversationBufferMemory`インスタンスを作成します。次に、言語モデル、メモリ、およびデフォルトの会話プロンプトを組み合わせた`ConversationChain`を初期化します。`verbose=True`パラメータを使用すると、チェーンの内部動作を確認することができます。

ユーザーの入力を渡して`predict`メソッドを使用してチェーンと対話します。最初の対話ではAliceを紹介し、2番目の対話ではモデルにAliceの名前を思い出すように尋ねます。ConversationBufferMemoryが会話全体の履歴を保存しているため、モデルは正しく答えることができます。

LangChainでのConversationBufferWindowMemoryの使用

ConversationBufferWindowMemoryは、最近のメッセージのスライディングウィンドウを保持し、長い会話を扱う際にモデルが過剰なコンテキストに圧倒されるのを防ぐのに役立ちます。

ConversationBufferWindowMemoryの実装

from langchain.memory import ConversationBufferWindowMemory

# ウィンドウサイズ3のメモリを作成する
window_memory = ConversationBufferWindowMemory(k=3)

# 会話チェーンの作成
window_conversation = ConversationChain(
    llm=llm,
    memory=window_memory,
    verbose=True
)

# チェーンとの対話
window_conversation.predict(input="こんにちは、私はボブです。")
window_conversation.predict(input="私はピザが好きです。")
window_conversation.predict(input="私のお気に入りの食べ物は何ですか?")
window_conversation.predict(input="私の名前は何ですか?")

この例では、`k=3`としてConversationBufferWindowMemoryを作成し、会話の最後の3ターンのみを保持します。これは、以前のコンテキストがより関連性が低くなる長い会話や、モデルに渡す情報の量を制限したい場合に特に有用です。

このチェーンでは、Bobのお気に入りの食べ物(ピザ)に関する質問に答えることができますが、名前が言及されてから3ターン以上経過している場合、Bobの名前を思い出すのに苦労するかもしれません。これにより、スライディングウィンドウが会話の初期の情報にアクセスする際のモデルの能力にどのような影響を与えるかが示されます。

LangChainでのConversationSummaryMemoryの実装

ConversationSummaryMemoryは、会話の概要を保持し、すべての詳細を保存することなく、会話全体のコンテキストを維持するのに役立ちます。

ConversationSummaryMemoryの使用手順

  1. ConversationSummaryMemoryインスタンスを作成する
  2. 概要メモリを使用してConversationChainを初期化する
  3. チェーンとの対話

以下にサンプルの実装を示します:

from langchain.memory import ConversationSummaryMemory

# 概要メモリの作成
summary_memory = ConversationSummaryMemory(llm=llm)

# 会話チェーンの作成
summary_conversation = ConversationChain(
    llm=llm,
    memory=summary_memory,
    verbose=True
)

# チェーンとの対話
summary_conversation.predict(input="こんにちは、私はチャーリーです。ソフトウェアエンジニアです。")
summary_conversation.predict(input="Pythonと機械学習を使用した新しいプロジェクトに取り組んでいます。")
summary_conversation.predict(input="私について知っていることを要約してください。")

ConversationSummaryMemoryは、各対話の後に会話の概要を生成して更新するために言語モデルを使用します。このアプローチにより、モデルは詳細をすべて保存することなく会話の大まかな理解を維持することができます。これは、会話全体の履歴を保存することが現実的ではない長い会話や、最も重要な情報に焦点を当てたい場合に特に有用です。

この例では、モデルはCharlieの職業と現在のプロジェクトについて簡潔な要約を提供できるはずです。会話がさらに多くのターンを続けても、モデルはCharlieの職業とプロジェクトに関する詳細を把握できます。

LangChainでのConversationKGMemoryの使用

ConversationKGMemoryは、会話中に言及されたエンティティのナレッジグラフを作成します。これは、複数の主題に関する関係や事実を追跡する際に特に有用です。

ConversationKGMemoryの実装

from langchain.memory import ConversationKGMemory

# ナレッジグラフメモリの作成
kg_memory = ConversationKGMemory(llm=llm)

# 会話チェーンの作成
kg_conversation = ConversationChain(
    llm=llm,
    memory=kg_memory,
    verbose=True
)

# チェーンとの対話
kg_conversation.predict(input="私の名前はデビッドで、私にはMaxという犬がいます。")
kg_conversation.predict(input="Maxはゴールデンレトリバーです。")
kg_conversation.predict(input="私のペットについてどんなことを知っていますか?")

ConversationKGMemoryは、会話で言及されたエンティティとその関係を表すグラフ構造を作成します。これにより、より構造化された詳細な情報の再呼び出しが可能となります。この例では、メモリは「デビッド」と「Max」のためのノードを作成し、「デビッドはMaxという犬を飼っている」と「Maxはゴールデンレトリバーである」というような関係を持ちます。

このメモリタイプは、複数のエンティティとその属性に関する情報を正確に追跡する必要がある複雑な情報を扱う場合に特に有用です。

LangChainでのConversationEntityMemoryの実装

ConversationEntityMemoryは、会話で言及された特定のエンティティについての情報を追跡するために設計されており、特定の主題に関する詳細を思い出すことを容易にします。

ConversationEntityMemoryの使用手順

  1. ConversationEntityMemoryインスタンスを作成する
  2. エンティティメモリを使用してConversationChainを初期化する
  3. チェーンとの対話

以下にサンプルの実装を示します:

from langchain.memory import ConversationEntityMemory

# エンティティメモリの作成
entity_memory = ConversationEntityMemory(llm=llm)

# 会話チェーンの作成
entity_conversation = ConversationChain(
    llm=llm,
    memory=entity_memory,
    verbose=True
)

# チェーンとの対話
entity_conversation.predict(input="私はWhiskersとMittensという2匹の猫を飼っています。")
entity_conversation.predict(input="Whiskersはタビーで、Mittensはキャリコです。")
entity_conversation.predict(input="私の猫について教えてください。")

ConversationEntityMemoryは、会話で言及された特定のエンティティについての情報を追跡および更新することに焦点を当てています。各エンティティには別々のメモリエントリが作成されるため、他のトピックが議論される長い会話の中でも、各猫に関する詳細な情報を提供することができます。

高度なLangChainメモリテクニック

基本的なメモリの実装に慣れてきたら、より高度なテクニックを試して、会話型AIアプリケーションを強化できます。

複数のメモリタイプの組み合わせ

異なるメモリタイプを組み合わせることで、より包括的なメモリシステムを作成できます。たとえば、最近のコンテキストにはConversationBufferMemoryを使用し、長期的なコンテキストにはConversationSummaryMemoryを使用することがあります。

from langchain.memory import CombinedMemory

buffer_memory = ConversationBufferMemory(memory_key="buffer_memory")
summary_memory = ConversationSummaryMemory(llm=llm, memory_key="summary_memory")

combined_memory = CombinedMemory(memories=[buffer_memory, summary_memory])

combined_conversation = ConversationChain(
    llm=llm,
    memory=combined_memory,
    verbose=True
)

このアプローチで、異なるメモリタイプの長所を活用することができます。バッファメモリは最近の対話からの即座のコンテキストを提供し、概要メモリは会話全体の大まかなコンテキストを維持します。

メモリプロンプトのカスタマイズ

メモリモジュールが使用するプロンプトをカスタマイズして、特定のユースケースに最適なものにすることができます:

from langchain.prompts import PromptTemplate

custom_prompt = PromptTemplate(
    input_variables=["history", "input"],
    template="Chat History:\n{history}\nHuman: {input}\nAI:"
)

custom_memory = ConversationBufferMemory(human_prefix="Human", ai_prefix="AI")

custom_conversation = ConversationChain(
    llm=llm,
    memory=custom_memory,
    prompt=custom_prompt,
    verbose=True
)

プロンプトをカスタマイズすることで、モデルに会話履歴がどのように提示されるかや、応答のフォーマット方法を制御することができます。これは、特定の対話スタイルを実現したい場合や、各インタラクションに追加のコンテキストや指示を含める必要がある場合に特に有用です。

LangChainメモリ管理のベストプラクティス

LangChainのメモリ機能を最大限に活用するために、次のベストプラクティスを考慮してください。

ユースケースに適したメモリタイプを選択する:アプリケーションの性質や保持する情報のタイプを考慮して、適切なメモリタイプを選択しましょう。例えば、短いコンテキスト依存の会話にはConversationBufferMemoryを使用し、長期的なコンテキストが特定の詳細より重要な場合にはConversationSummaryMemoryを使用します。

バッファベースのメモリを使用する際にトークン制限に注意する:大規模言語モデルでは、入力のトークン制限がある場合があります。ConversationBufferMemoryやConversationBufferWindowMemoryを使用する際には、これらの制限に注意し、必要に応じて履歴を切り捨てたり要約したりする戦略を実装しましょう。

長い会話では概要やエンティティメモリを使用する:長い対話を含むアプリケーションでは、ConversationSummaryMemoryやConversationEntityMemoryを使用して、モデルに過剰な情報を渡すことなくコンテキストを維持しましょう。

複雑なアプリケーションでは、メモリタイプを組み合わせる:複数のメモリタイプの長所を利用するためには、CombinedMemoryを使用して単一のアプリケーションに複数のメモリタイプを組み合わせることを躊躇しないでください。

プロンプトをカスタマイズしてモデルのメモリの使用方法を指示する:会話チェーンで使用するプロンプトをカスタマイズすることで、保持されたメモリを効果的に活用し、望ましい会話の流れを実現できます。

新しい会話セッション用に定期的にメモリをクリアまたはリセットする:新しい会話セッションを開始する際にメモリをクリアまたはリセットするメカニズムを実装して、以前の会話のコンテキストが干渉しないようにしましょう。

アプリケーションでメモリの使用状況とパフォーマンスを監視する:使用されているメモリ量とそれがモデルのパフォーマンスにどのような影響を与えるかを常に把握しておきましょう。応答時間や関連性に問題がある場合は、メモリ戦略を調整しましょう。

結論

効果的なメモリ管理は、魅力的でコンテキストに対応した会話型AIアプリケーションを作成するために重要です。LangChainは、特定のニーズに合わせてカスタマイズできるさまざまなメモリモジュールを提供しています。異なるメモリタイプを理解し、実装することで、言語モデルの機能を大幅に向上させ、より自然で一貫した会話体験を提供することができます。

LangChainと連携して作業を続ける中で、さまざまなメモリタイプと組み合わせを試して、独自のユースケースに最適な方法を見つけましょう。成功する会話型AIの鍵は、モデルの応答だけでなく、コンテキストを維持し、時間をかけて関連性のあるパーソナライズされた対話を提供する能力にあります。

LangChainのメモリ管理機能をマスターすることで、様々なドメインやユースケースで意味のあるコンテキストに対応した対話型AIアプリケーションを開発するための十分な知識と技術を身につけることができます。

💡
制限なしでClaude 3.5 Sonnetを試してみたいですか?

あらゆるAIモデルにアクセスできるAIプラットフォームを探していますか?

それなら、Anakin AIを見逃すことはできません!

Anakin AIは、ワークフローオートメーションのためのオールインワンプラットフォームで、使いやすいノーコードアプリビルダーでパワフルなAIアプリを作成できます。Llama 3ClaudeGPT-4Uncensored LLMsStable Diffusionなどを使用して、数分で夢のAIアプリを構築しましょう!