Major (Capstone) Project — Retrieval-Augmented Generation
🔗 Live Demo: https://interview-copilot-rag.onrender.com 📦 Repo: https://github.com/prachi463/interview-copilot-rag
Note: hosted on Render's free tier — the app may take ~50 seconds to wake up if it's been inactive.
Ask natural-language questions about my background ("Walk me through your NTPC project", "What's the hardest bug you fixed?") and get answers grounded in my actual resume, internship report, and project docs — with cited sources, not hallucinated claims.
┌─────────────────────┐
User Query ───▶ │ Query Router │ rule-based intent classifier:
│ (rag_chain.py) │ project_technical / resume_fact / behavioral
└──────────┬───────────┘
│ (adjusts top_k + prompt framing per intent)
▼
┌──────────────────────────────┐
│ Hybrid Retriever │
│ (retriever.py) │
│ │
│ ┌───────────┐ ┌───────────┐ │
│ │ FAISS │ │ BM25 │ │
│ │ dense │ │ sparse │ │
│ │ cosine │ │ keyword │ │
│ └─────┬─────┘ └─────┬─────┘ │
│ └──────┬────────┘ │
│ Reciprocal Rank Fusion │
└───────────────┬──────────────────┘
▼
Top-k chunks + confidence scores
▼
┌───────────────────────────────┐
│ Generation (llm_backends.py) │
│ Groq → OpenAI → Extractive │
│ fallback (in priority order) │
└───────────────┬───────────────┘
▼
Answer + cited sources
(app.py — Streamlit chat UI)
- Hybrid retrieval, not just vector search. Dense embeddings (FAISS) catch semantic/ paraphrase matches; BM25 catches exact-term matches (numbers, proper nouns like "ESP32") that embeddings can blur together. Reciprocal Rank Fusion combines both rankings without needing a hand-tuned blending weight.
- Query routing. A lightweight rule-based classifier detects whether a question is a
technical deep-dive, a factual resume lookup, or a behavioral question, and adjusts
retrieval depth (
top_k) and prompt framing accordingly — factual questions get a tight, short retrieval; technical questions pull more context. - Pluggable everything. Embedding backend (
embeddings.py) and LLM backend (llm_backends.py) are both swappable via one-line config/env changes, not hardcoded. - Fails gracefully, not silently. With no API key configured, the app doesn't crash or fake an answer — it clearly labels an extractive fallback response built directly from the retrieved chunks, so the system is always demo-able.
- Source-grounded, with visible confidence. Every answer shows which document chunks it came from and a match-confidence score, so claims are auditable rather than opaque.
rag_resume_assistant/
├── knowledge_base/ # source documents (swap in your real resume/reports/docs)
│ ├── resume.md
│ ├── ntpc_internship_report.md
│ ├── unit_ctrl_project.md
│ └── interview_prep_qna.md
├── vector_store/ # generated by ingest.py — FAISS index, BM25 index, chunks
├── embeddings.py # pluggable embedding backends (TF-IDF default, sentence-transformers optional)
├── ingest.py # document loading, chunking, index building
├── retriever.py # hybrid dense+sparse retrieval with RRF
├── llm_backends.py # Groq / OpenAI / extractive-fallback generation backends
├── rag_chain.py # query routing + prompt construction + orchestration
├── app.py # Streamlit chat UI
├── requirements.txt
├── .env.example
└── .streamlit/config.toml
pip install -r requirements.txtReplace the files in knowledge_base/ with your actual resume, internship report(s), and
project write-ups. Supported formats: .md, .txt, .pdf, .docx.
cp .env.example .env
# edit .env and add GROQ_API_KEY (free tier: console.groq.com/keys) or OPENAI_API_KEYWithout a key, the app still runs — it falls back to showing the most relevant retrieved excerpts directly instead of a generated natural-language answer.
python ingest.pyRe-run this any time you change files in knowledge_base/.
streamlit run app.pyThis project is deployed on Render as a Web Service:
- Push the repo to GitHub.
- On Render, create a New Web Service connected to the GitHub repo, branch
main. - Build Command:
pip install -r requirements.txt - Start Command:
streamlit run app.py --server.port $PORT --server.address 0.0.0.0 - Add environment variables (API keys, embedding backend config, etc.) under the Environment
tab — Render supports bulk-adding via Add from .env. Never commit your real
.envfile to GitHub; keep secrets only in Render's environment settings. - Deploy. Render auto-redeploys on every push to
main.
Note: on Render's free tier, the instance spins down after inactivity, so the first request after idle time can take up to ~50 seconds.