The Core Stack: What You’ll Actually Need
Forget the all-in-one platforms that charge thousands per month. You can build a potent, custom ai-powered recruitment platform with a few off-the-shelf tools. This isn’t theoretical; I run a version of this for my own hiring, and it saves me about 10 hours of garbage work per job posting.
Here’s the stack:
- Workflow Orchestrator: You need a brain to connect the services. Your main options are Make or n8n. Make is easier for beginners, its UI is slicker. n8n is more powerful, open-source, and its error handling is far better for anything you’re putting into production. I started on Make, but I run all my critical systems on n8n now.
- Candidate Database: Airtable. Don’t overthink this. It’s a spreadsheet that thinks it’s a database, and its API is dead simple to work with. The free plan is more than enough to handle hundreds of applicants for a few roles.
- The AI Model: Your choice is between OpenAI‘s GPT models or Anthropic‘s Claude models. For parsing unstructured text from resumes, my money is on Claude 3.5 Sonnet as of mid-2026. It’s faster, cheaper than GPT-4o, and I’ve found it’s less likely to hallucinate structured data from a messy PDF. This is one of those operator playbooks where the specific model choice matters a lot.
- (Optional) A Simple Frontend: If you want a dashboard for non-technical team members to review flagged candidates, Retool is the professional choice. It’s not cheap, starting at $10/user/month, but it’s built for exactly this kind of internal tooling. For a simpler, cheaper option, Softr can build a basic portal on top of your Airtable data.
Step 1: Ingesting and Parsing Resumes
Your workflow starts the moment a candidate applies. The goal is to get their resume—usually a PDF or DOCX file—into a clean text format the AI can understand. The most reliable trigger is a dedicated inbox, like `jobs@yourcompany.com`.
Here’s the flow inside Make or n8n:
- Trigger: New Email Received. Filter for emails with attachments.
- Download Attachment: Save the file temporarily.
- Convert to Text: This is the most critical and failure-prone step. Do not just try to read the raw file. You need a dedicated service to convert it to plain text. I use the CloudConvert API for this. It’s not free, but it’s cheap (around $9 for 500 conversion minutes) and handles the ugly parts of PDF parsing.
- Store Text: Save the clean text output to a field in your Airtable base.
My main gripe with this entire process is PDF parsing. It’s a fundamentally broken part of the internet. Resumes with columns, tables, weird fonts, and logos will often turn into gibberish during the text extraction. CloudConvert is good, but it’s not magic. You have to plan for maybe 5-10% of your inputs being garbage. We’ll address how to handle that later.
What Most Guides Get Wrong About Candidate Scoring
Almost every tutorial I’ve seen on this topic makes the same mistake. They feed the resume text into an LLM with a lazy prompt like, “Score this candidate for a Senior Developer role from 1 to 10.”
This gives you useless, inconsistent, and biased results. The AI has no context for what *you* consider a good developer. It’s just pattern-matching against its training data.
A real system uses a multi-step prompting chain based on a specific, objective rubric. You aren’t asking for an opinion; you’re commanding it to act as a data-extraction machine.
Here’s the right way to do it:
- Define Your Ideal Candidate Profile (ICP): Write down the non-negotiable skills, experience levels, and keywords. This becomes your rubric.
- First Prompt: Data Extraction. The first call to the LLM isn’t for scoring. It’s for turning the unstructured resume text into structured JSON. You ask it to pull out specific entities: name, email, phone, years of experience with Python, mentions of AWS, etc.
- Second Prompt: Scoring Against the Rubric. Once you have the structured data, you can score it. This can be a separate AI call or even simple conditional logic in your workflow tool (e.g., IF `years_python > 5`, score = 10). I prefer using the LLM for this too, as it can handle nuance better. You feed it the extracted JSON and your rubric, and ask it to return a final score for each category.
This two-step process separates extraction from analysis, which dramatically reduces errors and makes the entire system easier to debug. You can see exactly what data the scoring was based on.
The “Scoring Engine” Prompt (A Real Example)
Never use a vague prompt. You need to be ruthlessly specific and demand a structured output. Forcing the model to return JSON is the single most important technique for building a reliable ai agent framework.
Here is a simplified version of a prompt I use to analyze candidates for a technical role. Notice how it provides a schema and clear instructions.
You are an expert technical recruiter tasked with extracting structured data from the following resume text. Your output MUST be a valid JSON object. Do not include any explanatory text before or after the JSON.
Resume Text:
---
{{RESUME_TEXT_FROM_PREVIOUS_STEP}}
---
Based on the text, populate the following JSON schema. If a value is not found, use null.
{
"contact_info": {
"name": "string",
"email": "string",
"phone": "string"
},
"experience_years": {
"python": number,
"react": number,
"aws": number
},
"scoring": {
"seniority_score_1_10": "Score 1-10 based on titles like 'Senior', 'Lead', 'Principal'. A 'Junior' or intern gets a 1-3.",
"aws_project_score_1_10": "Score 1-10 based on the depth of AWS project descriptions. Mentioning specific services like Lambda, S3, and DynamoDB gets a higher score than just listing 'AWS'."
},
"red_flags": ["List any potential red flags here, such as: job hopping (more than 3 jobs in 2 years), unexplained career gaps over 6 months, or major typos."],
"summary_for_hiring_manager": "Write a 2-sentence summary of the candidate's key strengths as they relate to a Senior Backend Engineer role.",
"parsing_confidence_score_1_10": "Rate your confidence from 1-10 that you accurately extracted all the key information from the provided text. A low score indicates the source text was messy or unclear."
}
This prompt does the work. It defines the structure, gives the AI a persona, and even asks it to self-report its confidence. That last field is your secret weapon for quality control.
