A production-ready FastAPI backend for an AI-powered interview and skill assessment system. Supports Google Gemini (primary) and Hugging Face LLaMA (fallback) — no OpenAI dependency.
| Feature | Description |
|---|---|
| Skill Extraction | Extracts skills from Job Description + Resume using LLM |
| Skill Matching | Deterministic 5-layer matching: exact → synonym → sub-skill hierarchy → inferred → contextual |
| Adaptive Interview | Generates difficulty-adjusted questions (easy/medium/hard) |
| Answer Evaluation | Structured scoring across 4 dimensions with model answers |
| Gap Analysis | Priority-based skill gap categorization (HIGH/MEDIUM/LOW) |
| Learning Plans | Week-by-week personalized roadmaps with resources |
┌─────────────────────────────────────────────────────────────────┐
│ FastAPI App │
├─────────────────────────────────────────────────────────────────┤
│ Routes │
│ ├── POST /analyze → Skill extraction + matching │
│ ├── POST /generate-questions → Adaptive question gen │
│ ├── POST /evaluate → Answer scoring │
│ ├── POST /gap-analysis → Skill gap categorization │
│ └── POST /learning-plan → Learning roadmap │
├─────────────────────────────────────────────────────────────────┤
│ Services │
│ ├── skill_extractor.py → LLM-based extraction │
│ ├── skill_matcher.py → Deterministic 5-layer matching │
│ ├── skill_mappings.py → Synonym, hierarchy & semantic │
│ ├── proficiency_engine.py → Evidence-based proficiency │
│ ├── question_generator.py → Difficulty-adaptive questions │
│ ├── evaluator.py → Structured scoring │
│ ├── gap_analysis.py → Priority categorization │
│ └── learning_plan.py → Roadmap generation │
├─────────────────────────────────────────────────────────────────┤
│ Utils │
│ ├── llm_client.py → Gemini / HF API client │
│ ├── json_parser.py → Robust JSON extraction │
│ ├── prompts.py → Centralized prompt templates │
│ └── validators.py → Validation helpers │
├─────────────────────────────────────────────────────────────────┤
│ Models │
│ └── schemas.py → Pydantic request/response │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────┐ ┌──────────────────────┐
│ Google Gemini API │ │ Hugging Face API │
│ (primary) │ │ (fallback) │
└─────────────────────┘ └──────────────────────┘
📖 See logic.md for a detailed breakdown of data flow and matching logic.
# Create virtual environment
python -m venv venv
# Activate (Windows)
venv\Scripts\activate
# Activate (macOS/Linux)
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt- Go to huggingface.co/settings/tokens
- Create a new token with Read access
- For gated models (like LLaMA 3), accept the model's license agreement on its model page
- Create a
.envfile:
cp .env.example .envEdit .env:
HF_API_TOKEN=hf_your_actual_token_here
HF_MODEL_ID=meta-llama/Meta-Llama-3-8B-InstructRecommended models:
meta-llama/Meta-Llama-3-8B-Instruct— Best balance of quality and speedmistralai/Mixtral-8x7B-Instruct-v0.1— Strong alternativemeta-llama/Meta-Llama-3-70B-Instruct— Highest quality (slower)
# Development mode (with hot reload)
python main.py
# Or directly with uvicorn
uvicorn main:app --reload --host 0.0.0.0 --port 8000- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
{
"job_description": "We need a Python developer with FastAPI, Docker, and PostgreSQL experience...",
"resume": "Experienced software engineer with 5 years in Python, Flask, Docker..."
}Response:
{
"jd_skills": ["Python", "FastAPI", "Docker", "PostgreSQL"],
"resume_skills": ["Python", "Flask", "Docker", "MySQL"],
"matched_skills": [
{"skill": "Python", "found_in_resume": true, "proficiency_estimate": "advanced"},
{"skill": "Docker", "found_in_resume": true, "proficiency_estimate": "intermediate"},
{"skill": "FastAPI", "found_in_resume": false, "proficiency_estimate": "unknown"},
{"skill": "PostgreSQL", "found_in_resume": false, "proficiency_estimate": "unknown"}
],
"match_percentage": 50.0,
"missing_skills": ["FastAPI", "PostgreSQL"]
}{
"skill": "Python",
"difficulty": "medium",
"count": 3,
"context": "Backend development role"
}{
"question": "Explain Python's GIL and its impact on multithreading.",
"answer": "The GIL is a mutex that protects access to Python objects...",
"skill": "Python",
"difficulty": "medium"
}Response:
{
"skill": "Python",
"difficulty": "medium",
"evaluation": {
"conceptual_understanding": 8,
"practical_knowledge": 7,
"clarity": 9,
"confidence": 7,
"final_score": 7.7,
"feedback": "Strong conceptual grasp of GIL. Consider adding examples of when to use multiprocessing vs threading.",
"correct_answer": "The GIL (Global Interpreter Lock) is..."
},
"next_difficulty": "hard"
}{
"required_skills": ["Python", "FastAPI", "Docker", "PostgreSQL"],
"scores": {
"Python": 8.5,
"FastAPI": 3.0,
"Docker": 6.0,
"PostgreSQL": 4.5
}
}{
"skill_gaps": [
{"skill": "FastAPI", "score": 3.0, "priority": "HIGH", "is_required": true, "recommendation": "Focus on FastAPI fundamentals"},
{"skill": "PostgreSQL", "score": 4.5, "priority": "HIGH", "is_required": true, "recommendation": "Learn SQL and database design"}
],
"available_hours_per_day": 2.0,
"target_weeks": 8
}The system adjusts question difficulty based on evaluation scores:
Score > 7 → Next question: HARD
Score < 4 → Next question: EASY
Otherwise → Next question: MEDIUM
LLaMA models may not always produce valid JSON. This system uses a 4-layer defense:
- Prompt Engineering — Every prompt includes strict JSON instructions + examples
- JSON Extraction — Regex-based extraction from markdown fences, prose wrappers
- Auto-Fix — Trailing commas, quote normalization, control character removal
- Pydantic Validation — Schema enforcement with retry (up to 3 attempts)
project/
├── main.py # FastAPI app entry point
├── requirements.txt # Python dependencies
├── .env.example # Environment variable template
├── README.md # This file
├── logic.md # Data flow & matching logic docs
├── models/
│ └── schemas.py # Pydantic request/response schemas
├── routes/
│ ├── analyze.py # POST /analyze
│ ├── interview.py # POST /generate-questions
│ ├── evaluation.py # POST /evaluate, /gap-analysis
│ └── learning.py # POST /learning-plan
├── services/
│ ├── skill_extractor.py # LLM skill extraction
│ ├── skill_matcher.py # Deterministic 5-layer matching
│ ├── skill_mappings.py # Synonym, hierarchy & semantic maps
│ ├── proficiency_engine.py # Evidence-based proficiency scoring
│ ├── question_generator.py # Interview question generation
│ ├── evaluator.py # Answer evaluation & scoring
│ ├── gap_analysis.py # Skill gap categorization
│ └── learning_plan.py # Learning roadmap generation
├── frontend/
│ ├── index.html # Main UI page
│ ├── script.js # Frontend logic
│ └── styles.css # Styles
└── utils/
├── llm_client.py # Gemini / HF Inference API client
├── json_parser.py # Robust JSON extraction
├── prompts.py # Centralized prompt templates
└── validators.py # Validation helpers
| Variable | Default | Description |
|---|---|---|
GEMINI_API_KEY |
— | Google Gemini API key (primary provider) |
GEMINI_MODEL_ID |
gemini-3-flash-preview |
Gemini model ID |
HF_API_TOKEN |
— | Hugging Face API token (fallback provider) |
HF_MODEL_ID |
meta-llama/Meta-Llama-3-8B-Instruct |
HF model ID |
HF_API_URL |
https://api-inference.huggingface.co/models |
HF API base URL |
HOST |
0.0.0.0 |
Server host |
PORT |
8000 |
Server port |
DEBUG |
true |
Enable debug mode + hot reload |
LLM_TIMEOUT |
120 |
API call timeout (seconds) |
LLM_MAX_RETRIES |
3 |
Max HTTP retry attempts |
LLM_MAX_NEW_TOKENS |
8192 |
Max tokens in LLM response |
LLM_TEMPERATURE |
0.3 |
LLM temperature (lower = more deterministic) |
- Logic & Data Flow — Detailed breakdown of matching algorithms.
- Deployment Guide — Steps for Render, Docker, and production.
- Contributing — How to add skills and run tests.
- Sample Input/Output — Examples of API requests and responses.
- Changelog — Project history.
MIT