LoginSignup
0
1

LangChainでPDF検索をやってみた(FAISS、VectorStoreRetrieverMemory、ConversationalRetrievalChain)

Last updated at Posted at 2023-12-11

はじめに

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の環境変数の設定をします。
ご自身の環境に合わせて設定してください。

.env
# APIキー
OPENAI_API_KEY = "XXXXX"

# エンドポイント
AZURE_OPENAI_ENDPOINT = "XXXXX"

# 使用するOpenAI APIのバージョン
OPENAI_API_VERSION = "XXXXX"

  
必要なライブラリをインポートします。

test.py
# 環境変数を.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を定義します。

test.py
llm = AzureChatOpenAI(
    temperature=0,
    azure_deployment="gpt-35-turbo-16k",
)

embeddings = AzureOpenAIEmbeddings(
    azure_deployment="text-embedding-ada-002",
    chunk_size=1,
)

FAISSベクトルストアの読み込み

ローカルに保存しているベクトルストアの読み込みを行い、as_retriever()メソッドで検索機能を作成します。

test.py
vectorstore = FAISS.load_local("./vectorstore", embeddings)
retriever = vectorstore.as_retriever()

VectorStoreRetrieverMemoryの定義

以下のようにVectorStoreRetrieverMemoryyを定義します。VectorStoreRetrieverMemoryは過去会話をVectorStoreに保持しておき、その中から質問と関連する会話を探索します。
会話を探索するアルゴリズムIndexFlatL2の設定と会話履歴を保持するVectorStoreの設定をします。
search_kwargs=dict(k=2)のkで関連する会話を取り出す個数を指定します。

test.py
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問目を想起させる質問です。

test.py
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で情報発信してます!

参考文献

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1