初めに
この記事では、StreamlitとLangchainを使用して開発した会話型PDFアシスタントについて紹介します。StreamlitとLangchainを学ぶために簡易的に作成したものです。これから、Streamlit、Langchainを使って簡単にチャットボットを作成してみたい!という方におすすめです。
概要
PDFデータを読み込んで、PDFの内容を回答してくれるチャットボット。
Streamlitとは
Streamlitは、PythonでWebアプリケーションを作成するためのフレームワークで、特にデータの可視化や分析を行うアプリケーションに適しています。Streamlitを用いることで、フロントエンドの技術がなくてもWebアプリケーションを作成することができます。
Langchainとは
Langchainは、GPTなどの大規模言語モデル(Large Language Model:LLM)を活用してサービスを開発する際に役立つライブラリです。このライブラリは、LLMと外部リソース(データソース、言語処理系)を組み合わせて、より高度なアプリケーションやサービスの開発をサポートすることができます。
開発環境の詳細とバージョン情報
ツール / ライブラリ | バージョン |
---|---|
Python | 3.11.3 |
Streamlit | 1.29.0 |
Langchain | 0.0.350 |
ライブラリ
pip install streamlit streamlit_chat langchain openai faiss-cpu tiktoken pypdf
ディレクトリ構成
├── ChatBot-env/ # 仮想環境フォルダ
│ ├── bin/
│ ├── include/
│ ├── lib/
│ └── ...
│
├── app.py # Streamlitアプリケーション
├── chatbot.py # チャットボットのロジック
├── pdf_loader.py # PDF読み込み用のスクリプト
app.py
import os
import streamlit as st
from streamlit_chat import message
from chatbot import conversational_chat, setup_chain
from pdf_loader import load_pdf_data
# UI設定
st.set_page_config(page_title="DocTalk", page_icon=":speech_balloon:")
# タイトルと説明文を追加
st.title("DocTalk: PDF会話型アシスタント")
st.markdown("""
PDFドキュメントから情報を引き出すためのチャットボットです。
OpenAI APIキーを入力し、PDFファイルをアップロードしてください。
""")
# セッション状態の初期化
def initialize_state():
if 'history' not in st.session_state:
st.session_state['history'] = []
if 'generated' not in st.session_state:
st.session_state['generated'] = ["会話を始めるには、PDFファイルをアップロードしてください。"]
if 'past' not in st.session_state:
st.session_state['past'] = ["やあ!"]
initialize_state()
# サイドバー設定
st.sidebar.title("設定")
user_api_key = st.sidebar.text_input("OpenAI APIキー", type="password")
uploaded_file = st.sidebar.file_uploader("PDFファイルをアップロード", type="pdf")
# APIキーとファイルの確認
if user_api_key:
os.environ['OPENAI_API_KEY'] = user_api_key
if uploaded_file:
data = load_pdf_data(uploaded_file)
setup_chain(data)
# チャット履歴の表示
if st.session_state['generated']:
for i in range(len(st.session_state['generated'])):
message(st.session_state["past"][i], is_user=True, key=str(i) + '_user')
message(st.session_state["generated"][i], key=str(i))
# チャット入力と送信ボタンの設定
user_input = st.text_input("質問:", placeholder="PDFデータについてここで話しましょう :)", key='input')
submit_button = st.button('送信')
# ユーザー入力の処理
if submit_button and user_input:
if user_api_key and uploaded_file is not None:
output = conversational_chat(user_input)
st.session_state['past'].append(user_input)
st.session_state['generated'].append(output)
else:
st.warning("APIキーとPDFファイルの両方が必要です。")
chatbot.py
import streamlit as st
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.vectorstores import FAISS
chain = None
def setup_chain(data):
global chain
embeddings = OpenAIEmbeddings()
vectors = FAISS.from_documents(data, embeddings)
chain = ConversationalRetrievalChain.from_llm(
llm=ChatOpenAI(temperature=0.0, model_name='gpt-3.5-turbo-16k'),
retriever=vectors.as_retriever())
def conversational_chat(query):
if chain is None:
return "Chain is not initialized."
result = chain({"question": query, "chat_history": st.session_state['history']})
st.session_state['history'].append((query, result["answer"]))
return result["answer"]
pdf_loader.py
import tempfile
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
def load_pdf_data(uploaded_file):
with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
tmp_file.write(uploaded_file.getvalue())
tmp_file_path = tmp_file.name
loader = PyPDFLoader(file_path=tmp_file_path)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=2000,
chunk_overlap=100,
length_function=len)
return loader.load_and_split(text_splitter)
今回使ったPDF資料
Gammaを使って、架空の会社のメンバー自己紹介スライドを作成しました。
Gammaは、ビジュアルよく簡単にスライドが作成できるのでおすすめです!
完成した会話型PDFアシスタント
まとめ
Langchain、Streamlitを使って、自分自身で手軽にアプリケーションを作成してみたいと思い、今回作成してみました。今回、作成してみて、Streamlitの簡単な操作性に驚きました。直感的で使いやすいUI構築機能になっていて、まだ試していないUIの機能もあるので、これから試していきたいです。
参考資料