Live demo: Add your public Streamlit Community Cloud URL here after deployment.
An end-to-end, citation-first PDF question-answering system built for the AI Engineer Intern assessment. Upload a multi-page, text-based PDF, then ask questions in a live chat UI. The assistant is constrained to retrieved document excerpts and displays source citations plus the retrieved context.
- PDF extraction with PyMuPDF, retaining page boundaries.
- 700-token chunks with a 100-token overlap (about 14%), each with a stable
[Page N, Chunk N]citation. - Normalized
sentence-transformers/all-MiniLM-L6-v2embeddings stored persistently in Chroma (cosine distance). - Bonus: hybrid retrieval using Chroma dense retrieval + BM25 keyword ranking fused with Reciprocal Rank Fusion (RRF).
- Strict, zero-temperature Groq + Llama 3.3 70B prompt: unsupported questions must return
Information not found in the provided document. - Bonus: streamed answers, a collapsible retrieved-context panel, and automated citation/faithfulness-proxy metrics.
- Graceful errors for unreadable/scanned PDFs. When no Groq key is configured, the UI makes this clear and provides only retrieved extractive excerpts—never an ungrounded answer.
PDF upload → PyMuPDF extraction → overlapping page chunks → MiniLM embeddings → Chroma
Question → MiniLM dense search ─┐
BM25 keyword search ───┼→ RRF hybrid ranking → grounded LLM stream → citations/UI
└→ retrieved-context inspection + citation check
Requires Python 3.10+.
git clone <your-public-repository-url>
cd qa_rag
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Add GROQ_API_KEY to .env for LLM-generated answers
streamlit run app.pyThe first run downloads the embedding model. PDFs are indexed locally in data/chroma/ (gitignored). Do not upload sensitive documents to a shared deployment unless its storage and access policy permit it.
pytest -q-
Create a new public empty repository on your GitHub account. Do not initialize it with a README.
-
From this project directory, publish it yourself (replace the URL):
git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPOSITORY.git git branch -M main git push -u origin main
-
Visit share.streamlit.io, sign in with GitHub, click Create app, choose that repository and branch, and set the main file path to
app.py. -
Before deploying, open Advanced settings → Secrets and add:
GROQ_API_KEY = "your-groq-api-key" GROQ_MODEL = "llama-3.3-70b-versatile"
-
Click Deploy. Streamlit will build from
requirements.txtand provide a publichttps://<subdomain>.streamlit.appURL. Test it with a multi-page PDF, then replace the Live demo placeholder at the top of this README with that URL and commit/push the README update.
For Render or another container host, use the supplied Dockerfile and configure the same environment variables.
Before submission, record a brief GIF/video showing: upload a multi-page PDF → successful indexing → a question → streamed answer with citations → expanded retrieved context. Add it here, for example:
app.py Streamlit UI
rag/pdf.py PDF text extraction
rag/chunking.py Page-aware overlap chunking
rag/embeddings.py MiniLM embeddings
rag/store.py Persistent Chroma vector store
rag/retrieval.py BM25 + dense RRF hybrid retriever
rag/generation.py Strict grounded LLM streaming
rag/evaluation.py Citation validation metric
tests/ Fast unit tests
Only the selected excerpts are sent to the LLM. The prompt prohibits outside knowledge and requires citations on factual claims. This reduces hallucination risk but cannot mathematically guarantee provider compliance, so the application also exposes the exact retrieval context and validates cited chunks. Image-only/scanned PDFs require OCR before use.