NEET Biology Question & Answer Generation System β Project Report
1. Project Objective
Build an end-to-end AI-powered Question Answering system for NEET Biology that:
- Ingests NCERT Class 11 & 12 Biology textbooks (PDFs)
- Chunks, embeds, and stores them in a vector database
- Uses a Retrieval-Augmented Generation (RAG) pipeline to answer student questions grounded in NCERT content
- Fine-tunes a BERT classifier to predict which chapter a question belongs to β enabling targeted retrieval and routing
- Exposes the pipeline via a FastAPI backend (planned)
The system is designed for NEET exam preparation, where every answer must be traceable back to specific NCERT textbook content.
2. High-Level Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER QUESTION β
ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββ
β BERT Chapter Classifier β β Classification/ (fine-tuned bert-base-uncased)
β Predicts: chapter_id β
ββββββββββββ¬ββββββββββββββββ
β chapter filter (planned integration)
βΌ
ββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ
β RAG Pipeline (rag/) ββββββΆβ Supabase + pgvector β
β 1. Embed question β β Table: ncert_knowledge_ β
β 2. Retrieve top-k chunksβββββββ chunks β
β 3. Build prompt β β RPC: match_ncert_chunks() β
β 4. Generate answer (LLM)β βββββββββββββββββββββββββββββββ
β 5. Justify + Verify β
β 6. Confidence score β
ββββββββββββ¬ββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββ
β FastAPI Backend (TBD) β β /qa endpoint, /ingest, /health
ββββββββββββββββββββββββββββ
3. Complete Tech Stack
| Layer |
Technology |
Purpose |
| Language |
Python 3.10+ |
Core runtime |
| PDF Extraction |
PyMuPDF 1.23.8 |
Extract text from NCERT PDFs |
| Chunking |
Custom (clean_pdf_to_json.py) |
Section-aware chunking with metadata |
| Embedding Model |
BAAI/bge-small-en-v1.5 (384-dim) |
Local embedding generation via sentence-transformers |
| Vector Database |
Supabase + pgvector |
Cloud-hosted PostgreSQL with vector similarity search |
| Vector Index |
HNSW (via pgvector) |
Fast approximate nearest-neighbor search |
| LLM Provider |
Groq API |
Free, fast inference (llama-3.3-70b-versatile) |
| Classification |
HuggingFace bert-base-uncased |
Fine-tuned for chapter prediction |
| Training Framework |
HuggingFace Trainer + PyTorch |
BERT fine-tuning with early stopping |
| Backend (planned) |
FastAPI + Uvicorn |
REST API serving |
| Data Validation |
Pydantic |
Request/response schemas |
| Environment |
python-dotenv |
Secrets management via .env |
| Dependencies |
pip + requirements.txt |
All versions pinned for reproducibility |
4. Repository Structure
Question_AndAnswerGeneration/
βββ .env # (gitignored) API keys
βββ .gitignore # .venv, .env, __pycache__, *.pyc
βββ requirements.txt # All dependencies pinned
βββ taxonomy_full.txt # Complete NCERT syllabus taxonomy
β
βββ pdf_to_embedding/ # π’ PHASE 1: Data Pipeline
β βββ .env / .env.example # Supabase + Groq credentials
β βββ clean_pdf_to_json.py # PDF β section-aware JSON chunks
β βββ embed_and_upload.py # JSON β embeddings β Supabase upsert
β βββ supabase_schema.sql # Table + RPC + HNSW index DDL
β βββ json_ouput/ # Intermediate JSON files
β βββ 11th Ncert output/ # 19 files (Kebo101βKebo119)
β βββ 12th Ncert Output/ # 13 files (Lebo101βLebo113)
β
βββ rag/ # π’ PHASE 2: RAG Pipeline
β βββ __init__.py
β βββ retriever.py # Embed question β Supabase RPC β top-k chunks
β βββ prompt_builder.py # Build answer/justification/verifier prompts
β βββ generator.py # Groq LLM calls (answer + justify + verify)
β βββ confidence.py # Confidence scorer (retrieval + verification)
β βββ pipeline.py # Orchestrator with smoke test (--debug flag)
β
βββ Classification/ # π‘ PHASE 3: BERT Classifier (scaffold ready)
βββ __init__.py
βββ config.json # All hyperparameters (model, lr, epochs, etc.)
βββ dataset.py # PyTorch Dataset + label_map builder
βββ train.py # Full HuggingFace Trainer script
βββ predict.py # ClassifierPredictor inference wrapper
βββ data/
βββ sample_questions.json # Placeholder labeled data (3 examples)
βββ label_map.json # (auto-generated) chapter_id β chapter_name
5. What Is Completed β
Phase 1 β Data Ingestion Pipeline β
Data stats: 32 JSON files β ~696 chunks with metadata (chapter, section, section_title, chunk_text, embedding vector).
Phase 2 β RAG Pipeline β
| Component |
File |
What It Does |
| Retriever |
retriever.py |
Embeds query β calls match_ncert_chunks RPC β returns top-k relevant chunks |
| Prompt Builder |
prompt_builder.py |
Constructs 3 prompt types: answer, justification, verifier |
| Generator |
generator.py |
Calls Groq API for answer generation, step-by-step justification, and YES/NO faithfulness verification |
| Confidence Scorer |
confidence.py |
Combines retrieval similarity + verifier output into a 0-1 confidence score |
| Pipeline Orchestrator |
pipeline.py |
End-to-end flow: question β retrieve β generate β justify β verify β confidence. Includes --debug smoke test |
RAG design highlights:
- Multi-stage pipeline: Retrieve β Answer β Justify β Verify β Confidence
- Singleton pattern for Supabase client, embedding model, and Groq client (no repeated initialization)
- Similarity threshold of 0.1 (tuned lower to avoid false negatives with limited data)
- Groq model:
llama-3.3-70b-versatile β fast, free tier, high quality
Phase 3 β BERT Classification Layer π‘ (Scaffold Complete)
| Component |
File |
Status |
| Config |
config.json |
β
All hyperparameters defined |
| Dataset class |
dataset.py |
β
Tokenizer + label_map builder |
| Training script |
train.py |
β
Full Trainer with early stopping, F1 metric |
| Inference wrapper |
predict.py |
β
ClassifierPredictor with top-k + confidence |
| Labeled training data |
data/ |
π΄ Only 3 sample examples β needs real NEET questions |
Classifier config:
{
"model_name": "bert-base-uncased",
"max_length": 128,
"num_labels": 16,
"batch_size": 16,
"learning_rate": 2e-5,
"num_epochs": 10,
"warmup_ratio": 0.1,
"eval_strategy": "epoch",
"metric_for_best_model": "f1",
"early_stopping_patience": 2
}
6. NCERT Dataset Summary
| Class |
Chapters |
Files |
Total Chunks |
Unique Sections |
| 11th |
19 (Ch 1β19) |
Kebo101βKebo119 |
~263 |
~200+ |
| 12th |
12 (Ch 2β13) + 1 front matter |
Lebo101βLebo113 |
~433 |
~150+ |
| Total |
32 |
32 JSON files |
~696 |
~350+ |
Note: Class 12 Chapter 1 (Reproduction in Organisms) is missing β Lebo101.json contains only front matter. Needs re-processing.
7. Environment Variables
SUPABASE_URL=https://xxxxx.supabase.co
SUPABASE_KEY=eyJhbG... # Service Role Key
GROQ_API_KEY=gsk_... # Free tier API key
GROQ_MODEL=llama-3.3-70b-versatile # Default LLM
EMBEDDING_MODEL=BAAI/bge-small-en-v1.5 # 384-dim local embeddings
8. What Remains β Roadmap π
Immediate (Next Steps)
| # |
Task |
Priority |
Effort |
| 1 |
Collect & label NEET questions β map each to chapter_id |
π΄ Critical |
Medium |
| 2 |
Run BERT training (python -m Classification.train) |
π΄ Critical |
Low (code ready) |
| 3 |
Evaluate classifier β target >85% F1 on held-out set |
π΄ Critical |
Low |
| 4 |
Fix Lebo101.json β re-process Ch 1 Reproduction in Organisms PDF |
π‘ Medium |
Low |
Short-Term (Integration)
| # |
Task |
Priority |
| 5 |
Integrate classifier into RAG β use predicted chapter to filter retrieval (pre-filter Supabase query by chapter metadata) |
π΄ Critical |
| 6 |
Build FastAPI backend β /qa endpoint wrapping pipeline.run(), /health, /ingest |
π‘ Medium |
| 7 |
Add syllabus_taxonomy.json β structured JSON of all chapters/sections for the classifier and frontend |
π‘ Medium |
Medium-Term (Production Readiness)
| # |
Task |
Priority |
| 8 |
Add unit + integration tests for RAG pipeline and classifier |
π‘ Medium |
| 9 |
Build frontend UI (React / Streamlit) for question input + answer display |
π’ Nice-to-have |
| 10 |
Add question generation capability (generate practice MCQs from NCERT content) |
π’ Future |
| 11 |
Deploy to cloud (Render / Railway / Docker) |
π’ Future |
9. Key Design Decisions
| Decision |
Rationale |
| BGE-small-en-v1.5 over larger models |
384-dim is fast and good enough for NCERT-level text; runs locally without GPU |
| Supabase + pgvector over Pinecone/Weaviate |
Free tier, PostgreSQL ecosystem, full SQL alongside vectors |
| Groq API over OpenAI/Anthropic |
Free tier with fast inference; llama-3.3-70b is competitive quality |
| bert-base-uncased for classification |
Lightweight, well-studied for text classification; fine-tunes on a single GPU |
| Section-aware chunking |
Each chunk carries chapter/section metadata β enables filtered retrieval |
| Multi-stage RAG (answer β justify β verify) |
Reduces hallucination by adding a verification layer before presenting answers |
| Singleton pattern for clients |
Avoids expensive re-initialization of embedding model, Supabase client, Groq client |
10. How to Run (Quick Reference)
.\.venv\Scripts\activate
python pdf_to_embedding/clean_pdf_to_json.py --input "path/to/chapter.pdf"
python pdf_to_embedding/embed_and_upload.py
python -m rag.pipeline --debug
python -m Classification.train
python -m Classification.predict