Chat with Multiple PDFs | LangChain App Tutorial in Python (Free LLMs and Embeddings)
Education
Introduction
In this tutorial, we will walk you through the steps to build a chatbot application that can interact with multiple PDF documents at once. This application will utilize Python, the LangChain library, and various language models, both from OpenAI and Hugging Face. To ensure you don't incur excessive costs while learning, we'll showcase free models as well. Let’s jump in!
Overview
The goal of our application is to allow users to upload PDF documents (like the U.S. Constitution and the Bill of Rights), process them, and then ask questions related to their content. The chat interface will provide answers based solely on the information contained within the uploaded PDFs.
Setting Up the Environment
We will begin by setting up our development environment using Python 3.9 and creating a virtual environment. You need to install the following dependencies:
pip install streamlit PyPDF2 langchain python-dotenv files-cpu openai huggingface-hub
Building the User Interface
We will create the user interface using Streamlit:
- Start by setting the configuration of the Streamlit page.
- Add a header and a text input for the user to ask questions.
- Include a sidebar where users can upload their PDF files.
The following code snippet demonstrates how to set this up:
import streamlit as st
st.set_page_config(page_title="Chat with Multiple PDFs", page_icon="?")
st.header("Chat with Multiple PDFs ?")
user_question = st.text_input("Ask a question about your documents:")
pdf_docs = st.sidebar.file_uploader("Upload your PDFs here", accept_multiple_files=True)
if st.sidebar.button("Process"):
pass # Button Logic Here
Processing PDF Files
Next, we will implement the logic to read the content from the uploaded PDF files. We will use the PyPDF2
library, which allows us to extract raw text from the PDFs. The extracted text will then be divided into smaller chunks for easier processing.
from PyPDF2 import PdfReader
def get_pdf_text(pdf_docs):
text = ""
for pdf in pdf_docs:
pdf_reader = PdfReader(pdf)
for page in pdf_reader.pages:
text += page.extract_text()
return text
Chunking the Text
Once we have the raw text, we will split it into manageable chunks. This is done using LangChain's CharacterTextSplitter
, which helps maintain context between chunks:
from langchain.text_splitter import CharacterTextSplitter
def get_text_chunks(raw_text):
text_splitter = CharacterTextSplitter(separator="\n", chunk_size=1000, chunk_overlap=200)
return text_splitter.split_text(raw_text)
Creating a Vector Store
Embeddings play a crucial role in retrieving relevant information for the user's questions. We will use OpenAI's and Hugging Face's models to create a vector store from the embedding representations of our text chunks. For OpenAI's embeddings, the installation of the OpenAI package is required, and the following code snippet demonstrates how to create this store:
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
def create_vector_store(text_chunks):
embeddings = OpenAIEmbeddings()
vector_store = FAISS.from_texts(text_chunks, embeddings)
return vector_store
Implementing Memory in the Chatbot
LangChain allows us to create conversational chains with memory capabilities. This means users can ask follow-up questions, and the bot will maintain context:
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationalBufferMemory
def create_conversation_chain(vector_store):
memory = ConversationalBufferMemory(memory_key="chat_history", return_messages=True)
conversational_chain = ConversationalRetrievalChain.from_llm(OpenAIChat(), vector_store, memory=memory)
return conversational_chain
Displaying the Chat Messages
To display chat messages in a user-friendly interface, we can use HTML and CSS to format the appearance of messages from both the user and the bot. By replacing specific variables with message content, we create a visually pleasing chat environment.
def display_chat(chat_history):
for i, message in enumerate(chat_history):
if i % 2 == 0:
st.write(user_template.replace("(message)", message["content"]))
else:
st.write(bot_template.replace("(message)", message["content"]))
Conclusion
In this tutorial, we've covered the end-to-end process of building a chatbot that can answer questions based on the content of multiple PDFs. By utilizing free models and efficient coding practices with Python and LangChain, you can create a functional application capable of processing and responding to user queries.
Keywords
- Chatbot
- Python
- PDFs
- LangChain
- OpenAI
- Hugging Face
- Embeddings
- Streamlit
FAQ
What programming language is used in this tutorial?
This tutorial uses Python for building the chatbot application.
Can the chatbot answer questions from any PDF document?
Yes, the chatbot can answer questions based solely on the content of the uploaded PDF documents.
Are the embeddings used in this application paid?
The tutorial demonstrates the use of both OpenAI’s paid embeddings and free models from Hugging Face.
How does the chatbot maintain context between questions?
The chatbot uses LangChain’s built-in memory features, specifically the Conversational Buffer Memory, to remember previous questions and answers.
Is this application scalable?
Yes, the application can be enhanced further by integrating persistent databases or using more advanced models as required.