A retrieval-augmented generation (RAG) app that lets you chat with your own PDFs/notes, with every answer citing the exact source page — so answers are verifiable, not a black box.
Most "chat with your PDF" tutorials stop at "get an answer." I wanted to extend that into something closer to production practice: every answer traces back to the exact chunk and page it came from, similar to the answer-region-highlighting I built for an AI assessment-grading tool (VedaAI assignment). This project applies that same "make retrieval verifiable" philosophy to a general-purpose notes assistant.
ingest.py— loads PDFs from/data, splits them into overlapping chunks, embeds each chunk with Gemini's embedding model, and stores them in a local ChromaDB vector store.rag_chain.py— takes a question, retrieves the most relevant chunks via vector similarity search, and passes them to Gemini with a strict "only answer from this context" instruction to prevent hallucination. Returns the answer plus the exact source chunks used.app.py— a Streamlit chat interface on top of the above, with an expandable "sources" panel under every answer.
pip install -r requirements.txt
cp .env.example .env # then add your Gemini API keyDrop your PDF notes into the data/ folder, then:
python ingest.py # one-time: builds the vector store
streamlit run app.py # launches the chat UI- LangChain (orchestration)
- ChromaDB (local vector store)
- Embeddings: local by default (
sentence-transformers/all-MiniLM-L6-v2, no API calls, no rate limits) — switchable to Gemini embeddings viaEMBEDDING_PROVIDER=geminiin.env - Google Gemini (LLM for answer generation)
- Streamlit (UI)
Gemini's free-tier embedding API has a tight rate limit, which makes it
unreliable for ingesting more than a few pages at a time. Since embedding
quality for retrieval doesn't need to match generation quality, running
embeddings locally with a small open-source model removes that bottleneck
entirely while keeping generation on Gemini for answer quality. This also
means ingest.py works fully offline after the model's first download.
- Hybrid search (keyword + semantic) for queries with exact terms/numbers
- Support for non-PDF formats (markdown, docx)
- Swap Chroma for a hosted vector DB (Pinecone/Weaviate) for multi-user deployment