A resume ranking application that uses AI agents to parse and score resumes against job requirements.
- Resume Parsing: Upload PDF/DOCX resumes and extract structured data (skills, experience, summary)
- Job Matching: Define job descriptions with required and preferred skills
- AI-Powered Ranking: Score and rank candidates based on job requirements using LLM
- Web Interface: User-friendly Razor Pages frontend for managing jobs and resumes
- AWS Integration: Deploy agents to AWS Lambda with S3 storage and API Gateway
Job detail page showing the job title, description, required and preferred skills, and the list of resumes uploaded for that job. You can upload PDF/DOCX files and run AI-powered ranking from here.
AI-generated ranking of candidates for the selected job. Each resume is scored and ordered by fit, with a short rationale. Use this view to compare candidates and decide who to interview.
The application consists of three components:
| Component | Technology | Port | Description |
|---|---|---|---|
| Web App | .NET 8 ASP.NET Core | 5016 | Razor Pages frontend |
| Resume Parser Agent | Python FastAPI | 5100 | Extracts structured data from resumes |
| Ranking Agent | Python FastAPI | 5101 | Scores resumes against job criteria |
┌─────────────────────────────────────────────────────────────────┐
│ Browser │
└─────────────────────────────┬───────────────────────────────────┘
│ HTTP
▼
┌─────────────────────────────────────────────────────────────────┐
│ .NET Web Application │
│ (ASP.NET Core - Port 5016) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ Razor Pages │ │ Services │ │ SQLite Database │ │
│ └─────────────┘ └──────┬──────┘ └─────────────────────────┘ │
└──────────────────────────┼──────────────────────────────────────┘
│ HTTP
┌────────────┴────────────┐
▼ ▼
┌───────────────────────┐ ┌───────────────────────┐
│ Resume Parser Agent │ │ Ranking Agent │
│ (FastAPI - Port 5100)│ │ (FastAPI - Port 5101)│
│ ┌─────────────────┐ │ │ ┌─────────────────┐ │
│ │ PDF/DOCX Parser │ │ │ │ LLM Service │ │
│ └─────────────────┘ │ │ └─────────────────┘ │
└───────────────────────┘ └───────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Browser │
└─────────────────────────────┬───────────────────────────────────┘
│ HTTP
▼
┌─────────────────────────────────────────────────────────────────┐
│ .NET Web Application (Local) │
│ (ASP.NET Core - Port 5016) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ Razor Pages │ │ Services │ │ SQLite Database │ │
│ └─────────────┘ └──────┬──────┘ └─────────────────────────┘ │
└──────────────────────────┼──────────────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────────────────────────┐
│ AWS API Gateway │
│ POST /parse POST /rank │
└─────────────┬───────────────────────────────┬───────────────────┘
│ │
▼ ▼
┌───────────────────────┐ ┌───────────────────────┐
│ Resume Parser Lambda │ │ Ranking Lambda │
│ ┌─────────────────┐ │ │ ┌─────────────────┐ │
│ │ PDF/DOCX Parser │ │ │ │ AWS Bedrock │ │
│ │ + AWS Bedrock │ │ │ │ (Claude) │ │
│ └────────┬────────┘ │ │ └─────────────────┘ │
└───────────┼───────────┘ └───────────────────────┘
│
▼
┌───────────────────────┐
│ S3 Bucket │
│ (Resume Storage) │
└───────────────────────┘
- .NET 8 SDK
- Python 3.10+
- LLM API Key (Anthropic for local mode)
- AWS CLI configured with appropriate credentials
- Terraform >= 1.0
- AWS Bedrock Claude model access enabled in your AWS account
git clone https://github.com/skizha/ResumeRank.git
cd ResumeRankpip install -r src/agents/requirements.txtSet your LLM API key (for local mode):
# Windows
set ANTHROPIC_API_KEY=your-api-key-here
# Linux/Mac
export ANTHROPIC_API_KEY=your-api-key-heredotnet buildYou need to run all three components:
cd src/agents
python -m uvicorn resume_parser.main:app --port 5100cd src/agents
python -m uvicorn ranking_agent.main:app --port 5101dotnet run --project src/ResumeRank.WebOpen http://localhost:5016 in your browser.
# Package and deploy
.\scripts\deploy-aws.ps1
# Or with custom options
.\scripts\deploy-aws.ps1 -Environment prod -Region us-west-2 -AutoApproveUpdate src/ResumeRank.Web/appsettings.json or create appsettings.Production.json:
{
"AgentMode": "AWS",
"AWS": {
"Region": "us-east-1",
"ApiGatewayUrl": "https://YOUR_API_ID.execute-api.us-east-1.amazonaws.com/dev",
"S3BucketName": "resumerank-resumes-dev-YOUR_ACCOUNT_ID"
}
}The deployment script will output the correct values for ApiGatewayUrl and S3BucketName.
# Using environment variable
set AgentMode=AWS
dotnet run --project src/ResumeRank.Web
# Or use Production environment
dotnet run --project src/ResumeRank.Web --environment Production.\scripts\destroy-aws.ps1
# Force destroy including S3 contents
.\scripts\destroy-aws.ps1 -Force -AutoApproveThe application supports two modes configured via AgentMode in appsettings:
| Mode | Description | File Storage | Agent Endpoints |
|---|---|---|---|
Local (default) |
Local development | Local filesystem | FastAPI on localhost |
AWS |
Cloud deployment | Amazon S3 | API Gateway + Lambda |
{
"AgentMode": "Local",
"AgentServices": {
"ResumeParserUrl": "http://localhost:5100",
"RankingAgentUrl": "http://localhost:5101"
},
"FileStorage": {
"UploadPath": "uploads"
}
}{
"AgentMode": "AWS",
"AWS": {
"Region": "us-east-1",
"ApiGatewayUrl": "https://xxx.execute-api.us-east-1.amazonaws.com/dev",
"S3BucketName": "resumerank-resumes-dev-123456789012"
}
}ResumeRankV1/
├── infrastructure/ # Terraform AWS configs
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ ├── s3.tf
│ ├── lambda.tf
│ ├── api_gateway.tf
│ └── iam.tf
├── scripts/ # Deployment scripts
│ ├── deploy-aws.ps1
│ ├── destroy-aws.ps1
│ └── package-lambda.ps1
├── src/
│ ├── ResumeRank.Web/ # .NET 8 ASP.NET Core Razor Pages
│ │ ├── Pages/ # Razor Pages
│ │ ├── Models/ # Data models
│ │ ├── Services/ # Business logic and HTTP clients
│ │ └── Data/ # EF Core DbContext
│ └── agents/
│ ├── resume_parser/ # Local FastAPI resume parser
│ ├── ranking_agent/ # Local FastAPI ranking agent
│ ├── shared/ # Shared configuration
│ └── aws_lambda/ # AWS Lambda handlers
│ ├── resume_parser/ # Lambda resume parser
│ ├── ranking_agent/ # Lambda ranking agent
│ └── shared/ # Shared AWS utilities
├── tests/
│ ├── ResumeRank.Web.Tests/ # xUnit tests
│ └── agents/ # pytest tests
└── ResumeRank.sln # .NET solution file
| Method | Endpoint | Description |
|---|---|---|
| POST | /parse |
Parse a resume file |
| GET | /health |
Health check |
| Method | Endpoint | Description |
|---|---|---|
| POST | /rank |
Rank resumes against a job |
| GET | /health |
Health check |
dotnet testpytest tests/agents/ -v# Test parser directly
aws lambda invoke --function-name resumerank-parser-dev \
--payload '{"file_path":"resumes/job-1/test.pdf"}' response.json
# Test ranking directly
aws lambda invoke --function-name resumerank-ranking-dev \
--payload '{"resumes":[...],"job":{...}}' response.json
# Test via API Gateway
curl -X POST https://xxx.execute-api.us-east-1.amazonaws.com/dev/parse \
-H "Content-Type: application/json" \
-d '{"file_path":"resumes/job-1/test.pdf"}'| Service | Purpose |
|---|---|
| S3 | Store uploaded resume files (PDF/DOCX) |
| Lambda | Resume Parser and Ranking Agent functions |
| API Gateway | REST API endpoints for Lambda invocation |
| Bedrock | Claude LLM for AI processing |
| IAM | Roles and policies for service access |
| CloudWatch | Logging and monitoring |
MIT

