fablefrost/Project2-Quizzie
0
π Overview
Quizzie is an AI-powered autonomous quiz-solving agent built for the Tools in Data Science β Project 2 of the IITM BS Degree Programme.
The system uses a LangGraph state machine, LLMs (GPT/Gemini), and Playwright headless browser to:
- Fetch quiz pages (HTML, screenshots, console logs from JS-rendered content)
- Reason using an AI agent that decides which tools to use
- Execute Python code, JavaScript on pages, download files, analyze with vision/audio LLMs
- Submit answers and handle feedback (retry on wrong, proceed on correct)
- Iterate through the entire quiz chain until completion
βββββββββββββββ βββββββββββββββββββ βββββββββββββββββ
β fetch_contextββββββΆβ agent_reasoning ββββββΆβ execute_tools β
βββββββββββββββ ββββββββββ¬βββββββββ βββββββββββββββββ
β
ββββββββββΌβββββββββ
β submit_answer β
ββββββββββ¬βββββββββ
β
ββββββββββΌβββββββββ ββββββββββββββββ
βprocess_feedback ββββββΆβ next quiz/ENDβ
βββββββββββββββββββ βββββββββββββββββ¨ Features & Capabilities
π€ AI Agent Tools
π Supported Task Types
Based on project.md requirements, the system handles:
π‘οΈ Robustness Features
- 3-minute timeout per quiz with automatic skip to next
- Unlimited retries within timeout window
- 10 max attempts before moving on
- Exponential backoff on LLM errors (up to 10 retries)
- Round-robin API key rotation for Gemini (up to 3 keys)
- File-based caching with TTL for pages and downloads
- Graceful error handling - agent never crashes
- Token limit protection - skips quiz if messages exceed 25000 tokens
π Quick Start
Prerequisites
- Python 3.11+ (recommended via uv)
- Docker (optional, for deployment)
- Playwright browsers (auto-installed on first run)
1οΈβ£ Clone & Install
git clone https://github.com/23f3002872/Quizzie
cd Quizzie
uv sync # or: pip install -e .
playwright install chromium2οΈβ£ Configure Environment
Create .env file:
# Required
SECRET_KEY=your-secret-key
STUDENT_EMAIL=your-email@ds.study.iitm.ac.in
# LLM Configuration (Primary reasoning model)
LLM_API_KEY=your-openai-api-key
LLM_BASE_URL=https://api.openai.com/v1
LLM_PROVIDER=openai # or google
# Gemini Keys (for file analysis - round-robin rotation)
GEMINI_API_KEY_1=your-gemini-key-1
GEMINI_API_KEY_2=your-gemini-key-2
GEMINI_API_KEY_3=your-gemini-key-3
# Server
HOST=0.0.0.0
PORT=8000
DEBUG=false3οΈβ£ Run
uv run uvicorn main:app --host 0.0.0.0 --port 8000
# or
python main.py4οΈβ£ Test
# Health check
curl http://localhost:8000/health
# Submit a quiz (runs in background)
curl -X POST http://localhost:8000/solve \
-H "Content-Type: application/json" \
-d '{"email":"your-email","secret":"your-secret","url":"https://quiz-url"}'π³ Docker Deployment
# Build
docker build -t Quizzie .
# Run
docker run -p 8000:8000 \
-e SECRET_KEY=xxx \
-e STUDENT_EMAIL=xxx \
-e LLM_API_KEY=xxx \
-e GEMINI_API_KEY_1=xxx \
QuizzieHuggingFace Spaces
- Create new Space with Docker SDK
- Push this repository
- Add secrets in Space settings
- Access via
https://your-space.hf.space/
π² Project Structure
Quizzie/
βββ main.py # FastAPI entry point
βββ app/
β βββ config/
β β βββ settings.py # Pydantic settings from env
β βββ graph/
β β βββ graph.py # LangGraph workflow definition
β β βββ state.py # QuizState TypedDict
β β βββ resources.py # GlobalResources (browser, llm)
β βββ nodes/
β β βββ fetch.py # Fetch page content node
β β βββ agent.py # AI reasoning node
β β βββ tools.py # Tool execution node
β β βββ submit.py # Answer submission node
β β βββ feedback.py # Process server response node
β βββ tools/
β β βββ python.py # Python execution sandbox
β β βββ javascript.py # Browser JS execution
β β βββ download.py # File downloader with cache
β β βββ call_llm.py # Gemini multimodal analysis
β β βββ submit_answer.py # HTTP POST submission
β βββ resources/
β β βββ llm.py # Multi-provider LLM client
β β βββ browser.py # Playwright browser wrapper
β β βββ api.py # HTTP client utilities
β βββ utils/
β βββ logging.py # Structured logger
β βββ cache.py # File-based caching
β βββ helpers.py # Temp file management
β βββ gemini.py # Gemini API utilities
βββ tests/ # Pytest test suite
βββ Dockerfile # Production container
βββ pyproject.toml # Dependencies & scriptsπ API Reference
GET / or GET /health
Health check endpoint.
{"status": "ok", "message": "Quiz Solver is running"}POST /solve
Start quiz solving (runs in background).
Request:
{
"email": "student@example.com",
"secret": "your-secret-key",
"url": "https://example.com/solve/1"
}Response:
200- Quiz solving started400- Invalid JSON payload403- Invalid secret or email
βοΈ Configuration
π§ͺ Testing
uv run pytest -vTest coverage includes:
- API endpoint validation
- Browser initialization
- LLM response mocking
π TODO: Future Improvements
Note: The project statement (project-llm-analysis-quiz.md) itself contains TODOs and states "THIS PROJECT IS WORK IN PROGRESS. SOME DETAILS MAY CHANGE." Below are improvements that could be made with more time.π΄ High Priority
- [ ] Gemini Function Calling - Currently it is experiencing Malformed Function Call errors
- [ ] Dynamic Model Selection - Allow choosing different LLMs per quiz
- [ ] Advanced Error Handling - More granular error categories and recovery
π‘ Medium Priority
- [ ] Parallel Quiz Handling - Process current and next URL simultaneously on wrong answers
- [ ] Better Visualization Support - Generate charts as images or interactive formats
- [ ] Geo-spatial Analysis - Improve GeoJSON/KML processing capabilities
- [ ] Network Analysis - Better graph/network data handling
π’ Nice to Have
- [ ] Comprehensive Test Suite - Add more unit tests
- [ ] Performance Metrics - Track success rates per question type
- [ ] Caching Optimization - Smarter cache invalidation
- [ ] Enhanced Logging - More granular logs for debugging
- [ ] User Interface - Simple web UI for monitoring quiz progress
- [ ] More Test Cases - Cover edge cases in quiz solving
π Project Notes
What the Project Requires (from project-llm-analysis-quiz.md)
- API Endpoint that:
- Accepts POST with
{email, secret, url} - Returns HTTP 200 for valid requests, 400 for invalid JSON, 403 for invalid secrets
- Solves quiz within 3 minutes of receiving the request
- Quiz Solving capabilities for:
- Web scraping (JS-rendered pages)
- API sourcing (with provided headers)
- Data cleansing (text/PDF/etc.)
- Data processing (transformation, transcription, vision)
- Analysis (filtering, sorting, aggregating, ML models, geo-spatial, network)
- Visualization (charts as images, narratives, slides)
- Answer Submission:
- POST to URL specified on quiz page (never hardcoded)
- Payload:
{email, secret, url, answer}under 1MB - Answer can be: boolean, number, string, base64 URI, or JSON object
- Prompt Testing (separate evaluation):
- System prompt (max 100 chars) to resist revealing a code word
- User prompt (max 100 chars) to extract code words from other system prompts
β οΈ Unclear Aspects in Project Statement
The official project statement has these unresolved items:
- "THIS PROJECT IS WORK IN PROGRESS" - Requirements may change
- Scoring weights - "will be finalized later"
- Model selection - "Which models will prompts be tested on?" marked as TODO
- Test pairing - "How many other prompts will each prompt be tested against?" marked as TODO
- Viva format - Only says "voice viva with LLM evaluator" without details
- 3 minute timer - Unclear if for a single question or entire quiz
π‘ Design Decisions Made
Given the ambiguity, this implementation:
- Uses LangGraph for flexible workflow management
- Implements multiple LLM providers (OpenAI, Google) for redundancy
- Has aggressive retry logic (10 attempts, 3-min timeout per quiz)
- Uses Gemini for multimodal (vision, audio, PDF) analysis
- Maintains persistent Python sessions for stateful computations
- Caches page content to avoid redundant fetches
Test endpoint provided: https://tds-llm-analysis.s-anand.net/demo
π License
MIT License - see LICENSE file.
π Contact
` Khushi Choudhary
- Email: 23f3002872@ds.study.iitm.ac.in
- GitHub: @23f3002872
