Skip to main content
DevProjects
IntermediateFinal YearMajorPlacementResumeMachine Learning & AI

AI Resume Screening & Skill Matching Engine

An end-to-end NLP pipeline parsing unstructured candidate resumes (PDF/DOCX), extracting technical skill entities, and computing cosine similarity against job descriptions with FastAPI.

Author: Ananya Verma (Senior AI/ML Researcher & Curriculum Lead)
Reviewed by Rohit Sharma
Updated: Sep 28, 2026

Problem Statement & Objectives

Modern corporate recruiting portals receive thousands of heterogeneous resumes per opening. Manual candidate screening causes severe evaluation delays, keyword-matching bias, and missed qualified candidates whose resumes use synonym terminology rather than literal exact strings.

Real-World Context:High-volume recruitment workflows at enterprise software companies, placement cells filtering candidates for specialized campus hiring drives, and automated job portal applicant pre-qualifiers.

Key Project Objectives:

  • •Build a robust file-parsing subsystem that reliably extracts plain text from varied PDF and DOCX document layouts.
  • •Implement an entity-extraction pipeline that isolates technical skills, years of experience, and degrees without relying on brittle regex alone.
  • •Vectorize candidate profiles and target job descriptions using dense text embeddings to evaluate conceptual semantic fit.
  • •Provide a high-throughput, asynchronous REST API delivering scored match rankings and missing skill gap insights.

System Architecture

The system follows a modular pipeline architecture. The Ingestion Layer ingests resumes via FastAPI multipart endpoints and extracts raw text via PyMuPDF. The NLP Engine cleans the text, tokenizes, removes stopwords, and performs custom spaCy NER to extract hard technical skills and qualifications. The Vector Matcher converts candidate text and job descriptions into high-dimensional vectors, calculating cosine similarity. Results are persisted to SQLite/PostgreSQL with candidate rank scores.

+-------------------------------------------------------------------------+
|                        CLIENT / RECRUITER UI                            |
+-------------------------------------------------------------------------+
                                     | (PDF/DOCX Upload + Job Spec)
                                     v
+-------------------------------------------------------------------------+
|                         FASTAPI INGESTION API                           |
|               (Async Multipart Validation & Queueing)                   |
+-------------------------------------------------------------------------+
                                     |
                                     v
+-------------------------------------------------------------------------+
|                        DOCUMENT EXTRACTION LAYER                        |
|           (PyMuPDF / pdfplumber Text & Structure Normalizer)            |
+-------------------------------------------------------------------------+
                                     |
                                     v
+-------------------------------------------------------------------------+
|                          NLP PROCESSING PIPELINE                        |
|   - spaCy Named Entity Recognition (Skill & Education Extraction)       |
|   - Tokenization & Lemmatization                                        |
|   - Sentence-Transformers / TF-IDF Vectorizer                           |
+-------------------------------------------------------------------------+
                                     |
                                     v
+-------------------------------------------------------------------------+
|                         MATCHING & SCORING ENGINE                       |
|   - Cosine Similarity Computation (Candidate Vector vs Job Vector)      |
|   - Skill Gap Penalty Matrix Calculation                                |
+-------------------------------------------------------------------------+
                                     |
                                     v
+-------------------------------------------------------------------------+
|                       PERSISTENCE & RANKING STORE                       |
|          (SQLite / PostgreSQL: Candidates, JobSpecs, MatchLogs)         |
+-------------------------------------------------------------------------+

Database Design (Relational (SQLite / PostgreSQL))

Stores candidates, structured extracted skill sets, posted job criteria, and scoring execution history.

Table: candidatesPK: id (UUID)

Master record of processed applicants.

idfull_nameemailphoneraw_textcreated_at
Table: job_descriptionsPK: id (UUID)

Target job criteria with required and optional skills.

idtitledepartmentraw_descriptionrequired_skillscreated_at
Table: match_resultsPK: id (UUID)

Computed compatibility scores between candidates and jobs.

idcandidate_idjob_idsimilarity_scorematched_skillsmissing_skillsevaluated_at

REST API Specifications

POST/api/v1/resumes/upload

Accepts multipart/form-data PDF resume and returns extracted text and candidate ID.

Response Payload:
{
  "candidate_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "status": "parsed",
  "detected_skills": ["Python", "FastAPI", "Docker", "PostgreSQL"]
}
POST/api/v1/jobs/match/{job_id}

Ranks uploaded candidates against the specified job description.

Response Payload:
{
  "job_id": "e3b0c442-98fc-1c14-9afb-4c8996fb9242",
  "rankings": [
    {
      "candidate_id": "9b1deb4d",
      "score": 88.5,
      "matched": ["Python", "FastAPI"],
      "missing": ["Kubernetes"]
    }
  ]
}

Step-by-Step Implementation Guide

Step 1: Document Parsing & Text Extraction Setup

Set up a virtual environment and configure PyMuPDF (fitz) to read raw streams from PDF uploads, handling multi-column reading order.

extractor.py
import fitz  # PyMuPDF

def extract_text_from_pdf(file_bytes: bytes) -> str:
    doc = fitz.open(stream=file_bytes, filetype="pdf")
    text_blocks = []
    for page in doc:
        text_blocks.append(page.get_text("text"))
    return "\n".join(text_blocks).strip()

Step 2: Skill Entity Matching with spaCy PhraseMatcher

Load an English spaCy model and initialize PhraseMatcher with pre-compiled technical terminology tokens to extract technology entities with zero false positives.

ner_pipeline.py
import spacy
from spacy.matcher import PhraseMatcher

nlp = spacy.load("en_core_web_sm")
matcher = PhraseMatcher(nlp.vocab, attr="LOWER")

TECH_SKILLS = ["Python", "FastAPI", "Docker", "PostgreSQL", "PyTorch", "React"]
patterns = [nlp.make_doc(skill) for skill in TECH_SKILLS]
matcher.add("TECH_SKILLS", patterns)

def extract_skills(text: str) -> list[str]:
    doc = nlp(text)
    matches = matcher(doc)
    return sorted(list({doc[start:end].text for _, start, end in matches}))

Step 3: Vector Similarity Engine & FastAPI Endpoint

Implement cosine similarity computation using scikit-learn's TfidfVectorizer or sentence-transformers, exposed through an asynchronous FastAPI route.

main.py
from fastapi import FastAPI, UploadFile, File
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

app = FastAPI(title="Resume Screening Engine")

@app.post("/api/v1/score")
async def calculate_score(resume_text: str, job_text: str):
    vectorizer = TfidfVectorizer(stop_words="english")
    tfidf_matrix = vectorizer.fit_transform([resume_text, job_text])
    similarity = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])[0][0]
    return {"match_score": round(float(similarity) * 100, 2)}

Placement Viva & Technical Questions

Questions commonly asked by college examiners and product company interviewers regarding this project architecture.

Keyword matching checks for exact string equality (e.g. searching for 'Node.js' misses 'NodeJS' or 'Express backend developer'). Semantic similarity converts words and sentences into high-dimensional vector embeddings, measuring conceptual proximity via cosine distance regardless of trivial spelling or phrasing variations.

Project FAQs

Yes. It combines applied NLP, data parsing, machine learning evaluation metrics, and asynchronous backend engineering, providing plenty of depth for viva examinations and live demonstrations.
Cross-Disciplinary Paths

Related Engineering Projects

View All Projects →
IntermediatePortfolio
TypeScript, JavaScript, Python

Real-Time Collaborative Code Editor & Runner

Browser-based collaborative IDE supporting multi-user concurrent code editing via Operational Transformation (CRDT / Yjs), real-time WebSockets, Monaco Editor, and containerized code execution.

Core Competencies
React & TypeScript Component State ManagementWebSocket Protocols & Socket.io Room PartitioningConflict-Free Replicated Data Types (CRDTs)+3 more
Full Architecture & APIs
View Guide
AdvancedFinal Year
Java, SQL

Cloud-Native Banking & Transaction Engine

Distributed FinTech backend implementing ACID-compliant fund transfers, idempotency keys, JWT role-based security, and event-driven audit logging with Spring Boot and PostgreSQL.

Core Competencies
Spring Boot 3 & Spring Data JPAACID Transaction Isolation & Pessimistic LockingIdempotency Key Patterns in Financial APIs+3 more
Full Architecture & APIs
View Guide