1. Project Overview

This project is a production-ready Conversational RAG (Retrieval-Augmented Generation) chatbot built with Streamlit. Users upload one or more PDF files, and the app allows them to ask questions about the content in a multi-turn conversation. The app maintains full chat history across turns so follow-up questions are understood in context.

1.1 Key Features

  • Upload multiple PDFs and chat with their combined content
  • Session-based memory — follow-up questions understand previous context automatically
  • Groq LLaMA 3.3 70B as the LLM — fast and 100% free
  • HuggingFace MiniLM embeddings — no OpenAI key needed
  • ChromaDB persistent vector store — stored locally in ./chroma_db
  • API key loaded from .env — no input box in the UI
  • Clean Streamlit UI with expandable chat history viewer

1.2 Tech Stack

LayerTechnologyPurpose
UIStreamlitWeb interface for file upload and chat
LLMGroq API — llama-3.3-70b-versatileAnswering questions from retrieved context
EmbeddingsHuggingFace all-MiniLM-L6-v2Converting text chunks to vectors
Vector StoreChromaDB (PersistentClient)Storing and retrieving document embeddings
MemoryRunnableWithMessageHistorySession-based multi-turn conversation memory
Document LoaderPyPDFLoaderLoading and parsing uploaded PDF files
Text SplitterRecursiveCharacterTextSplitterChunking documents (5000 chars, 500 overlap)
Chaincreate_history_aware_retrieverReformulates questions using chat history
Chaincreate_retrieval_chainCombines retriever + LLM into full RAG pipeline
Configpython-dotenvLoads GROQ_API_KEY and HF_TOKEN from .env

2. Architecture

2.1 How RAG + Memory Works

When a user asks a question, the system first reformulates it as a standalone question using chat history (so follow-ups like ‘tell me more about that’ work). Then it retrieves relevant chunks from ChromaDB, passes them as context to Groq LLaMA, and returns a concise answer.

PDF Upload
    ↓ PyPDFLoader → RecursiveCharacterTextSplitter
    ↓ HuggingFace Embeddings → ChromaDB (local)
User Question + Chat History
    ↓ create_history_aware_retriever (Groq) → Standalone Question
    ↓ ChromaDB Retriever → Relevant Chunks
    ↓ create_stuff_documents_chain (Groq LLaMA 3.3 70B)
    ↓ Answer → Streamlit UI + ChatMessageHistory updated

2.2 LangChain Components

ComponentWhat It Does
create_history_aware_retrieverTakes the LLM + retriever + contextualize prompt. Rewrites user’s question into a standalone question if chat history exists.
create_stuff_documents_chainTakes the LLM + QA prompt. Stuffs retrieved docs into the context window and generates an answer.
create_retrieval_chainCombines the history-aware retriever and the document chain into a single invokable pipeline.
RunnableWithMessageHistoryWraps the RAG chain. Automatically loads and saves ChatMessageHistory per session_id.
ChatMessageHistoryIn-memory store of HumanMessage and AIMessage objects per session. Stored in st.session_state.

3. Installation & Setup

3.1 Prerequisites

RequirementDetails
Python3.10 or higher (tested on 3.11)
pipLatest version recommended
GitTo clone the repository
Groq API KeyFree at console.groq.com — no credit card needed
HuggingFace TokenFree at huggingface.co/settings/tokens

3.2 Installation Steps

Step 1 — Clone the repo

git clone https://github.com/shivamrawat2002/conversational-rag-pdf-chatbot/tree/main
cd Conversational-QnA-Chatbot

Step 2 — Create and activate virtual environment

python -m venv venv
venv\Scripts\activate     # Windows
source venv/bin/activate  # Mac/Linux

Step 3 — Install dependencies

pip install streamlit langchain-classic langchain-core langchain-community
pip install langchain-chroma langchain-groq langchain-huggingface
pip install langchain-text-splitters chromadb pypdf python-dotenv

Step 4 — Create .env file in project root

GROQ_API_KEY=gsk_your_groq_key_here
HF_TOKEN=hf_your_huggingface_token_here

Step 5 — Run the app

streamlit run app.py

Open http://localhost:8501 in your browser. Upload a PDF and start chatting!

4. Usage Guide

4.1 How to Use the App

StepAction
1Open the app at http://localhost:8501
2Optionally change the Session ID field (default: ‘default_session’)
3Click ‘Choose PDF file(s)’ and upload one or more PDFs
4Wait for documents to be processed and embedded into ChromaDB
5Type your question in the ‘Your question:’ input box and press Enter
6Read the Assistant’s answer below
7Click ‘Chat History’ expander to see the full conversation so far
8Ask follow-up questions — the app remembers context automatically

4.2 Session ID Explained

The Session ID field lets you run multiple independent conversations. Each session has its own isolated chat history. If you want a fresh conversation, change the Session ID. Useful for comparing answers across different research sessions.

4.3 Tips for Best Results

  • Use specific questions rather than vague ones — e.g. ‘What are the key findings in section 3?’ works better than ‘Tell me about the document’
  • Upload multiple related PDFs together — they are all embedded into the same ChromaDB collection
  • If answers seem off, try re-uploading the PDF — this re-chunks and re-embeds the content
  • Keep Breadth and Depth in mind — larger PDFs with more chunks give richer, more accurate answers
  • The chat history expander shows both Human and AI messages for full transparency

5. Configuration & Customization

5.1 Changing the LLM Model

Edit app.py line 33 to use a different Groq model:

# Current (recommended):
llm = ChatGroq(groq_api_key=api_key, model_name=’llama-3.3-70b-versatile’)

# Other free Groq models:
# model_name=’llama-3.1-8b-instant’   (faster, smaller)
# model_name=’mixtral-8x7b-32768′     (older, still free)

5.2 Changing Chunk Size

Edit app.py to adjust how PDFs are split:

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=5000,   # characters per chunk (increase for more context)
    chunk_overlap=500  # overlap between chunks (increase to reduce cut-offs)
)

5.3 Changing the Embedding Model

Edit app.py to use a different HuggingFace embedding model:

# Current (fast, lightweight):
embeddings = HuggingFaceEmbeddings(model_name=’all-MiniLM-L6-v2′)

# Higher quality alternative:
# embeddings = HuggingFaceEmbeddings(model_name=’all-mpnet-base-v2′)

6. Project File Structure

Conversational-QnA-Chatbot/
├── app.py              # Main Streamlit app — all logic lives here
├── .env               # API keys (GROQ_API_KEY, HF_TOKEN) — never commit!
├── requirements.txt   # Python dependencies
├── chroma_db/         # Auto-created — persistent ChromaDB vector store
├── temp.pdf           # Temporary file for uploaded PDF processing
└── venv/              # Python virtual environment

Demo Video