はじめに
LangChainの会話履歴を保存するMemory機能の1つであるVectorStoreRetrieverMemoryを検証してみました。LangChainのVectorStoreRetrieverMemoryの挙動を確認したい方におすすめです。
開発環境
- Windows 11
- Python 3.11.5
- dotenv
- LangChain
- Azure OpenAI Embeddings
- CharacterTextSplitter
- FAISS
- PyPDFLoader
実装
事前準備
今回は以下の記事で事前にベクトルストアを作成し、そこから回答を生成する方式をとります。
私はランニングを行っていることもあり、以下のランニング時計の取扱説明書のPDFをベクトル化しました。
必要なパッケージのインストール
以下のコマンドで必要なパッケージをインストールします。
pip install langchain
pip install openai
pip install python-dotenv
pip install faiss-cpu
pip install PyPDF2
pip install tiktoken
環境変数の設定と依存関係の読み込み
.envファイルを作成し、Azure Open AIの環境変数の設定をします。
ご自身の環境に合わせて設定してください。
# APIキー
OPENAI_API_KEY = "XXXXX"
# エンドポイント
AZURE_OPENAI_ENDPOINT = "XXXXX"
# 使用するOpenAI APIのバージョン
OPENAI_API_VERSION = "XXXXX"
必要なライブラリをインポートします。
# 環境変数を.envファイルから読み込む
from dotenv import load_dotenv
load_dotenv()
import faiss
from langchain.chat_models import AzureChatOpenAI
from langchain.embeddings import AzureOpenAIEmbeddings
from langchain.docstore import InMemoryDocstore
from langchain.vectorstores import FAISS
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import VectorStoreRetrieverMemory
使用するモデルの準備
Azure Chat OpenAIとAzure OpenAI Embeddingsを定義します。
llm = AzureChatOpenAI(
temperature=0,
azure_deployment="gpt-35-turbo-16k",
)
embeddings = AzureOpenAIEmbeddings(
azure_deployment="text-embedding-ada-002",
chunk_size=1,
)
FAISSベクトルストアの読み込み
ローカルに保存しているベクトルストアの読み込みを行い、as_retriever()メソッドで検索機能を作成します。
vectorstore = FAISS.load_local("./vectorstore", embeddings)
retriever = vectorstore.as_retriever()
VectorStoreRetrieverMemoryの定義
以下のようにVectorStoreRetrieverMemoryyを定義します。VectorStoreRetrieverMemoryは過去会話をVectorStoreに保持しておき、その中から質問と関連する会話を探索します。
会話を探索するアルゴリズムIndexFlatL2の設定と会話履歴を保持するVectorStoreの設定をします。
search_kwargs=dict(k=2)
のkで関連する会話を取り出す個数を指定します。
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
embedding_fn = embeddings.embed_query
conversation_history_vectorstore = FAISS(embedding_fn, index, InMemoryDocstore({}), {})
conversation_history_retriever = conversation_history_vectorstore.as_retriever(search_kwargs=dict(k=2))
memory = VectorStoreRetrieverMemory(
retriever=conversation_history_retriever,
memory_key="chat_history"
)
chainを作成し、実行
最後にchainを作成し、実行します。質問は4問準備しており、2問目は1問目を詳しく説明する質問、3問目は別の質問を挟み、4問目に2問目を想起させる質問です。
chain = ConversationalRetrievalChain.from_llm(
llm=llm, retriever=retriever, memory=memory, get_chat_history=lambda h :h
)
results = chain({"question": "心拍変動は計測可能ですか?"})
print("あなた:", results["question"])
print("ボット:", results["answer"])
print("会話履歴:", results["chat_history"])
results = chain({"question": "もっと詳しく説明してください。"})
print("あなた:", results["question"])
print("ボット:", results["answer"])
print("会話履歴:", results["chat_history"])
results = chain({"question": "血中酸素濃度は?"})
print("あなた:", results["question"])
print("ボット:", results["answer"])
print("会話履歴:", results["chat_history"])
results = chain({"question": "ハートレートセンサーをペアリングする方法は?"})
print("あなた:", results["question"])
print("ボット:", results["answer"])
print("会話履歴:", results["chat_history"])
これまでのPythonコードを上から順に記述し終わったら、Pythonファイルを実行します。
実行結果は以下のようになりました。
`embedding_function` is expected to be an Embeddings object, support for passing in a function will soon be removed.
あなた: 心拍変動は計測可能ですか?
ボット: はい、デバイスは心拍変動データを計測することができます。心拍変動データはストレスレベルの測定に使用されます。
会話履歴:
あなた: もっと詳しく説明してください。
ボット: デバイスとセンサーをペアリングするには、以下の手順を実行します。
1. デバイスとセンサーを近づけます。デバイスとセンサーの距離は3メートル(10フィート)以内にする必要があります。ただし、ペアリング中は他のワイヤレスセンサーから10メートル(33フィート)以上離れていることを確認してください。
2. ハートレートセンサーをペアリングする場合は、センサーを装着します。ハートレートセンサーは胸に装着するタイプが一般的で す。
3. デバイスのメニューから「センサーとアクセサリー」を選択します。このメニューは通常、設定やオプションの中にあります。
4. デバイスは自動的にセンサーを検出し、利用可能なセンサーのリストを表示します。センサーのリストからペアリングしたいセン サーを選択します。
5. デバイスはセンサーとの接続を確立し、センサーのデータをデバイスに送信します。センサーがアクティブで接続範囲内にあれば 、デバイスは自動的にセンサーに接続します。
注意点として、初めてセンサーをペアリングする場合は、デバイスとセンサーを近づけてペアリングする必要があります。また、センサーがANT+接続とBluetooth接続の両方に対応している場合は、ANT+接続を使用することをおすすめします。
以上がデバイスとセンサーのペアリングの手順です。もし具体的なセンサーの種類やデバイスのモデルについての情報があれば、それに基づいてより具体的な手順を説明することができます。
会話履歴: question: 心拍変動は計測可能ですか?
answer: はい、デバイスは心拍変動データを計測することができます。心拍変動データはストレスレベルの測定に使用されます。
あなた: 血中酸素濃度は?
ボット: はい、Garminデバイスは血中酸素濃度を計測する機能があります。デバイスには光学式センサーが搭載されており、血中酸 素濃度を測定することができます。
会話履歴: question: 心拍変動は計測可能ですか?
answer: はい、デバイスは心拍変動データを計測することができます。心拍変動データはストレスレベルの測定に使用されます。
question: もっと詳しく説明してください。
answer: デバイスとセンサーをペアリングするには、以下の手順を実行します。
1. デバイスとセンサーを近づけます。デバイスとセンサーの距離は3メートル(10フィート)以内にする必要があります。ただし、ペアリング中は他のワイヤレスセンサーから10メートル(33フィート)以上離れていることを確認してください。
2. ハートレートセンサーをペアリングする場合は、センサーを装着します。ハートレートセンサーは胸に装着するタイプが一般的で す。
3. デバイスのメニューから「センサーとアクセサリー」を選択します。このメニューは通常、設定やオプションの中にあります。
4. デバイスは自動的にセンサーを検出し、利用可能なセンサーのリストを表示します。センサーのリストからペアリングしたいセン サーを選択します。
5. デバイスはセンサーとの接続を確立し、センサーのデータをデバイスに送信します。センサーがアクティブで接続範囲内にあれば 、デバイスは自動的にセンサーに接続します。
注意点として、初めてセンサーをペアリングする場合は、デバイスとセンサーを近づけてペアリングする必要があります。また、センサーがANT+接続とBluetooth接続の両方に対応している場合は、ANT+接続を使用することをおすすめします。
以上がデバイスとセンサーのペアリングの手順です。もし具体的なセンサーの種類やデバイスのモデルについての情報があれば、それに基づいてより具体的な手順を説明することができます。
あなた: ハートレートセンサーをペアリングする方法は?
ボット: ハートレートセンサーをデバイスとペアリングする方法は以下の通りです。
1. デバイスとセンサーの距離を3m(10ft)以内に近づけます。
2. UPキーを長押しします。
3. [センサー]>[追加]を選択します。
4. [すべて検索]を選択するか、センサータイプを選択します。
5. センサーがペアリングされると、センサーのステータスが検索中から接続済みに変わります。
ペアリングが完了すると、トレーニングページのデータ項目にハートレートセンサーのデータが表示されます。
会話履歴: question: もっと詳しく説明してください。
answer: デバイスとセンサーをペアリングするには、以下の手順を実行します。
1. デバイスとセンサーを近づけます。デバイスとセンサーの距離は3メートル(10フィート)以内にする必要があります。ただし、ペアリング中は他のワイヤレスセンサーから10メートル(33フィート)以上離れていることを確認してください。
2. ハートレートセンサーをペアリングする場合は、センサーを装着します。ハートレートセンサーは胸に装着するタイプが一般的で す。
3. デバイスのメニューから「センサーとアクセサリー」を選択します。このメニューは通常、設定やオプションの中にあります。
4. デバイスは自動的にセンサーを検出し、利用可能なセンサーのリストを表示します。センサーのリストからペアリングしたいセン サーを選択します。
5. デバイスはセンサーとの接続を確立し、センサーのデータをデバイスに送信します。センサーがアクティブで接続範囲内にあれば 、デバイスは自動的にセンサーに接続します。
注意点として、初めてセンサーをペアリングする場合は、デバイスとセンサーを近づけてペアリングする必要があります。また、センサーがANT+接続とBluetooth接続の両方に対応している場合は、ANT+接続を使用することをおすすめします。
以上がデバイスとセンサーのペアリングの手順です。もし具体的なセンサーの種類やデバイスのモデルについての情報があれば、それに基づいてより具体的な手順を説明することができます。
question: 心拍変動は計測可能ですか?
answer: はい、デバイスは心拍変動データを計測することができます。心拍変動データはストレスレベルの測定に使用されます。
4問目の会話履歴に注目してください。4問目の質問と関連する2問目の会話履歴が取り出されていることが確認できます。会話履歴を探索する処理が必要なため、その分の時間を要する点には注意が必要です。
おわりに
LangChainの会話履歴を保存するmemory機能の1つであるVectorStoreRetrieverMemoryを検証してみました。文書検索に会話履歴を導入する際の選択肢の1つになります。ぜひ、試してみてください。
最後までお読みいただき、ありがとうございました!
以下のXで情報発信してます!
参考文献