Resume Screening Assistant
Automatically screen resumes against job requirements with objective, structured analysis.
**Important:** This tool assists human recruiters - it does not make hiring decisions. Always have humans review and make final decisions. Monitor for potential bias and validate regularly.
Implementation
1import { relay } from "@relayplane/workflows";23const result = await relay4 .workflow("hiring-screen")56 // Step 1: Parse resume into structured data7 .step("parse-resume")8 .with("openai:gpt-4o")9 .prompt(`Extract structured data from this resume:1011{{resumeText}}1213Return JSON:14{15 "name": "...",16 "contact": { "email": "...", "phone": "...", "location": "..." },17 "summary": "2-3 sentence professional summary",18 "experience": [19 {20 "title": "...",21 "company": "...",22 "duration": "months as number",23 "responsibilities": ["..."],24 "achievements": ["..."]25 }26 ],27 "skills": {28 "technical": ["..."],29 "soft": ["..."],30 "certifications": ["..."]31 },32 "education": [33 {34 "degree": "...",35 "field": "...",36 "institution": "...",37 "year": "..."38 }39 ],40 "totalYearsExperience": number41}4243Extract exact information, don't infer.`)4445 // Step 2: Match against job requirements46 .step("match-requirements")47 .with("anthropic:claude-3.5-sonnet")48 .depends("parse-resume")49 .prompt(`Match candidate against job requirements:5051Parsed Resume: {{parse-resume.output}}5253Job Requirements:54{{jobRequirements}}5556For each requirement, assess:57- Meets: Yes/Partial/No58- Evidence: specific resume content supporting assessment59- Gap: what's missing (if any)6061Categories:62- Required Technical Skills63- Years of Experience64- Education65- Preferred/Nice-to-have Skills66- Industry Experience6768Be objective and evidence-based.`)6970 // Step 3: Score candidate71 .step("score-candidate")72 .with("openai:gpt-4o")73 .depends("parse-resume", "match-requirements")74 .prompt(`Calculate match score:7576Resume: {{parse-resume.output}}77Requirements Match: {{match-requirements.output}}7879Scoring weights:80- Required skills: 40%81- Experience level: 25%82- Industry relevance: 15%83- Education: 10%84- Nice-to-haves: 10%8586Return:87- Overall score (0-100)88- Breakdown by category89- Confidence level (high/medium/low)9091Thresholds:92- 80+: Strong match93- 60-79: Good match94- 40-59: Partial match95- Below 40: Not a match`)9697 // Step 4: Generate screening summary98 .step("screening-summary")99 .with("anthropic:claude-3.5-sonnet")100 .depends("parse-resume", "match-requirements", "score-candidate")101 .prompt(`Generate screening summary for recruiter:102103Candidate: {{parse-resume.output}}104Requirements: {{match-requirements.output}}105Score: {{score-candidate.output}}106107Format:108## Candidate Overview109- Name and current role110- Total experience111- Match score and recommendation112113## Strengths114- Top 3-5 reasons this candidate fits115- Specific achievements relevant to role116117## Concerns/Gaps118- Missing requirements119- Areas to probe in interview120121## Interview Questions122- 3-5 targeted questions based on gaps or verification needs123124## Recommendation125- ADVANCE / HOLD / PASS126- Brief justification127128Objective, professional tone.129Focus on job-relevant factors only.`)130131 .run({132 resumeText: candidateResume,133 jobRequirements: {134 title: "Senior Software Engineer",135 required: [136 "5+ years software development experience",137 "Proficient in TypeScript and React",138 "Experience with PostgreSQL or similar RDBMS",139 "Background in CI/CD and DevOps practices",140 ],141 preferred: [142 "Experience with AI/ML integration",143 "Open source contributions",144 "Previous startup experience",145 ],146 education: "Bachelor's in CS or equivalent experience",147 },148 });149150// Save to ATS151await updateATS({152 candidateId: candidate.id,153 screeningScore: JSON.parse(result.steps["score-candidate"].output).score,154 screeningSummary: result.steps["screening-summary"].output,155 status: result.steps["screening-summary"].output.includes("ADVANCE")156 ? "Phone Screen"157 : "Reviewed",158});Batch Resume Processing
1// Process application queue2import { relay } from "@relayplane/workflows";34async function processApplicationQueue(jobId: string) {5 const applications = await getNewApplications(jobId);6 const jobRequirements = await getJobRequirements(jobId);78 const results = [];910 for (const app of applications) {11 const screening = await relay12 .workflow("hiring-screen")13 .run({14 resumeText: app.resume,15 jobRequirements,16 });1718 const score = JSON.parse(screening.steps["score-candidate"].output);1920 results.push({21 candidateId: app.candidateId,22 score: score.score,23 recommendation: score.recommendation,24 summary: screening.steps["screening-summary"].output,25 });26 }2728 // Sort by score and return top candidates29 const ranked = results.sort((a, b) => b.score - a.score);3031 // Auto-advance top scorers32 const autoAdvance = ranked.filter(r => r.score >= 80);33 for (const candidate of autoAdvance) {34 await schedulePhoneScreen(candidate.candidateId);35 }3637 return ranked;38}ATS Webhook Integration
1// Greenhouse/Lever webhook handler2app.post("/webhooks/greenhouse", async (req, res) => {3 const { action, payload } = req.body;45 if (action === "candidate.applied") {6 const { candidate, application, job } = payload;78 // Queue for screening9 await queue.add("screen-resume", {10 candidateId: candidate.id,11 resumeUrl: application.resume.url,12 jobId: job.id,13 });14 }1516 res.sendStatus(200);17});1819// Queue processor20queue.process("screen-resume", async (job) => {21 const resume = await downloadResume(job.data.resumeUrl);22 const requirements = await getJobRequirements(job.data.jobId);2324 const result = await relay25 .workflow("hiring-screen")26 .run({27 resumeText: resume,28 jobRequirements: requirements,29 });3031 // Update Greenhouse32 await greenhouse.candidates.addNote(job.data.candidateId, {33 body: result.steps["screening-summary"].output,34 user_id: BOT_USER_ID,35 });36});Sample Output
1## Candidate Overview2**Sarah Chen** - Staff Software Engineer at DataCorp3**Experience:** 8 years in software development4**Match Score:** 87/100 (Strong Match)5**Recommendation:** ADVANCE to phone screen67## Strengths81. **Strong TypeScript/React experience** - 5 years building production React apps at scale (DataCorp processes 1M+ daily transactions)92. **Relevant PostgreSQL expertise** - Led database optimization project reducing query times by 60%103. **DevOps/CI-CD** - Implemented GitHub Actions pipeline, Kubernetes deployments114. **Architecture experience** - Designed microservices architecture serving 10M users125. **Startup background** - Previous role at early-stage startup (20 employees)1314## Concerns/Gaps151. **AI/ML experience not mentioned** - Resume doesn't show direct AI work (but this is preferred, not required)162. **Open source** - No public contributions visible173. **Career gap** - 6-month gap in 2021 (may have explanation)1819## Interview Questions201. "Tell me about your database optimization project at DataCorp. What specific techniques did you use?"212. "Have you worked with any AI/ML technologies? Any interest in that area?"223. "I see a gap in early 2021 - what were you doing during that time?"234. "Describe a time you had to make a difficult architectural decision with trade-offs."245. "What interests you about moving from a large company to our startup?"2526## Recommendation27**ADVANCE** - Strong technical match with 8 years experience and relevant stack expertise. Verify culture fit and interest in AI during phone screen. Clarify career gap.Bias Mitigation
- Blind screening: Remove names, photos, demographics before AI analysis
- Structured criteria: Score only on job-related requirements
- Audit trail: Log all decisions for bias review
- Diverse validation: Regularly validate against diverse candidate pools
- Human review: All candidates reviewed by humans, AI is advisory only
Legal Note: Consult with legal/HR before implementing. Some jurisdictions have specific requirements for AI in hiring. Always maintain human decision-making authority.
Benefits
- Time Savings: Screen 100 resumes in minutes vs hours
- Consistency: Same criteria applied to every candidate
- Quality: Never miss a qualified candidate due to fatigue
- Documentation: Clear reasoning for all recommendations