A deterministic, 14-module AI pipeline that moves beyond simple keyword matching. AlgoRangers verifies skills natively via ontologies, enforces strict dependency graphs using Kahn's algorithm, and dynamically optimizes learning paths based on transfer learning and computed time-cost functions.
Traditional hiring platforms and "AI Resume Scanners" suffer from fundamental flaws: they rely on binary keyword extraction, ignore skill dependencies (e.g., suggesting React before JavaScript), and treat all missing skills equally.
AlgoRangers solves this by introducing mathematical rigor into talent assessment:
| Capability | The Industry Standard | The AlgoRangers Approach |
|---|---|---|
| Skill Detection | Simple Regex / Keyword Match | Context-aware ontological scanning with experience & project weightings. |
| Gap Analysis | "Missing 3 keywords" | Weighted gap magnitude: Importance Γ (Required - Actual Score). |
| Learning Path | Alphabetical checklists | Live Directed Acyclic Graph (DAG) generation utilizing topological sorts. |
| Confidence Scoring | "98% Match" | Multi-variable weighted readiness score penalized by detected exaggeration. |
We don't just ask if a skill exists; we calculate how well it's understood.
- Base Formula:
(Frequency Γ 0.4) + (Project Context Γ 0.35) + (Years Experience Γ 0.25) - Exaggeration Guard: If a candidate mentions a skill 5+ times but provides zero project context, the engine automatically triggers a massive confidence penalty to punish buzzword stuffing.
If the engine detects Java on a resume, but the job requires Node.js, the system automatically applies a Transfer Learning Boost. It acknowledges the shared paradigm, boosting the Node.js confidence threshold by 10% and reducing the required estimated learning time by 3 days.
Our backend runs Kahn's Algorithm to generate strict prerequisite chains. It computes the absolute fastest route to hire-readiness using a proprietary cost function:
Cost = Learning Time + (Difficulty Penalty) + (Dependency Depth Penalty) - (Transfer Reduction)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AlgoRangers AI Pipeline β
β β
β Input β
β ββββββββββββ ββββββββββββ β
β β Resume β β JD Text β β
β β PDF/TXT β β (string) β β
β ββββββ¬ββββββ ββββββ¬ββββββ β
β ββββββββ¬ββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 1: Extraction β β Word-boundary regex + ontology scan β
β β skill_ontology.py β 50+ skills, aliases: "reactjs"β"React" β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 2: Confidence β β confidence = freqΓ0.4 β
β β confidence_engine.py β + projectΓ0.35 β
β β β + experienceΓ0.25 β
β β β Exaggeration: Γ0.75 penalty β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 3: Transfer β β Java known β Node.js: +0.10 conf β
β β Learning Boost β -3 days learning time β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 4: Weighted β β score = Ξ£(importanceΓfinal_score) β
β β Readiness Score β / Ξ£(importance) Γ 100 β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 5: Gap Engine β β gap = importance Γ max(0, 0.8βscore) β
β β ai_engine.py β Sorted DESC by gap magnitude β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 6: DAG Engine β β Kahn's Algorithm: topological sort β
β β graph_engine.py β Auto-insert missing prerequisites β
β β β Cycle detection β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 7: Path β β cost(skill) = learning_time β
β β Optimizer β + max(0, diffβ3) Γ 2 β
β β path_optimizer.py β + dep_penalty β
β β β β transfer_reduction β
β β β Path A: high-importance only (fast) β
β β β Path B: all skills (deep) β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 8: Risk β β 5 checks: weak prereq, steep jump, β
β β risk_engine.py β missing prereq, low-conf hard skill, β
β β β skill overload β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 9: Reasoning β β Per-skill JSON trace: gap, importance, β
β β reasoning_engine.py β dependency, transfer, priority rank β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 10: System β β sys_conf = data_qualityΓ0.4 β
β β Confidence β + validationΓ0.4 β
β β risk_engine.py β + model_certaintyΓ0.2 β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββββββββ β
β β MODULE 11: Hiring β β Weighted score + exaggeration penalty β
β β Intelligence β HIRE / HIRE_WITH_TRAINING / TRAIN / β
β β β REJECT with explicit reasoning β
β βββββββββββββ¬ββββββββββββ β
β βΌ β
β JSON Output β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# confidence_engine.py
freq_score = min(mentions / 6.0, 1.0) # cap at 6 occurrences
project_score = 1.0 if project_context else 0.3
exp_score = min(years / 5.0, 1.0) if years > 0 else 0.2
confidence = (
0.40 * freq_score +
0.35 * project_score +
0.25 * exp_score
)
if exaggerated: # >5 mentions, no project context
confidence *= 0.75# ai_engine.py + skill_ontology.py
# If user knows Java β Node.js learning is cheaper and confidence is higher
TRANSFER_LEARNING_MAP = {
"Java": [("Node.js", 3, 0.10), ("Python", 2, 0.05)],
"Python": [("JavaScript", 2, 0.05), ("Node.js", 3, 0.10)],
"React": [("Vue", 4, 0.15), ("Angular", 3, 0.10)],
...
}
transfer_boost = sum(conf_boost for matching transfers) # capped at 0.25
final_score = min(1.0, raw_confidence + transfer_boost)# ai_engine.py β NOT a count ratio
score = (
Ξ£(importance_i Γ final_score_i)
βββββββββββββββββββββββββββββββ Γ 100
Ξ£(importance_i)
)# ai_engine.py
required_level = 0.80 # 80% proficiency expected
gap = importance Γ max(0, required_level - final_score)
# Sorted DESC β highest gap = first to learn# graph_engine.py
def topological_sort(dag):
in_degree = compute_in_degrees(dag)
queue = [n for n in dag if in_degree[n] == 0]
order = []
while queue:
node = queue.pop()
order.append(node)
for neighbor in adjacency[node]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.append(neighbor)
has_cycle = len(order) != len(all_nodes)
return order, has_cycle# path_optimizer.py
def cost(skill):
base = learning_time # days from ontology
diff_pen = max(0, difficulty - 3) * 2 # higher than level 3 β +2 days/level
dep_pen = 1 if auto_inserted else 0 # missing prereq overhead
transfer = time_reduction from transfer map
return base + diff_pen + dep_pen - transfer # minimized by path optimizer# risk_engine.py
data_quality = min(resume_skill_count / 10.0, 1.0)
validation_str = avg_confidence_score
model_certainty = min(jd_skill_count / 5.0, 1.0)
system_confidence = (
0.40 * data_quality +
0.40 * validation_str +
0.20 * model_certainty
)"React": {
"importance": 0.95, # 0-1: role criticality
"difficulty": 3, # 1-5: learning complexity
"learning_time": 14, # days to reach proficiency
"dependencies": ["JavaScript"], # prerequisite skills (DAG edges)
"category": "Frontend",
"tags": ["ui", "component", "spa"]
}{
"skill": "React",
"importance": 0.95,
"required_level": 0.80,
"current_score": 0.32, # confidence + transfer_boost
"raw_confidence": 0.22,
"transfer_boost": 0.10, # from knowing JavaScript
"gap_magnitude": 0.456, # 0.95 Γ (0.80 - 0.32)
"action": "LEARN", # LEARN / REVISE / SKIP
"learning_time": 14,
"difficulty": 3
}{
"skill": "React",
"action": "LEARN",
"current_score": 0.32,
"gap_magnitude": 0.456,
"importance": 0.95,
"reasons": [
"Current proficiency (32%) is below required level (80%).",
"Explicitly required in Job Description (importance: 95%).",
"β οΈ Unmet prerequisites: JavaScript β auto-added to learning path.",
"Extremely high priority β core skill for this role."
],
"transfer_note": "Transfer learning from Python saves ~2 days."
}{
"type": "WEAK_PREREQUISITE",
"severity": "HIGH",
"skill": "React",
"detail": "Prerequisite 'JavaScript' is weak or missing before learning 'React'.",
"recommendation": "Learn 'JavaScript' first to avoid confusion."
}Content-Type: multipart/form-data
Body:
file (File) β Resume PDF or TXT
jd_text (string) β Job Description text
Response: Full 15-field output including all pipeline results
Content-Type: multipart/form-data
Body: same as /analyze
Response:
{
"skills": [...], // extracted resume skills
"verified_scores": [...], // per-skill gap objects
"skill_gap": [...], // skills where action = LEARN
"optimal_path": {...}, // Path A or B (lower cost)
"alternative_path": {...},
"time_estimate": "~42 days (6.0 weeks)",
"reasoning": [...], // structured trace per skill
"risk": [...], // risk warnings with severity
"system_confidence": {...}, // { score, flag, data_quality, ... }
"hiring_decision": "HIRE_WITH_TRAINING"
}
Body: {
"jd_skills": ["React", "Python", "Docker"],
"resume_skills": ["Python", "Django"],
"verified_scores": {"Python": 0.6, "React": 0.2}
}
Response: {
"questions": [{
"skill": "Python",
"type": "scenario",
"question": "You're debugging a memory leak in a Python service...",
"follow_up": "How would you identify which objects are not being garbage collected?",
"keywords": ["gc", "tracemalloc", "weakref", "profiler"]
}],
"count": 4
}Body: {
"answer": "I would use tracemalloc to track allocations...",
"keywords": ["tracemalloc", "gc", "profiler"],
"time_taken_seconds": 45
}
Response: {
"score": 0.72,
"concepts_found": ["tracemalloc", "gc"],
"concepts_missed": ["profiler", "weakref"],
"needs_follow_up": false,
"speed_flag": false
}?jd_skills=React,Docker,Python&resume_skills=Python
Response: {
"roadmap": [...steps in cost-optimized order],
"total_days": 35,
"path_name": "Path A β Fast-Track",
"auto_inserted": ["JavaScript"]
}
# 1. Navigate to backend
cd AlgoRangers/backend
# 2. Create virtual environment
python -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # Linux/Mac
# 3. Install dependencies
pip install -r requirements.txt
# 4. Configure environment
cp .env.example .env # Set GEMINI_API_KEY if using AI fallback
# 5. Start server
uvicorn main:app --reload --port 8000
# Swagger UI: http://localhost:8000/docs# 1. Navigate to frontend
cd AlgoRangers/frontend
# 2. Install dependencies
npm install
# 3. Start dev server
npm run dev
# App: http://localhost:5173# Navigate to project folder
cd AlgoRangers
# Start all services
docker-compose up --build
# Services:
# - Frontend: http://localhost:5173
# - Backend API: http://localhost:8000cd AlgoRangers/backend
pip install -r requirements.txt
uvicorn main:app --reloadcd AlgoRangers/frontend
npm install
npm run devfastapi>=0.104.0
uvicorn>=0.24.0
python-multipart>=0.0.6
PyMuPDF>=1.23.0
python-dotenv>=1.0.0
1. Open http://localhost:5173
2. Paste this example Job Description:
"Looking for a senior engineer with React, Node.js, Docker, PostgreSQL,
REST API experience. System Design knowledge required."
3. Upload resume PDF (or use the demo mode)
4. Click "Analyze"
5. Dashboard shows:
β Weighted readiness score (not a count ratio)
β Skill gap with importance weights
β Learning path A (fast) vs B (deep) with cost comparison
β Risk warnings (e.g. missing JavaScript before React)
β Per-skill reasoning traces
6. Click "Start Skill Validation"
β 4 open-ended questions targeting YOUR claimed skills
β 90-second timer per question
β Follow-up questions on weak answers
β Results: Validated / Needs Revision / Added to Gap
7. Click "Update Dashboard"
β Skill gap updates with quiz-confirmed weaknesses
| Edge Case | Detection | Handling |
|---|---|---|
| Resume exaggeration | Mentions > 5, no project context | Confidence Γ 0.75; hiring score β3pts/skill |
| Skill mentioned but no depth | No years, no project context | exp_score = 0.2 (minimum), confidence stays low |
| Missing prerequisites | DAG dependency not in resume | Auto-inserted into learning path, RISK flagged |
| Multiple valid paths | Both Path A and B generated | Cost comparison, lower-cost path recommended |
| No course available | Not in question bank | Falls back to Google search link for project-based learning |
| Outdated skill | Not in SKILL_ONTOLOGY | Treated as unknown, not penalized |
| Gaming the quiz | Answer submitted < 5 seconds | Speed flag raised, score multiplied by 0.7 |
| Low confidence prediction | system_confidence < 0.6 |
flag: "low_confidence" warning surfaced in output |
| Circular dependencies | Kahn's algorithm detects cycle | has_cycle = True, path generated with cycle-broken order |
| Empty resume | No text extracted from PDF | Demo mode activated with sample developer profile |
| Single-skill JD | JD has only 1 skill | Path optimizer returns single-step path, no A/B needed |
- Weighted, not binary β a skill at 25% and 90% proficiency are NOT treated the same
- Dependency-aware β never recommends learning React before JavaScript
- Transfer-aware β knowing Java gives you a headstart on Node.js (quantified: 3 days saved)
- Deterministic β same input always produces same output, fully reproducible
- Explainable β every decision has a JSON reasoning trace, not "AI said so"
- No hallucination β all skills, dependencies, and metadata grounded in ontology
- Cost-optimized β path chosen by minimizing
Ξ£ cost(skill), not alphabetical or random - Risk-aware β detects steep learning jumps and weak prerequisites before you waste time
- Adaptive β transfer learning reduces time estimates for related skills you already have
- DAG-first β dependency graph built before any recommendations are made
- Two-pass scoring β confidence calculated first, then transfer boost applied on top
- Hiring decision uses effective_score β after exaggeration penalty, not raw confidence
- Quiz targets matched skills β validates what you claim to know, not what you don't (yet)
Built for AlgoRangers Hackathon β Production-grade implementation, not a demo.