LangChainにおける会話記憶
LangChainは、LLMアプリケーションを構築するための堅牢なフレームワークです。しかし、そのパワーは複雑さを伴います。LangChainはLLMをプロンプトする多くの方法と、会話記憶のような重要な機能を提供します。会話記憶は、LLMがあなたのチャットを記憶するためのコンテキストを提供します。
この投稿では、LangChainとmilvusで会話メモリを使う方法を見ていきます。この記事に従うには、pip
、4つのライブラリとOpenAI APIキーをインストールする必要があります。必要な4つのライブラリはpip install langchain milvus pymilvus python-dotenv
を実行することでインストールできる。または、この記事のCoLab Notebookの最初のブロックを実行する。
この記事では、以下について学びます:
- LangChainを使った会話記憶
- 会話コンテキストの設定
- LangChainで会話記憶を促す
- LangChain会話記憶のまとめ
LangChainによる会話記憶
デフォルトの状態では、LLMとの対話は単一のプロンプトを通して行われます。コンテキストのためのメモリ、つまり "会話メモリ "を追加することは、一つのプロンプトを通して全てを送信する必要がなくなることを意味します。LangChainはLLMとの会話を保存し、後でその情報を取り出すことができます。
ベクターストアを使った持続的会話記憶のセットアップには、LangChainの6つのモジュールが必要です。まず、OpenAIEmbeddings
とOpenAI
LLMを手に入れなければなりません。ベクトルストア・バックエンドを使うには、VectorStoreRetrieverMemory
とLangChainバージョンのMilvus
も必要です。次に、会話を保存してクエリするために、ConversationChain
とPromptTemplate
が必要です。
os
、dotenv
、openai
ライブラリは、主に運用目的で使用します。OpenAIのAPIキーをロードして使用するために使用します。最後のセットアップステップは、ローカルのMilvus Liteインスタンスをスピンアップすることである。Milvus Pythonパッケージのdefault_server
。
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.memory import VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate
from langchain.vectorstores import Milvus
embeddings = OpenAIEmbeddings()
import os
from dotenv import load_dotenv
import openai
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
from milvus import default_server
default_server.start()
会話コンテキストのセットアップ
これで前提条件がすべて整ったので、会話メモリの作成に進むことができる。最初のステップは、LangChainを使ってMilvusサーバーへの接続を作成することです。次に、空の辞書を使ってLangChain Milvusコレクションを作成します。さらに、上記で作成したエンベッディングとMilvus Liteサーバへの接続情報を渡します。
ベクターデータベースを会話記憶に使うには、ベクターデータベースをリトリーバとしてインスタンス化する必要があります。この場合、上位1つの結果のみを取得し、k=1
。最後の会話記憶のセットアップステップでは、先ほどセットアップしたレトリーバーとベクトルデータベースの接続を通して、VectorStoreRetrieverMemory
オブジェクトを会話記憶として使用します。
会話メモリを使うには、そのメモリにコンテキストが必要です。そこで、メモリにコンテキストを与えてみましょう。この例では、5つの情報を与える。好きなスナック(チョコレート)、スポーツ(水泳)、ビール(ギネス)、デザート(チーズケーキ)、ミュージシャン(テイラー・スウィフト)。各エントリーは、save_context
機能を使ってメモリーに保存される。
vectordb = Milvus.from_documents(
{},
embeddings,
connection_args={"host": "127.0.0.1", "port": default_server.listen_port})
retriever = Milvus.as_retriever(vectordb, search_kwargs=dict(k=1))
memory = VectorStoreRetrieverMemory(retriever=retriever)
about_me = [
{"input": "My favorite snack is chocolate",
"output": "Nice"},
{"input": "My favorite sport is swimming",
"output": "Cool"},
{"input": "My favorite beer is Guinness",
"output": "Great"},
{"input": "My favorite dessert is cheesecake",
"output": "Good to know"},
{"input": "My favorite musician is Taylor Swift",
"output": "Same"}
]
for example in about_me:
memory.save_context({"input": example["input"]}, {"output": example["output"]})
LangChainで会話メモリをプロンプトする
会話メモリーの使い方を見てみましょう。まず、LangChainを使ってOpenAI LLMに接続します。LLMに創造性を求めないことを示すために、温度を0にします。
次に、テンプレートを作成します。LLMが人間とフレンドリーな会話をしていることを伝え、2つの変数を挿入する。history
変数は会話の記憶からコンテキストを提供する。input
変数は現在の入力を提供する。これらの変数を挿入するために、PromptTemplate
オブジェクトを使います。
ConversationChain
オブジェクトを使って、プロンプト、LLM、メモリーを結合する。これで、いくつかのプロンプトを与えて、会話の記憶をチェックする準備ができた。まずLLMに、私たちの名前がポケモンシリーズの主なライバルであるゲイリーであることを伝えます(会話メモリ内の他のすべては、私についての事実です)。
llm = OpenAI(temperature=0) # Can be any valid LLM
_DEFAULT_TEMPLATE = """The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Relevant pieces of previous conversation:
{history}
(You do not need to use these pieces of information if not relevant)
Current conversation:
Human: {input}
AI:"""
PROMPT = PromptTemplate(
input_variables=["history", "input"], template=_DEFAULT_TEMPLATE
)
conversation_with_summary = ConversationChain(
llm=llm,
prompt=PROMPT,
memory=memory,
verbose=True
)
conversation_with_summary.predict(input="Hi, my name is Gary, what's up?")
下の画像は、LLMからの予想される反応を示している。この例では、自分の名前は「AI」だと答えている。
では、ここまでの記憶をテストしてみよう。先ほど作成したConversationChain
オブジェクトを使い、私の好きなミュージシャンを検索します。
conversation_with_summary.predict(input="who is my favorite musician?")
下の画像は、Conversation Chainからの予想される応答である。verboseオプションを使ったので、関連する会話も表示されている。予想通り、私の好きなアーティストがTaylor Swiftであることが返されているのがわかる。
次に、私の好きなデザート、チーズケーキを調べてみましょう。
conversation_with_summary.predict(input="Whats my favorite dessert?")
私の好きなデザートを問い合わせると、カンバセーションチェーンは再びmilvusから正しい情報を選んでいることがわかる。私の好きなデザートはチーズケーキです。
さて、先ほどの情報を照会できることを確認したところで、もうひとつ、会話の最初に提供した情報を確認してみよう。私たちはAIに自分の名前をゲイリーと告げて会話を始めた。
conversation_with_summary.predict(input="What's my name?")
最終的なチェックでは、会話チェーンが私たちの名前に関するビットをベクターストアの会話メモリーに保存したことを返す。私たちがゲイリーと名乗ったことが返されます。
LangChain会話メモリのまとめ
このチュートリアルではLangChainで会話型メモリを使う方法を学びました。LangChainはMilvusのようなベクトルストア・バックエンドにアクセスして、永続的な会話型メモリを提供します。プロンプトに履歴を注入し、ConversationChain
オブジェクトに履歴コンテキストを保存することで、会話メモリを使うことができます。
このチュートリアルの例では、Conversation Chainに私に関する5つの事実を伝え、ポケモンの主なライバルであるゲイリーになりすました。そして、会話チェーンに、保存しておいた先験的知識、つまり好きなミュージシャンとデザートについての質問を投げかけました。会話チェーンはこの2つの質問に正しく答え、関連するエントリーを表示した。最後に、会話の最初に答えた私たちの名前について質問すると、私たちが "ゲイリー "と答えたことを正しく返してくれた。
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word