A full-stack web application that generates personalized interview questions for IT specialists using a modular RAG (Retrieval-Augmented Generation) pipeline. The system retrieves questions from a PDF-based knowledge base and optionally generates additional questions using Google's Gemini AI.
- RAG-based Question Retrieval: Primary source of questions from PDF files organized by specialization
- AI-powered Difficulty Classification: Automatically classifies question difficulty (easy/medium/hard) using Gemini
- Experience-based Distribution: Probabilistic selection of questions based on candidate experience level
- Junior: 60% easy, 30% medium, 10% hard
- Middle: 30% easy, 50% medium, 20% hard
- Senior: 10% easy, 30% medium, 60% hard
- CV Analysis: Optional CV upload (PDF, DOCX, TXT) for personalized question generation
- Specialization Filtering: Supports backend, frontend, DevOps, ML, mobile, data engineering, QA, and other specializations
- Optional LLM Generation: Can generate additional questions via Gemini based on CV and context
- Automated Benchmarking: Evaluates RAG pipeline performance with real CVs
- LIME Explainer: Explains why specific documents were retrieved with high scores using Local Interpretable Model-agnostic Explanations
LIME explains why a specific document was ranked for a query.
- Endpoint:
POST /api/interview/explain-retrieval - Runtime code:
backend/app/services/lime_retrieval.py - Minimal notes:
backend/LIME_notes.md - Request/response guide:
backend/LIME_api.md
Location: backend/
Main Entry: app.main:app
Key Services:
services/ingestion.py: CV upload and text extraction from PDF, DOCX, TXTservices/embeddings.py: HuggingFace SentenceTransformer embeddings (all-MiniLM-L6-v2, 384 dimensions)services/vectorstores.py: ChromaDB vector store implementationservices/retrieval.py: RAG retrieval service with similarity searchservices/reranking.py: Heuristic reranking of retrieved resultsservices/prompting.py: Prompt construction for CV understanding and question generationservices/pipeline.py: End-to-end interview question generation pipeline- RAG retrieval from PDF question bank
- Difficulty classification via Gemini
- Probabilistic question selection
- Optional LLM-based question generation
services/memory.py: In-memory CV storage and response cachingservices/benchmarking.py: Automated RAG evaluation with metricsservices/gemini_client.py: Gemini API client with retry logic for rate limitsservices/qa_corpus.py: Loads questions from PDF files indata/questions/services/pdf_question_parser.py: Extracts Q&A pairs from structured PDF documents
API Endpoints:
POST /api/interview/upload-cv: Upload and process CV filePOST /api/interview/generate: Generate interview questionsGET /api/interview/specializations: List available specializationsPOST /api/interview/explain-retrieval: Explain retrieval score using LIME (new)POST /api/benchmarking/run: Run automated benchmark evaluationGET /api/health: Health check
Location: frontend/
Tech Stack: Vite + React + TypeScript
Features:
- CV upload interface (optional)
- Specialization and experience level selection
- Prompt mode selection (CV-focused, specialization-focused, mixed)
- Optional custom parameters (tech stack, company profile, job description)
- Question display with difficulty tags
- Export questions to PDF
- Optional LLM generation toggle
- Python 3.11+
- Node.js 18+
- Docker and Docker Compose (for containerized deployment)
- Google Gemini API key (Get one here)
cd backend
pip install --upgrade pip
pip install .
export GEMINI_API_KEY="YOUR_KEY_HERE" # Windows: set GEMINI_API_KEY=...
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000Backend will be available at http://localhost:8000
cd frontend
npm install
npm run devFrontend will be available at http://localhost:3000
The dev server proxies /api requests to http://localhost:8000.
- Create a
.envfile in the project root:
GEMINI_API_KEY=your_gemini_api_key_here
CORS_ALLOW_ORIGINS=["http://localhost:3000","http://127.0.0.1:3000"]- Build and run:
docker-compose up --build- Backend API:
http://localhost:8000/api - Frontend:
http://localhost:3000 - API Docs:
http://localhost:8000/api/docs
Place PDF files containing interview questions in data/questions/ directory. Files should be named by specialization (e.g., backend.pdf, ml.pdf, qa.pdf).
Expected PDF Format:
- Questions marked with "Q:", "Question:", or numbered (1., 2., etc.)
- Answers marked with "A:", "Answer:", "Ideal Answer:", etc.
- Optional category and difficulty markers
The system automatically:
- Parses Q&A pairs from all PDF files
- Generates embeddings using HuggingFace model
- Stores them in ChromaDB vector store
- Filters by specialization based on source file name
An optional questions.csv file can be placed in data/questions/ for LLM generation reference. This file is not used for RAG retrieval, only as a style reference when generating additional questions via LLM.
CSV Format:
Question,Answer,Category,Difficulty
"What is...?","Answer text...","Category","easy"-
Question Retrieval (RAG):
- User selects specialization and experience level
- System retrieves relevant questions from PDF-based vector store
- Questions are filtered by specialization (using source file names and categories)
-
Difficulty Classification:
- Retrieved questions are sent to Gemini for difficulty classification
- Each question is classified as easy, medium, or hard
-
Question Selection:
- Questions are selected probabilistically based on experience level
- System ensures exactly the requested number of questions
-
Optional LLM Generation:
- If
generate_with_llmis enabled, additional questions are generated via Gemini - LLM uses CV summary, retrieved questions, and custom context as references
- If
-
Response:
- Returns list of questions with difficulty, category, ideal answers, and explanations
To make the application accessible to others over the internet, see PUBLIC_ACCESS.md for detailed instructions.
Quick start with Tuna (recommended):
- Sign up at https://tuna.am/
- Install Tuna CLI:
tuna auth(follow instructions) - Start your application:
docker-compose upor run locally - Start tunnels:
- Windows:
.\start-tuna.ps1 - Linux/Mac:
chmod +x start-tuna.sh && ./start-tuna.sh
- Windows:
- Copy the Tuna URLs and add them to
CORS_ALLOW_ORIGINSin.env - Restart backend:
docker-compose restart backend(or restart local server)
Alternative: ngrok:
- Install ngrok
- Create
.envfile with your Gemini API key - Run
docker-compose up - In a new terminal:
ngrok http 3000 - Add the ngrok HTTPS URL to
CORS_ALLOW_ORIGINSin.env - Restart backend:
docker-compose restart backend
GEMINI_API_KEY(required): Your Google Gemini API keyCORS_ALLOW_ORIGINS: JSON array of allowed origins for CORS- Example:
["http://localhost:3000","http://127.0.0.1:3000","https://your-domain.com"] - Use
["*"]to allow all origins (not recommended for production)
- Example:
Default models (configurable in backend/app/core/config.py):
- Embeddings:
all-MiniLM-L6-v2(HuggingFace, 384 dimensions) - Question Generation:
gemini-2.5-pro - CV Understanding & Classification:
gemini-2.5-flash
.
├── backend/
│ ├── app/
│ │ ├── core/ # Configuration and logging
│ │ ├── models/ # Pydantic schemas
│ │ ├── routes/ # API endpoints
│ │ └── services/ # Business logic
│ ├── data/
│ │ ├── questions/ # PDF question files
│ │ └── basic_cv/ # CV files for benchmarking
│ └── pyproject.toml # Python dependencies
├── frontend/
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── services/ # API client
│ │ └── App.tsx # Main app component
│ └── nginx.conf # Nginx configuration
├── docker-compose.yml # Docker orchestration
└── README.md # This file
This project is provided as-is for educational and demonstration purposes.