Hey Devs! ๐
Have you ever wanted to chat with your favorite books like you're texting a friend? ๐๐ฌ
Well, you're in the right place! In this blog post, Iโll walk you through how I built BookChatBot, an AI-powered chatbot that can answer questions about a book, using:
- ๐ง LangChain (for LLM logic)
- ๐ฒ Pinecone (for vector search)
- ๐งพ PDF loading and splitting
- โก Google Gemini (for answering questions)
- ๐งช Flask (as the web framework)
You can find the full code on GitHub:
๐ GitHub Repo
๐ก What are we building?
We're building a chatbot web app that can read PDFs (like a book ๐), store them in Pineconeโs vector database, and allow users to ask questions about the content!
The AI will retrieve the most relevant chunks and generate human-like answers using Google's Gemini model.
๐ธ Note: Pineconeโs free tier only allows one index. So for now, you can't dynamically upload new books โ but once set up, it's super efficient for Q&A!
๐๏ธ Project Structure
bookchatbot-/
โโโ app.py # Flask app and RAG chain
โโโ helper.py # PDF loading, chunking, and embeddings
โโโ src/
โ โโโ prompt.py # System prompt for LLM
โโโ data/ # Folder with your PDF files
โโโ templates/
โ โโโ chat.html # Simple frontend
โโโ .env # API keys (not shared!)
๐ง How does it work?
This is a RAG (Retrieval-Augmented Generation) pipeline:
- Load and split PDFs into chunks
- Convert chunks into vector embeddings
- Store in Pinecone (vector DB)
- Accept user question
- Find the top relevant chunks (via Pinecone)
- Use Gemini to answer based on retrieved content
๐งพ helper.py โ Preprocessing the PDFs
def load_pdf(data):
loader = DirectoryLoader(data, glob="*.pdf", loader_cls=PyMuPDFLoader)
return loader.load()
๐ฅ We load all PDFs from the data/ folder.
def text_splitter(extraced_date):
text_split = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=20)
return text_split.split_documents(extraced_date)
๐ We split documents into manageable 500-token chunks to help with better retrieval.
def load_geneni_embeddings():
embeddings = GoogleGenerativeAIEmbeddings(
model="models/embedding-001",
google_api_key=os.getenv("GOOGLE_API_KEY")
)
return embeddings
๐ We use Google's embedding model to turn text chunks into vectors!
๐ app.py โ The Flask App + AI Brain
We start by setting up Pinecone:
pc = Pinecone(api_key= PINECONE_API_KEY)
docsearch = PineconeVectorStore.from_existing_index(index_name="bookchat", embedding=embeddings)
retriver = docsearch.as_retriever(search_type="similarity", search_kwargs={"k": 3})
๐ง This allows us to retrieve 3 most similar chunks from our stored book.
Then we build a prompt + Gemini LLM:
llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash")
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}"),
])
๐ฌ system_prompt defines how the AI should behave (e.g., polite, detailed).
Create the RAG chain:
question_answer_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriver, question_answer_chain)
๐ก This is the brain of the chatbot โ retrieval + generation.
Finally, the Flask endpoints:
@app.route("/")
def index():
return render_template('chat.html')
@app.route("/get", methods=["GET", "POST"])
def chat():
msg = request.form["msg"]
response = rag_chain.invoke({"input": msg})
return str(response["answer"])
๐ก The front end sends a message โ gets a smart reply from the AI!
๐งช Testing it Out
Just run:
python app.py
Then open http://localhost:8080 and start chatting with your book! ๐จ๏ธ๐
โ ๏ธ Limitations
- Pineconeโs free tier = only one index. So, you can't upload new books at runtime unless you upgrade or manage your own embedding storage.
- Static loading: you must re-run the app if you want to embed a different book.
- Basic HTML frontend โ could be upgraded with React, Tailwind, or Chat UI kits.
๐ ๏ธ Ideas for Improvements
- Add file upload (if using a paid Pinecone plan or local vector store like FAISS)
- Use streaming responses for a more chat-like feel
- Add authentication and user-specific history
- Display source chunk(s) below each answer for transparency
๐ Conclusion
Building an AI chatbot like this is easier than ever thanks to:
- ๐ง LangChain for chaining LLM workflows
- ๐ฒ Pinecone for fast vector search
- โก Google Gemini for intelligent responses
- ๐งช Flask for quick APIs
If you liked this post, donโt forget to โญ the GitHub repo and follow me here on Dev.to!
Got questions or ideas? Drop them below! ๐ฌ๐
Top comments (0)