Stop AI Hallucinations: Build a RAG Chatbot That Reads Before It Answers
Learn to build a retrieval-augmented generation (RAG) chatbot using Python, LangChain, and Gemini that answers questions only from your uploaded documents, eliminating hallucinations by forcing the AI to read the source material first.
The Problem: Hallucinating Chatbots
Why Standard AI Chatbots Lie
Without access to your documents, AI models answer from training data memory, guessing when uncertain. This creates confident false answers called hallucinations—the model invents information rather than admitting it doesn't know.
Setup: Install and Configure
One-Command Installation
A single terminal command installs three core tools: LangChain (orchestration), Chroma (vector database), and LangChain Google GenAI (Gemini integration). Grab a free Gemini API key and paste it into your code to authenticate.
Step 1: Load and Chunk Your Document
Load Document into Python
Use TextLoader to read your document file (e.g., leave_policy.txt) into Python. For PDFs, swap TextLoader for PyPDFLoader. This pulls the entire file content into a variable for processing.
Split into Searchable Chunks
Documents are too large to search efficiently whole. Use RecursiveCharacterTextSplitter to break the document into small pieces. Set chunk_size to 300 (a few sentences) and chunk_overlap to 50 so sentences cut at boundaries aren't lost.
Step 2: Convert Chunks to Embeddings
What Are Embeddings
An embedding is a list of numbers that captures the semantic meaning of a chunk. Chunks about vacation days get similar number patterns; chunks about sick leave get different ones. This numeric representation allows meaning-based search.
Generate Embeddings with Gemini
Use Gemini's embedding model (e.g., 'models/embedding-001') to convert each chunk into a vector. The same Gemini API key handles both embeddings and later answer generation. If you encounter a model-not-found error, Google has renamed the model—grab the current name from AI Studio.
Step 3: Store in Vector Database
Build Your Knowledge Base with Chroma
Use Chroma's from_documents method to store all chunks and their embeddings in a vector database. A vector database is optimized to hold number lists and search them by similarity at scale. Once stored, your knowledge base is ready to retrieve.
Step 4: Retrieval and Generation (The RAG Magic)
Set Up the Retriever
Create a retriever that searches the vector database when a question arrives. Set k=3 to return the top 3 most relevant chunks by meaning. Raise k if answers are missed; lower it if irrelevant chunks appear.
Configure the Language Model
Initialize ChatGoogleGenerativeAI with temperature=0 to disable creativity and enforce factual answers. Use Gemini 2.5 Flash for speed and free-tier compatibility. Temperature is a creativity dial: 0 means strictly factual, which is essential for RAG.
The RAG Pipeline: Retrieve Then Generate
When a question arrives, retrieve the top k chunks from the vector database, paste them into the prompt, and instruct the model to answer using only those chunks. The model reads the exact lines from your file instead of relying on training memory. This is the core trick that eliminates hallucinations.
Add Transparency with Source Citations
Print the chunk used to generate each answer alongside the response. This gives every answer a receipt—users can verify the source and check accuracy themselves.
Why RAG Works: Open Book vs. Closed Book
The Hallucination Root Cause
The broken bot at the start was taking a closed-book exam, answering from training data memory. When uncertain, it guessed—that guess is a hallucination. RAG converts it to an open-book exam: retrieve the right page first, then answer from it.
What RAG Stands For
RAG is Retrieval Augmented Generation. The model retrieves relevant context first, then generates answers augmented by that context. It reads before it speaks.
When to Use RAG (and When Not To)
Three Cases Where RAG Doesn't Apply
Skip RAG if data is tiny (paste directly in prompt), if you need live numbers like prices or weather (use an API instead), or if the task is creative like writing (RAG is for facts, not imagination).
Notable quotes
Same model, but now it reads before it speaks. — Aksa (MLTut)
Retrieve, then generate. That's literally what RAG stands for. — Aksa (MLTut)
The model is not reaching into its memory anymore. It's reading the exact lines from your file. — Aksa (MLTut)
Action items
- Run the one-command pip install to set up LangChain, Chroma, and Google GenAI.
- Obtain a free Gemini API key from Google AI Studio and paste it into your code.
- Create a text file with your document (or use a PDF and swap TextLoader for PyPDFLoader).
- Load the document and split it into chunks using RecursiveCharacterTextSplitter with chunk_size=300 and chunk_overlap=50.
- Generate embeddings for each chunk using Gemini's embedding model.
- Store chunks and embeddings in Chroma using from_documents.
- Set up a retriever with k=3 to fetch the top 3 most relevant chunks per question.
- Initialize ChatGoogleGenerativeAI with temperature=0 for factual answers.
- Build the RAG pipeline: retrieve chunks, paste into prompt, generate answer.
- Print the source chunk alongside each answer for transparency and verification.
- Test with a question from your document to confirm correct, grounded answers.