The itch
Running PyTorch labs and BERT fine-tuning sessions as a Teaching Assistant at IIIT Lucknow put me in front of the same conceptual confusion, over and over, from different students: why does backprop break on this architecture, what's actually different between an RNN and an LSTM cell, why is this fine-tune overfitting after two epochs. The questions were legitimate. Answering the same one for the fifteenth time wasn't a good use of anyone's time — mine or theirs, since a live queue means everyone waits.
The obvious fix, "just point them at ChatGPT," has an obvious problem: general-purpose LLMs answer confidently whether or not they're right, and a student who doesn't yet know the material has no way to tell a correct explanation from a plausible-sounding wrong one.
What already existed
Generic LLM chatbots are fluent but ungrounded — ask one a subtle ML question and it will produce a clean, well-formatted, occasionally wrong answer with the same confident tone as a right one. There was no shortage of RAG demo projects online either, but most of them stopped at "retrieve some chunks, stuff them in a prompt" without the parts that actually make a RAG system trustworthy in an academic setting: source attribution down to the page, retrieval that favors diverse relevant context over near-duplicate chunks, and guardrails to stop it wandering off-topic.
How I actually built it
I built the knowledge base from two authoritative ML/DL textbooks rather than the open web, so every answer is grounded in material the student can actually go check. Text gets embedded with BAAI/bge-base-en-v1.5 and stored in ChromaDB for semantic search.
For retrieval, I didn't settle for naive top-k similarity search. I layered MMR (Maximal Marginal Relevance) to keep retrieved chunks diverse instead of five near-duplicates of the same paragraph, plus an embedding-filtering step to drop chunks that pass a similarity threshold but aren't actually relevant to the question. Groq's Llama-3.3-70B-versatile generates the final answer — chosen for the inference speed, since a slow answer defeats the purpose in a live lab session — and every response comes back with the source and page number it was pulled from.
Guardrails, not just generation
I added query-filtering guardrails specifically so the assistant rejects questions outside its
knowledge base instead of hallucinating an answer anyway, plus a WindowBufferMemory for
conversation memory, so a student can ask a follow-up without re-explaining their original question.
What it does
- Answers ML/DL concept questions with source citations and page numbers, not unverifiable prose
- MMR retrieval + embedding filtering instead of naive top-k similarity search
- Guardrails that reject off-topic queries rather than answering anyway
- Conversation memory for natural multi-turn follow-ups
- Built on Streamlit for a lightweight, fast-to-iterate interface
Why it matters
This wasn't built as a portfolio flex — it came directly out of a real bottleneck in my own TA work. Cutting the repeat-question load frees up TA time for the questions that actually need a human, and giving students a citation instead of an unverifiable answer is the difference between a study tool and a liability.