テックブログ

エルカミーの技術ブログです

🦜 LangChain応用 ConversationalRetrievalChain編

はじめに


LangChainの機能の一つであるChainには様々な機能が提供されています。今回はChain機能の一つであるConversationalRetrievalChainについて説明します。

ConversationalRetrievalChain


ConversationalRetrievalChainを使用することで、チャットとの会話内容を保持することができます。実際にやっていきます。

やってみる

今回はエルカミーの簡単な会社情報のファイル (about_elcamy.txt) を読み込ませ、問い合わせていきます。

about_elcamy.txtの内容は以下の通りです。

エルカミーについて
エルカミーは、データ分析やAI開発を通じてお客様と並走して価値共創する企業です。
ミッション
データの可能性を形にする!
データで、あらゆる問題の本質を知りたい。
データで、意思決定して問題を解決したい。
データで、新しい価値を創造したい。
ビジョン
コラボイノベートカンパニー
ユーザと並走してデータ活用を内製化する。
エルカミーに関わる人々と創発する。
バリュー
スピード アンド クオリティ
期待を超えるプロフェッショナル
学び続ける個人と組織
課題発見と価値創造
自責、謙虚、パッション
コード全体

コード全体を載せておきました。概要を知りたい方はご確認ください。

コード例
import os
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma, FAISS
from langchain.text_splitter import CharacterTextSplitter
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.document_loaders import TextLoader
from langchain.memory import ConversationBufferMemory
os.environ["OPENAI_API_KEY"]="YOUR_OPENAI_API_KEY"
loader = TextLoader("about_elcamy.txt", encoding='utf-8')
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
documents = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(documents, embeddings)
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
qa = ConversationalRetrievalChain.from_llm(ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo", max_tokens=500), vectorstore.as_retriever(search_kwargs={"k": 1}), memory=memory)
query = "エルカミーについて要約してください"
result = qa({"question": query})
print(result["answer"])
query = "要約した内容からキャッチコピーを考えてください。日本語でお願いします"
result = qa({"question": query})
print(result["answer"])
コードの説明

コードの説明に入ります。

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

import os
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.document_loaders import TextLoader
from langchain.memory import ConversationBufferMemory

次にOpenAIのAPIを設定します。"YOUR_OPENAI_API_KEY”の部分に自分のAPIキーを入力します。

os.environ["OPENAI_API_KEY"]="YOUR_OPENAI_API_KEY"

about_elcamy.txtの内容をVectorStoreに格納します。そして、ConversationalRetrievalChainを使用して会話の内容を保持しながら、会話していく仕組みを作成します。

以下が具体的なコードです。

loader = TextLoader("about_elcamy.txt", encoding='utf-8')
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
documents = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(documents, embeddings)
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
qa = ConversationalRetrievalChain.from_llm(ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo", max_tokens=500), vectorstore.as_retriever(search_kwargs={"k": 1}), memory=memory)

では、実際に質問してみましょう。

query = "エルカミーについて要約してください"
result = qa({"question": query})
print(result["answer"])
Using embedded DuckDB without persistence: data will be transient
エルカミーは、データ分析やAI開発を通じてお客様と一緒に価値を共創する企業であり、データを活用して問題を解決し、新しい価値を創造することをミッションとしています。ビジョンは、ユーザと協力してデータ活用を内製化し、エルカミーに関わる人々と共に創造することです。バリューは、スピードと品質、期待を超えるプロフェッショナル、学び続ける個人と組織、課題発見と価値創造、自責、謙虚、パッションです。

会話の内容が保持できているか確認していきます。

query = "要約した内容からキャッチコピーを考えてください。日本語でお願いします"
result = qa({"question": query})
print(result["answer"])
データの可能性をカタチにする、エルカミー。

前文の要約文を保持できており、その内容からキャッチコピーを考えてくれました!

まとめ

今回は、ConversationalRetrievalChainについて紹介していきました!

前文の内容を元に答えてほしい場合や、連続で同じ内容について質問する際は、会話の履歴を保持しておく必要があります。ConversationalRetrievalChainを使って、会話の内容を保持することができるので、ぜひ使ってみてください。

参考