๐ค A self-improving AI agent for processing resumes and evaluating job matches using OpenAI GPT
This project implements an intelligent agent designed to parse PDF resumes, extract structured information using OpenAI GPT, and evaluate how well candidates match job descriptions. Built for integration with the handit open-source platform for self-improving AI.
Goal: Parse a resume (PDF), extract structured info, and evaluate how well it matches a job description โ self-improving over time.
The agent consists of three main nodes working in sequence:
-
๐ง PDF Reader Tool (
pdf_reader_tool)- Type: Tool Node
- Function: Reads PDF files and extracts raw text
- Input: PDF file (path or buffer)
- Output: Raw text string with metadata
-
๐ง Resume Extractor LLM (
resume_extractor_llm)- Type: Model Node (structured-extraction)
- Function: Uses OpenAI GPT to extract structured data from resume text
- Input: Raw resume text
- Output: JSON with name, title, skills, education, experience, contact
-
๐ง Job Match Evaluator LLM (
job_match_evaluator_llm)- Type: Model Node (evaluation)
- Function: Uses OpenAI GPT to evaluate resume-job description match
- Input: Structured resume data + job description
- Output: Match score (0-100) with detailed breakdown and recommendations
- Node.js 18+
- npm or yarn
- OpenAI API Key (required for LLM nodes)
- Clone or download this project
- Install dependencies:
npm install- Set up environment variables:
# Copy the example environment file
cp env.example .env
# Edit .env and add your OpenAI API key
OPENAI_KEY=your_OPENAI_KEY_here# Run the demo (uses mock data if no PDF provided)
npm start
# Start the API server
npm run server
# Run in development mode with auto-reload
npm run devThe agent now provides HTTP endpoints for easy integration:
npm run server
# Server runs on http://localhost:3000POST /process-resume
Content-Type: multipart/form-data
# Upload PDF or text file
curl -X POST http://localhost:3000/process-resume \
-F "resume=@path/to/resume.pdf" \
-F "jobDescription=Looking for a React developer with 3+ years experience..."POST /process-resume-text
Content-Type: application/json
curl -X POST http://localhost:3000/process-resume-text \
-H "Content-Type: application/json" \
-d '{
"resumeText": "John Doe\nSoftware Engineer\nSkills: React, JavaScript, Python",
"jobDescription": "Looking for a React developer..."
}'GET /health
curl http://localhost:3000/healthGET /
curl http://localhost:3000/{
"success": true,
"data": {
"sessionId": "session_1699123456_abc123def",
"processing_time_ms": 2500,
"results": {
"extracted_resume": {
"name": "Sarah Chen",
"title": "Senior Frontend Developer",
"skills": ["React", "JavaScript", "TypeScript", "AWS"],
"education": "Bachelor of Science in Computer Science",
"contact": {
"email": "sarah.chen@email.com"
},
"extraction_method": "openai_gpt"
},
"job_match_evaluation": {
"score": 87,
"explanation": "Strong match with excellent technical skills alignment...",
"breakdown": {
"skills": 92,
"title": 85,
"education": 80,
"experience": 88
},
"strengths": ["Strong React experience", "Relevant education"],
"gaps": ["Limited AWS experience"],
"recommendations": ["Highlight cloud platform experience"],
"evaluation_method": "openai_gpt"
},
"confidence_score": 0.94,
"meets_threshold": true
}
}
}Create a .env file with the following variables:
# Required
OPENAI_KEY=your_OPENAI_KEY_here
# Optional
PORT=3000
NODE_ENV=development
MAX_TOKENS=2000
TEMPERATURE=0.3
CONFIDENCE_THRESHOLD=0.7// Process resume text
const response = await fetch('http://localhost:3000/process-resume-text', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
resumeText: resumeContent,
jobDescription: jobDescription
})
});
const result = await response.json();
console.log('Match Score:', result.data.results.job_match_evaluation.score);import requests
response = requests.post('http://localhost:3000/process-resume-text',
json={
'resumeText': resume_content,
'jobDescription': job_description
}
)
result = response.json()
print(f"Match Score: {result['data']['results']['job_match_evaluation']['score']}")# Run the test script
node examples/api_test.js
# Or test with your own resume
node examples/test_with_text_resume.js- Resume Extraction:
gpt-4o-mini(cost-effective for structured extraction) - Job Evaluation:
gpt-4o-mini(efficient for evaluation tasks)
If OpenAI API is unavailable or quota exceeded, the agent automatically falls back to rule-based processing to ensure reliability.
- Uses efficient
gpt-4o-minimodel - Configurable token limits
- Structured JSON output format
- Smart fallback to avoid failures
This agent is designed for seamless integration with the handit platform:
// Get agent info for handit registration
const agentInfo = agent.getAgentInfo();
console.log(agentInfo);Each node provides metadata for handit integration:
// Tool node info
const pdfReaderInfo = agent.pdfReader.getToolInfo();
// LLM node info
const extractorInfo = agent.resumeExtractor.getNodeInfo();
const evaluatorInfo = agent.jobMatchEvaluator.getNodeInfo();The agent tracks performance metrics for self-improvement:
// Get performance analytics
const analytics = agent.getPerformanceAnalytics();
console.log(analytics);
// Output: success_rate, avg_processing_time, avg_match_score, etc.Modify the skills extraction in src/nodes/resume_extractor_llm.js:
const skillKeywords = [
'javascript', 'python', 'java', 'react', 'node',
// Add your custom skills here
'your-custom-skill', 'another-skill'
];Adjust the scoring weights in src/nodes/job_match_evaluator_llm.js:
const totalScore = Math.round(
(scores.skills * 0.40) + // 40% weight on skills
(scores.title * 0.25) + // 25% weight on title
(scores.experience * 0.20) + // 20% weight on experience
(scores.education * 0.15) // 15% weight on education
);Change models and parameters in the node constructors:
// In resume_extractor_llm.js or job_match_evaluator_llm.js
this.model = 'gpt-4'; // Use more powerful model
this.maxTokens = 3000; // Increase token limit
this.temperature = 0.1; // Make output more deterministicresume-processing-agent/
โโโ src/
โ โโโ nodes/
โ โ โโโ pdf_reader_tool.js # PDF processing tool
โ โ โโโ resume_extractor_llm.js # OpenAI resume extraction
โ โ โโโ job_match_evaluator_llm.js # OpenAI job matching
โ โโโ agent.js # Main agent orchestrator
โ โโโ index.js # CLI entry point
โ โโโ server.js # HTTP API server
โโโ examples/ # Example files and tests
โโโ package.json # Dependencies and scripts
โโโ env.example # Environment variables template
โโโ README.md # This file
npm start # Run CLI demo
npm run server # Start HTTP API server
npm run dev # Start server with auto-reload
node examples/api_test.js # Test API endpoints# Add new dependencies
npm install new-package
# Update package.json
npm install-
OpenAI API Errors
- Check your API key is correctly set in
.env - Verify you have sufficient quota/credits
- Agent automatically falls back to rule-based processing
- Check your API key is correctly set in
-
PDF Parsing Errors
- Ensure PDF contains extractable text (not just images)
- Check file permissions and size limits (10MB max)
- Verify the PDF is not password-protected
-
Missing Dependencies
- Run
npm installto install all required packages - Check Node.js version (requires 18+)
- Run
-
Server Issues
- Check if port 3000 is available
- Verify environment variables are loaded
- Look for error messages in console output
- Check the console output for detailed error messages
- Test the
/healthendpoint to verify configuration - Review the performance analytics for insights
- Ensure all dependencies are properly installed
The agent includes built-in performance tracking:
- Success Rate: Percentage of successful processing attempts
- Processing Time: Average time to complete full pipeline
- Match Score: Average accuracy of job matching
- Session History: Detailed logs of recent processing sessions
- API Method Tracking: OpenAI vs fallback usage statistics
This data enables continuous improvement when integrated with handit's self-improvement capabilities.
- Support for multiple resume formats (DOCX, HTML, plain text)
- Advanced NLP models for better text extraction
- Real-time performance optimization based on feedback
- Integration with job boards APIs
- Batch processing capabilities
- Web UI for easier interaction
- Multi-language support
- Fine-tuned models for specific industries
MIT License - see LICENSE file for details
๐ Ready to process some resumes with AI?
- Set up your OpenAI API key
- Start the server:
npm run server - Test the API:
node examples/api_test.js - Integrate with your applications!