# How Hiring Agent Parses Different Sections of a Resume

> Discover how Hiring Agent parses resume sections. Learn about PDF to text conversion, LLM prompts, Jinja templates, and Pydantic JSONResume model integration for efficient recruitment.

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

---

**Hiring Agent extracts resume sections by converting PDF documents to raw text, then processing that text through section-specific LLM prompts defined in Jinja templates, and finally aggregating the structured responses into a Pydantic `JSONResume` model.**

The `interviewstreet/hiring-agent` repository implements a hybrid parsing pipeline that transforms unstructured candidate documents into structured data. This technical approach combines PDF text extraction with AI-driven content classification to reliably identify and separate distinct resume sections like work experience, education, and skills.

## PDF Text Extraction Foundation

The parsing process begins in [`main/pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/pdf.py) with the **`PDFHandler`** class, which handles the initial document ingestion. The **`extract_text`** method (around line 54) reads the uploaded PDF file, converts each page to raw text, and concatenates the results into a single continuous string.

This raw text extraction serves as the contextual foundation for all subsequent section parsing. The system does not attempt to split sections during this phase; instead, it preserves the full document text to maintain contextual relationships between different parts of the resume.

## Section-Specific LLM Prompting Strategy

Rather than using rule-based parsing, Hiring Agent employs a template-driven LLM strategy defined in [`main/prompts/template_manager.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/prompts/template_manager.py). This module maintains a dictionary of **Jinja templates** (such as `basics.jinja`, `work.jinja`, `education.jinja`, `skills.jinja`, `projects.jinja`, and `awards.jinja`) that instruct the LLM how to extract specific sections.

Each template defines the expected JSON schema for its respective section while embedding the complete raw resume text as context. The **`_call_llm_for_section`** method in [`main/pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/pdf.py) (around line 145) orchestrates these calls by:
1. Rendering the appropriate Jinja template with the resume text
2. Sending the formatted prompt to the LLM
3. Parsing the JSON response into the corresponding Pydantic section model

## Individual Section Extraction Methods

The `PDFHandler` class exposes specific extraction methods for each standard resume section:

- **`extract_basics_section`** – Parses candidate contact information and personal details
- **`extract_work_section`** – Identifies employment history and job responsibilities  
- **`extract_education_section`** – Extracts degrees, institutions, and academic dates
- **`extract_skills_section`** – Catalogs technical and soft skills
- **`extract_projects_section`** – Captures portfolio and personal project details
- **`extract_awards_section`** – Recognizes certifications and honors

Each method follows the same pattern: render the section-specific prompt, call the LLM via `_call_llm_for_section`, and return a validated Pydantic model representing that particular section's data structure.

## Structured Data Aggregation

Once individual sections are extracted, the system aggregates them into a unified **`JSONResume`** model defined in [`main/models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/models.py) (around line 201). This Pydantic model mirrors the official JSON Resume schema and includes typed attributes for `basics`, `work`, `education`, `skills`, `projects`, `awards`, and other standard resume components.

The `JSONResume` model enforces type safety and validation across all extracted sections, ensuring that the final output conforms to a predictable schema regardless of the input document's original formatting or layout variations.

## Converting to Human-Readable Formats

After_structuring the data_, Hiring Agent can transform the `JSONResume` object into alternative formats for evaluation or export. The **`convert_json_resume_to_text`** function in [`main/transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/transform.py) (around line 744) walks through every populated field and produces a human-readable text block.

This text representation feeds into the evaluation pipeline in [`main/score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/score.py), where it serves as context for assessment LLMs, or exports to CSV format for spreadsheet analysis.

## Complete Implementation Example

The following example demonstrates the complete parsing workflow from PDF to structured data:

```python
from main.pdf import PDFHandler
from main.models import JSONResume
from main.transform import convert_json_resume_to_text

# Initialize the PDF handler

pdf_handler = PDFHandler()

# Step 1: Extract raw text from PDF

raw_text = pdf_handler.extract_text("candidate_resume.pdf")

# Step 2: Parse individual sections using LLM-powered extraction

basics = pdf_handler.extract_basics_section(raw_text)
work = pdf_handler.extract_work_section(raw_text)
education = pdf_handler.extract_education_section(raw_text)
skills = pdf_handler.extract_skills_section(raw_text)
projects = pdf_handler.extract_projects_section(raw_text)
awards = pdf_handler.extract_awards_section(raw_text)

# Step 3: Aggregate into unified JSONResume model

resume = JSONResume(
    basics=basics,
    work=work,
    education=education,
    skills=skills,
    projects=projects,
    awards=awards,
)

# Step 4: Convert to text for evaluation or export

resume_text = convert_json_resume_to_text(resume)
print(resume_text)

```

## Summary

- **PDF Processing:** The `PDFHandler` class in [`main/pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/pdf.py) converts documents to raw text using the `extract_text` method.
- **LLM-Driven Extraction:** Section-specific Jinja templates in [`main/prompts/template_manager.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/prompts/template_manager.py) guide the LLM to extract structured data via `_call_llm_for_section`.
- **Typed Methods:** Dedicated methods like `extract_work_section` and `extract_education_section` handle each resume component individually.
- **Schema Validation:** The `JSONResume` Pydantic model in [`main/models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/models.py) aggregates all sections into a standardized format.
- **Output Flexibility:** `convert_json_resume_to_text` in [`main/transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/transform.py) enables conversion to human-readable formats for scoring or CSV export.

## Frequently Asked Questions

### What file format does Hiring Agent require for resumes?

Hiring Agent processes **PDF documents** as its primary input format. The `extract_text` method in [`main/pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/pdf.py) specifically handles PDF parsing to produce the raw text required for LLM processing.

### How does Hiring Agent handle different resume layouts and formats?

The system uses **context-aware LLM prompts** rather than rigid template matching. By providing the complete resume text to section-specific Jinja templates, the LLM can identify relevant information regardless of formatting variations, column layouts, or section ordering.

### Can Hiring Agent extract sections from image-based PDFs or scanned documents?

The analysis indicates text-based extraction via standard PDF parsing. For image-based or scanned PDFs, the repository would require OCR (Optical Character Recognition) preprocessing before the `extract_text` method could process the content, though this specific capability isn't detailed in the core parsing logic.

### What data schema does the parsed resume follow?

Hiring Agent implements the **JSON Resume standard** through the `JSONResume` Pydantic model in [`main/models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/models.py). This schema includes standardized fields for basics, work experience, education, skills, projects, awards, and other common resume sections, ensuring interoperability with other HR tech systems.