# Understanding the 5 Stages in the Hiring Agent Processing Pipeline

> Explore the 5 stages of the Hiring Agent processing pipeline. Learn how it transforms candidate résumés into fairness-aware evaluations, improving your hiring efficiency.

- Repository: [HackerRank/hiring-agent](https://github.com/interviewstreet/hiring-agent)
- Tags: internals
- Published: 2026-07-11

---

**The Hiring Agent executes a linear, five-stage pipeline that transforms a candidate’s résumé PDF into a structured, fairness-aware evaluation, with each stage implemented by dedicated modules orchestrated by [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py).**

The **interviewstreet/hiring-agent** repository provides a complete **resume-to-score processing pipeline** designed for automated technical recruiting. By breaking down the stages in the Hiring Agent processing pipeline, developers can better understand how unstructured PDF documents become quantified candidate assessments with explanatory evidence.

## Stage 1: PDF Extraction and Markdown Conversion

The pipeline begins in [`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py), where the **PDF extraction** stage converts uploaded résumés into Markdown-like text. The `PDFToMarkdown` class leverages PyMuPDF to read each page while preserving structural elements—headings, hyperlinks, tables, and basic formatting—ensuring downstream language models receive clean, structured input rather than raw text soup.

This stage handles the critical first transformation from binary PDF to parseable text, maintaining document hierarchy that subsequent stages depend on for accurate section identification.

## Stage 2: LLM-Powered Section Parsing

Once converted to Markdown, the **section parsing** stage processes each résumé component through LLM-driven templates. Located in [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py), the `PDFHandler` class coordinates with [`prompts/template_manager.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompts/template_manager.py) to feed section-specific Markdown content into Jinja templates stored in `prompts/templates/*.jinja`.

The LLM returns structured JSON that the pipeline normalizes into a standardized **JSON-Resume model** defined in [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py). This normalization ensures that wildly different résumé formats—from minimalist single-page designs to elaborate multi-column layouts—produce consistent data structures for evaluation.

## Stage 3: GitHub Profile Enrichment

The **GitHub enrichment** stage, implemented in [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py), transforms the pipeline from static document analysis to dynamic portfolio assessment. The `GitHubEnricher` class detects GitHub usernames within the parsed résumé content, then programmatically retrieves the candidate’s profile and repositories.

The system classifies projects by determining author commit thresholds and relevance, then prompts the LLM to select up to seven representative projects that best demonstrate the candidate’s technical capabilities. This stage ensures the evaluation considers actual code contributions rather than just self-reported skills.

## Stage 4: Fairness-Aware Evaluation

The core assessment logic resides in [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py), where the **evaluation** stage applies a strict, rubric-based scoring framework. The `Evaluator` class scores candidates across multiple dimensions:

- **Open-source contributions** and community engagement
- **Self-project** complexity and completeness
- **Production experience** and professional work history
- **Technical skills** depth and breadth
- **Bonus points** for exceptional achievements
- **Deductions** for red flags or missing information

Crucially, this stage generates **explanatory evidence** for each score, providing transparency into the automated decision-making process and enabling human reviewers to understand the rationale behind specific ratings.

## Stage 5: Output Generation and CSV Export

The final stage, orchestrated by [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py), handles **output and persistence**. The pipeline prints a human-readable evaluation summary to stdout for immediate review. When `DEVELOPMENT_MODE=True` in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py), the system additionally writes structured results to `resume_evaluations.csv` and caches intermediate JSON artifacts for debugging and audit purposes.

This dual-output approach supports both interactive recruiting workflows and bulk processing operations, with the CSV export enabling integration into existing applicant tracking systems.

## Running the Pipeline From the Command Line

Execute the complete five-stage pipeline with a single command:

```bash
python score.py /path/to/resume.pdf

```

This triggers the full sequence: PDF extraction → LLM section parsing → GitHub enrichment → fairness-aware evaluation → CSV export, processing the résumé through all transformation stages automatically.

## Programmatic Pipeline Execution

For integration into custom workflows, each stage exposes clean Python APIs:

Extract raw Markdown from PDFs (Stage 1):

```python
from pymupdf_rag import PDFToMarkdown

pdf_path = "resume.pdf"
markdown = PDFToMarkdown().to_markdown(pdf_path)
print(markdown[:500])  # preview first 500 characters

```

Parse specific sections using LLM templates (Stage 2):

```python
from pdf import PDFHandler
from prompts.template_manager import TemplateManager

handler = PDFHandler()
section_md = "... markdown for the Work section ..."
work_json = handler.parse_section(section_md, TemplateManager.WORK_TEMPLATE)
print(work_json)

```

Enrich with GitHub data (Stage 3):

```python
from github import GitHubEnricher

enricher = GitHubEnricher()
projects = enricher.enrich(username="octocat")
print(projects)   # list of up to 7 selected projects

```

Score and export results (Stages 4–5):

```python
from evaluator import Evaluator
from score import ScoreRunner

evaluation = Evaluator().evaluate(resume_json)
ScoreRunner().export(evaluation)   # writes CSV when dev mode is on

```

## Key Implementation Files

Understanding these source files clarifies the pipeline architecture:

- **[`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py)** – PDF-to-Markdown conversion (Stage 1)
- **[`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py)** – LLM-driven section parsing (Stage 2)
- **[`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)** – GitHub profile and repository enrichment (Stage 3)
- **[`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)** – Fairness-aware scoring logic (Stage 4)
- **[`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py)** – Pipeline orchestration and CSV export (Stage 5)
- **`prompts/templates/`** – Jinja templates controlling LLM instructions for each résumé section
- **[`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py)** – Pydantic schemas for JSON-Resume validation and provider-agnostic LLM interfaces
- **[`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py)** – Contains `DEVELOPMENT_MODE` flag and global configuration settings

## Summary

- The **Hiring Agent processing pipeline** consists of five linear stages: PDF extraction, LLM section parsing, GitHub enrichment, fairness-aware evaluation, and CSV export.
- **[`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py)** handles Stage 1 by converting PDFs to Markdown while preserving document structure.
- **Section parsing** in Stage 2 uses Jinja templates in `prompts/templates/` to normalize résumés into JSON-Resume format via [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py).
- **[`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)** enriches candidate profiles in Stage 3 by analyzing actual repositories and selecting up to seven representative projects.
- **[`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)** applies a transparent, rubric-based scoring system in Stage 4, generating evidence for each rating.
- **[`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py)** orchestrates the entire workflow and manages CSV output when `DEVELOPMENT_MODE` is enabled.

## Frequently Asked Questions

### How does the Hiring Agent extract text from PDF résumés?

The pipeline uses **[`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py)** and the `PDFToMarkdown` class to convert PDFs into Markdown-like text, preserving headings, links, and tables. This approach maintains document hierarchy better than simple text extraction, ensuring the LLM can accurately identify sections like Work Experience and Education.

### What data format does the pipeline use for structured résumé data?

Stages 2 through 5 operate on a **JSON-Resume** model defined in [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py). The LLM transforms Markdown sections into this standardized schema using Jinja templates, creating consistent data structures regardless of the original PDF layout or formatting.

### How does the GitHub enrichment stage select candidate projects?

The **`GitHubEnricher`** class in [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) fetches the candidate’s repositories, filters for minimum author-commit thresholds, and prompts the LLM to select up to seven projects that best represent technical skills. This prevents overflow of minor repositories while highlighting substantial contributions.

### Can I run individual pipeline stages without executing the full workflow?

Yes. While [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) runs all five stages sequentially, each module exposes independent APIs. You can import `PDFToMarkdown` for Stage 1, `PDFHandler` for Stage 2, or `GitHubEnricher` for Stage 3 individually, allowing custom integrations that bypass stages irrelevant to specific use cases.