This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
VaultExam AI is a 100% local, privacy-first tool that turns a chapter (In any format) into a ready-to-print question paper + answer key and lets you ask questions of the same document with page-cited answers.
Who would pay for it: independent coaching institutes, test-prep tutors, university professors and corporate trainers. Their curated notes and question banks are their intellectual property, and they don't want to upload them to a cloud API. They also spend hours every week typing up mock tests, DPPs and Set A/B variations by hand.
What it does:
- Upload Notes in any format. It is chunked and embedded locally, and the file is deleted from disk straight after ingestion.
- Ask the document: answers come only from your notes, with Page citations.
- Generate an exam: choose the institute name, exam type (Coaching Mock Test, University Mid-Sem, Corporate SOP Quiz), difficulty (Recall, Application, Analytical/Edge Cases) and the number of MCQs, short answers and long answers.
- Set A/B/C: each set draws on different parts of the document and avoids repeating earlier questions.
- Answer key included: MCQ answers with explanations, model answers for short and long questions, marking-scheme key points, and the source page for every question so a teacher can verify it.
- Print or save as PDF straight from the browser.
Demo
Code
https://github.com/ronitsolanki-01/VaultExam.git
How I Built It
Everything runs on the user's own machine. No cloud calls, no per-token fees.
- Backend: Java 21, Spring Boot 4.1.1 and Spring AI 2.0.1
- LLM: an open-weight model (qwen3.5:4b) served by local Ollama
- Embeddings:
nomic-embed-textvia Ollama - Vector store: PostgreSQL with PGVector (pgvector/pgvector:pg16 via Docker Compose), with metadata filtering by
document_id - Ingestion: Spring AI's
TikaDocumentReader and PagePdfDocumentReaderkeeps page number on every chunk, thenTokenTextSplitterchunks it - Frontend: one Next.js page (TypeScript, Tailwind), with window.print() for output
How the exam generator works: it retrieves a sample of chunks from the document, asks the model for MCQs, short answers and long answers in separate structured-output calls, then validates each result (question count, exactly four options, valid answer index) and retries if the local model returns bad JSON. Each set uses a different seeded sample of the document, plus a "don't repeat these questions" list.
Things that bit me on a small local model:
- Reasoning models like
qwen3.5can spend their whole token budget "thinking" and return an empty answer, which breaks JSON parsing. I fixed it by disabling thinking in the Ollama options. - Ollama's default context window silently truncates long RAG prompts, so I set a larger
num-ctxand tuned how many chunks each call retrieves. - Small models sometimes return a bare JSON array instead of an object, so the parsing and validation code handles that and retries.
Why Does Open Innovation Matter?
A closed API would have made this product impossible to sell to its target customers. A coaching institute's notes are its business, and "send your question bank to a third party" is a dealbreaker.
Open-weight models let the whole pipeline run inside the customer's own machine. That also changes the economics: generating a hundred papers costs electricity, not tokens, so a tutor can regenerate Set B at 11pm without watching a bill. And because the stack is open, institutes can swap the model for a bigger one as their hardware allows.



Top comments (0)