AI-powered adaptive quiz engine — ingest educational PDFs, generate questions with Groq AI, and serve them through a REST API with intelligent difficulty adjustment.
AdaptIQ ingests educational PDFs, chunks and indexes the content, then uses Groq's Llama 3.3 70B to generate MCQ, True/False, and Fill-in-the-blank questions. A streak-based adaptive engine adjusts difficulty in real time as students answer:
- Upload any educational PDF → auto-chunked and indexed
- Groq generates 3 question types per chunk at ~300 tokens/second
- Adaptive difficulty: promotes after 3 correct, demotes after 2 wrong
- Full student profile and answer history tracking
PDF Upload
│
▼
POST /ingest ← multipart/form-data (file + grade + subject)
│ ingestion/ingester.py
│ ├─ PDFExtractor (PyMuPDF) → raw text per page
│ └─ TextProcessor → clean, paragraph-chunk, extract topic
│
▼
SQLite (adaptiq.db)
├─ source_documents
├─ content_chunks
├─ quiz_questions
├─ student_answers
└─ student_profiles
│
▼
POST /generate-quiz ← { source_id, questions_per_chunk }
│ quiz/service.py
│ └─ QuizGenerator → Groq llama-3.3-70b-versatile
│ MCQ · True/False · Fill-in-the-blank
│ duplicate detection per source
│
▼
GET /quiz ← ?topic= &difficulty= &subject= &grade= &limit=
POST /submit-answer ← { student_id, question_id, selected_answer }
│ evaluation/service.py
│ └─ AdaptiveEngine → streak-based difficulty adjustment
│
▼
GET /student/{id}/profile
GET /student/{id}/history
GET /student/{id}/next-question
GET /health
| Event | Effect |
|---|---|
| 3 consecutive correct answers | Promote: easy → medium → hard |
| 2 consecutive incorrect answers | Demote: hard → medium → easy |
| Promotion / demotion | Streak counter resets |
AdaptIQ/
├── main.py # FastAPI app entry point — all route definitions
├── requirements.txt # Python dependencies
├── .env.example # Environment variable template
├── data/ # Sample PDFs for ingestion
├── samples/ # Example outputs: chunks, questions, API responses, DB schema
├── models/
│ ├── database.py # SQLAlchemy engine, SessionLocal, get_db()
│ ├── db_models.py # ORM models: 5 tables with FK relationships
│ └── schemas.py # Pydantic v2 request / response schemas
├── ingestion/
│ ├── pdf_extractor.py # PyMuPDF text extraction
│ └── ingester.py # Ingestion pipeline orchestrator
├── processing/
│ └── text_processor.py # Text cleaning, chunking, topic extraction
├── quiz/
│ ├── generator.py # Groq-powered question generation
│ └── service.py # Question generation, dedup, retrieval
└── evaluation/
├── adaptive.py # Streak-based difficulty adjustment engine
└── service.py # Answer submission, student profile, history
- Python 3.12
- A free Groq API key
git clone https://github.com/lohith-1204/AdaptIQ.git
cd AdaptIQ
python3.12 -m venv venv
source venv/bin/activate
pip install -r requirements.txtcp .env.example .envSet in .env:
GROQ_API_KEY=your_groq_api_key_here
DATABASE_URL=sqlite:///./adaptiq.db
uvicorn main:app --reload- API:
http://localhost:8000 - Swagger docs:
http://localhost:8000/docs
| Method | Endpoint | Description |
|---|---|---|
| POST | /ingest |
Upload a PDF and index its content |
| POST | /generate-quiz |
Generate questions from an ingested source |
| GET | /quiz |
Retrieve questions with filters |
| POST | /submit-answer |
Submit a student answer, get feedback + new difficulty |
| GET | /student/{id}/profile |
Current difficulty, accuracy, stats |
| GET | /student/{id}/history |
Full answer history, newest first |
| GET | /student/{id}/next-question |
Next unanswered question at current difficulty |
| GET | /health |
Health check |
pip install pytest
pytest test.py -vAll 9 tests pass. ✅
| Layer | Choice |
|---|---|
| Framework | FastAPI |
| Database | SQLite via SQLAlchemy ORM |
| LLM | Groq (llama-3.3-70b-versatile) |
| PDF parsing | PyMuPDF (fitz) |
| Validation | Pydantic v2 |
| Server | Uvicorn |
Built with ❤️ by Lohith