Skip to content
AI Workflow 01 · HR Recruitment & CV Triage

Hire 10 promoters from 1,040 CVs — in one terminal command.

A working AI hiring pipeline you run on a laptop. Drop the Indeed.ae downloads and unzipped WhatsApp CVs in one folder, run python run_screener.py, and Claude Code reads every PDF / DOCX / image, scores each candidate against your JD, and ships a searchable HTML dashboard + Excel + PDF shortlist. Built for the Sales Promoter (Hypermarket), Dubai role — reusable for any role by editing one text file.

Open the screener app → Run it inline ↓ See how it got built Daily Tier A catcher

What this process replaces

A recruiter or HR ops manager spending three to five days opening 1,040 CVs one by one — copying name, visa, languages, and experience into a spreadsheet, then guessing which ten to call. This pipeline does the same job in minutes, with the same answer every time, and hands you a dashboard your hiring manager can actually search.

1,040CVs handled in one run
~5 minraw inbox → ranked shortlist
$0infra — runs on your laptop
1command per re-run

The architecture

STEP 01 · YOU
Collect & brief
Drop Indeed.ae + WhatsApp CVs into ~/Downloads/promoter_cvs. Paste the role into job_description.txt.
STEP 02 · EXTRACT
extract_text.py
Reads every PDF / DOCX / TXT / image (OCR optional). One text blob per candidate, sub-folders included.
STEP 03 · CLAUDE
analyze.py
Pulls name, visa, languages, years, hypermarket history. Scores each CV vs the JD. Auto-falls back to a rules engine if a call fails.
STEP 04 · OUTPUT
report.py
Writes dashboard.html (searchable, sortable, top 10 in gold), candidates.xlsx, top10_shortlist.pdf and raw JSON.

What's in the toolkit

A tiny, working Python repo. No frameworks, no servers, no SaaS account. Read the CLAUDE.md once inside Claude Code and it knows the entire workflow.

promoter_screener/run_screener.py
Main entry point. python run_screener.py runs the whole pipeline.
promoter_screener/config.py
All settings: CV_FOLDER, TOP_N, AI_ENGINE, ANTHROPIC_API_KEY, LLM_RESCORE_ONLY_TOP for cost control.
promoter_screener/job_description.txt
The JD. AI re-reads it every run. For a new role, just edit this file.
promoter_screener/extract_text.py
Reads PDF, DOCX, TXT, and (with Tesseract) scanned / photo CVs into clean text.
promoter_screener/analyze.py
LLM + rules extraction and the scoring model. Keyword banks are at the top — edit those, not the logic.
promoter_screener/report.py
Builds the four outputs: HTML dashboard, Excel, PDF shortlist, JSON.
promoter_screener/make_sample_cvs.py
Generates 22 fake CVs so you can run a full demo with no real data.
promoter_screener/CLAUDE.md
Project memory for Claude Code. Read once, it knows every command and convention.
promoter_screener/.claude/commands/
Slash commands: /setup, /screen, /add-role, /shortlist.

Quick start

npm install -g @anthropic-ai/claude-code
cd Hr-recuritement-ai-process/promoter_screener
claude                              # reads CLAUDE.md automatically
/setup                              # one-time install + key
# drop Indeed + WhatsApp CVs into ~/Downloads/promoter_cvs
/screen                             # runs everything, reports top 10
# open output/dashboard.html

Or run the pipeline directly

pip install -r requirements.txt
python run_screener.py
# → output/dashboard.html         searchable, sortable, top 10 in gold
# → output/candidates.xlsx        every candidate, every field
# → output/top10_shortlist.pdf    clean shortlist for your manager
# → output/candidates.json        raw structured data

The scoring model

Four hard must-haves drive ranking. Candidates are sorted first by how many of the 4 they meet, then by score. The whole table lives in analyze.py → score_candidate; change a number, save, re-run.

SignalWhy it mattersPoints
Sales experienceRetail / promotion / merchandising track record28
Hypermarket experienceCarrefour, Lulu, Union Coop, Spinneys, Nesto, Geant, Choithrams28
Own visaOwn / spouse / family / freelance / cancellable — not employer-sponsored22
Immediate joinerCan start now — no 30/60-day notice12
Currently in UAENo relocation friction+6
2+ languagesEN + AR / HI / UR / Tagalog for shop-floor coverage+4
Years of experience+1 per year, capped at 5+5

Tiers

A meets all 4 must-haves  ·  B meets 3  ·  C meets 2  ·  D weak fit

The Top 10 (set by TOP_N in config) are highlighted in gold across the dashboard, Excel, and PDF.

Two engines, one pipeline

Free rules engine

No API key. Keyword + regex extraction tuned for UAE retail CVs. Instant, deterministic, runs offline. Great for a first pass on 1,000+ files.

AI_ENGINE = "rules"

Claude (LLM)

Best accuracy on messy or scanned CVs. Adds a one-line "why this candidate" note. Auto-falls back to the rules engine per CV on errors — a run never fully fails.

AI_ENGINE = "llm"     # or "auto"
ANTHROPIC_MODEL = "haiku"   # or "sonnet"

Cost tip for 1,000+ CVs

Set LLM_RESCORE_ONLY_TOP = 60. The free rules engine scores every CV instantly, then Claude only re-analyses the 60 strongest. You get LLM accuracy where it matters while paying for a fraction of the calls.

Reuse it for any role

The whole toolkit is one folder. To screen for a different role:

  • Edit job_description.txt — the JD the AI re-reads each run.
  • Update the keyword banks at the top of analyze.py (HYPERMARKETS, SALES_TERMS, OWN_VISA_TERMS, IMMEDIATE_TERMS).
  • Adjust the WEIGHTS dict if must-haves change.
  • Drop the new role's CVs in the folder. Re-run.

That's it. The dashboard, Excel, and PDF auto-rebuild against the new criteria.

Run the screener — right here, in your browser

Want just the tool, no write-up? Open the clean screener app →

This is the real engine, not a video. Drop your own CVs (PDF · DOCX · TXT) into the box below — or paste CV text — and the page reads each file, extracts the fields, scores every candidate against the JD using the exact keyword + weight model from analyze.py, and renders the searchable shortlist dashboard. No upload to any server, no API key — everything runs locally in your browser. No CVs handy? Click Run 22 sample CVs to see a full run instantly.

Engine: Rules engine (in-browser) · scores against the live JD · top 10 shortlisted
⬆ Drop real CVs here to screen them for real
PDF · DOCX · TXT · multiple files OK — or ·
🔒 100% private — files never leave your device.
STEP 01
Collect CVs
Idle — click Run.
STEP 02
Extract text
Waiting…
STEP 03
Analyze & score
Waiting…
STEP 04
Build outputs
Waiting…

How this got built — the actual conversation

No spec doc, no Jira ticket. Three Q&A rounds with the agent took the role from "I need 10 promoters" to a working pipeline verified on 22 sample CVs. The exchange below is the real transcript.

Aziz

HR dept needs 10 promoters. I logged into Indeed.ae as an employer to post the JD — days later 1,000 CVs landed in the inbox. I also have ~40 CVs in WhatsApp I'll zip and drop in ~/Downloads. Build me a workflow that (1) collects them, (2) takes my JD, (3) extracts every CV's details into a searchable HTML, (4) sorts and picks the top 10.

Agent

Before I build — four quick questions:

  1. Where will the CVs physically live?
  2. What's the role & the must-have screening criteria?
  3. What's the final deliverable?
  4. How should this run — reusable script, scheduled agent, or one-off?
Aziz
  • Location: all in a local Downloads folder.
  • Role & filters: sales promoters with hypermarket experience, must have own visa in Dubai, ready to work immediately.
  • Deliverable: HTML + Excel + PDF shortlist.
  • Run: reusable script + dashboard.
Agent

Got it. One more design call — the extraction engine. Your Claude API key gives the highest accuracy but costs per CV; a free offline rules engine is instant but matches keywords only. Which?

Aziz

Use my Claude API key — highest accuracy.

Agent

Building. I'll bake in the rules engine as automatic fallback so a run never fully fails on rate limits when 1,000 CVs hit the API.

Scaffolded  ·  extract_text.py · analyze.py · report.py · run_screener.py · CLAUDE.md · /setup /screen /shortlist /add-role.

Verified  ·  ran make_sample_cvs.py → 22 fake CVs → python run_screener.py → all four outputs ship, top 10 are the candidates that meet all 4 musts. Screenshot of dashboard + PDF attached.

Aziz

Good. Give me Claude Code-ready files so an end user can run this conversationally.

Agent

Done. Packaged CLAUDE.md + .claude/commands/ + a bootstrap prompt so a non-technical user just types:

npm install -g @anthropic-ai/claude-code
cd promoter_screener
claude        # reads CLAUDE.md automatically
/setup        # one-time
# drop Indeed + WhatsApp CVs into ~/Downloads/promoter_cvs
/screen       # runs everything, reports top 10
# open output/dashboard.html

Three rounds. Working pipeline. The build conversation is the requirements doc — nothing else got written down.

Follow-up workflow — Daily Tier A catcher

One real-world question after the first run was: "Catch net-new Tier A Promoter candidates from Gmail and Indeed.ae every weekday before my hiring review, ranked by visa and hypermarket fit." Same scoring model, scheduled. This is now built and runnable — the files below ship in promoter_screener/, and python catch_tier_a.py --demo runs the whole flow end-to-end with no credentials. The mind tree below is the design it implements.

How it reuses what's already built

  • Same scorer. Imports analyze_rules() / score_candidate() from analyze.py — one source of truth for ranking.
  • Same JD & same store. Reads job_description.txt and diffs against the very same output/candidates.json the screener writes, so it only ever alerts on net-new people.
  • Shipped files: catch_tier_a.py, gmail_poll.py, indeed_pull.py, diff.py, digest.py, the /catch-tier-a slash command, and a ready-to-copy GitHub Actions cron template.
  • No new model logic. If you tune weights in analyze.py for the screener, the catcher inherits it automatically the next morning.
  • Runs with zero credentials. Gmail / Indeed / WhatsApp connectors degrade gracefully to local folders + a saved digest, so it works before you wire up any API keys.
# Zero setup — seeds fresh sample CVs and runs the whole flow:
python catch_tier_a.py --demo

# Real run — pull since last night, send the digest to WhatsApp + email:
python catch_tier_a.py --since "yesterday 17:00" --digest whatsapp+email

# Or inside Claude Code:
/catch-tier-a since=yesterday digest=whatsapp+email

The whole recruiting agent on one screen

Screening is step 3 of a bigger loop. Here's the end-to-end flow an end user actually follows — you type one brief in Claude Code, the agent runs five steps, and a single Google Sheet is the live database behind all of it.

You — in Claude Code
💬 Type a brief
“10 sales promoters, hypermarket, Dubai, own visa, immediate”
The agent — 5 steps
STEP 01
📝
Create JD
Writes the job description and extracts the scored screening criteria.
Claude API · rules fallback
STEP 02
📤
Post jobs
Posts to Indeed + LinkedIn on your logged-in browser (you confirm each).
Playwright MCP
STEP 03
📥
Accept candidates
Pulls from 4 sources, then screens & scores every CV. (This page.)
Gmail · folder · WhatsApp · browser
STEP 04
✉️
Send project info
Accepts your top picks and emails / messages them the project details.
Gmail · WhatsApp Cloud
STEP 05
📊
Daily reports
Dashboard + email + WhatsApp recap for the business, every morning.
HTML · Gmail · WhatsApp
Single source of truth
🗄️ Google Sheet — “Recruiting Pipeline”
Tabs: Candidates · Jobs · Log  |  every action is read/written here
You trigger Agent step Data store All browser actions ask for your confirmation and respect daily caps.

Open the full interactive demo → Try the live CV screener HR Skill & workflows reference

Where this fits in the full HR workflow

This page covers the screening half of HR Workflow 01. The mind-tree on the home page shows the full loop — from AI-written JD and Indeed posting through to a LiveKit voice agent confirming the Zoom slot in EN/AR/HI. Screening is the link in the middle that turns 1,040 raw CVs into the 10 calls worth making.

See all 10 SMB AI workflows → See the full recruiting-agent demo See the chef-recruiter variant