# InterviewStreet Hiring Agent Architecture: Core Components Explained

> Explore the InterviewStreet hiring-agent architecture. Understand its nine Python modules for resume parsing, LLM evaluation, GitHub enrichment, and fairness-aware scoring. Optimize your hiring process.

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

---

**The InterviewStreet hiring-agent architecture is a modular Resume-to-Score pipeline that converts PDF resumes into structured JSON evaluations through nine specialized Python modules handling extraction, LLM parsing, GitHub enrichment, and fairness-aware scoring.**

The `interviewstreet/hiring-agent` repository implements a robust **hiring agent architecture** designed to automate technical candidate screening. This system processes documents through a linear pipeline—from raw PDF ingestion to explainable numerical scores—while maintaining strict separation between document processing, external API calls, and evaluation logic.

## PDF Text Extraction Layer

The pipeline begins in [[`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py)](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py), where **PyMuPDF** converts PDF pages into Markdown-like text. This low-level extraction module handles the initial document ingestion stage, preparing raw content for downstream LLM processing.

## Structured Resume Parsing

The [[`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py)](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py) module contains the `PDFHandler` class, which orchestrates the transformation of extracted text into structured sections. This component:
- Invokes the LLM for each resume section (basics, work, education, skills, projects, awards)
- Uses Jinja-templated prompts for consistent formatting
- Validates output against the `JSONResume` Pydantic schema

## LLM Provider Abstraction

[[`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py)](https://github.com/interviewstreet/hiring-agent/blob/main/models.py) provides a unified interface for multiple backend providers through `OllamaProvider` and `GeminiProvider` classes. This abstraction layer allows the system to switch between local Ollama instances and Google's Gemini API without modifying downstream parsing logic, with global settings defined in [`prompt.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompt.py).

## Template-Based Prompt Management

All LLM interactions rely on Jinja templates stored in `prompts/templates/*.jinja`. The [[`prompts/template_manager.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompts/template_manager.py)](https://github.com/interviewstreet/hiring-agent/blob/main/prompts/template_manager.py) module handles loading and rendering these templates for specific resume sections.

To render a prompt programmatically:

```python
from prompts.template_manager import TemplateManager

tm = TemplateManager()
system_msg = tm.render_template(
    "system_message",
    section_name_param="basics"
)
print(system_msg)

```

## GitHub Profile Enrichment

The [[`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) module detects GitHub usernames within resumes and fetches profile metadata and repositories. This component classifies projects, then prompts the LLM to select the **top 7 most relevant projects** for evaluation, adding crucial technical context to the candidate profile.

## Fairness-Aware Evaluation Engine

[[`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) implements the scoring rubric that produces the final candidate assessment. This engine applies fairness-aware criteria across categories like open-source contributions, production experience, and technical skills, calculating bonuses and deductions while generating human-readable explanations for each score.

## Orchestration and CLI Entry Point

The [[`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py)](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) module serves as the pipeline coordinator and command-line interface. It caches intermediate results between stages and writes evaluation summaries to CSV when `DEVELOPMENT_MODE` is enabled.

Run the complete pipeline from the command line:

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

```

## Configuration and Data Models

[[`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py)](https://github.com/interviewstreet/hiring-agent/blob/main/config.py) manages environment-specific settings including the `DEVELOPMENT_MODE` flag and LLM provider selection. [[`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py)](https://github.com/interviewstreet/hiring-agent/blob/main/models.py) defines the Pydantic schemas that enforce type safety across the `JSONResume` structure and all section definitions.

## Programmatic API Usage

You can invoke individual components directly without the CLI:

```python
from pdf import PDFHandler
from evaluator import Evaluator
from github import GitHubEnricher

# Extract structured resume from PDF

handler = PDFHandler()
json_resume = handler.extract_json_from_pdf("resume.pdf")

# Enrich with GitHub data

enricher = GitHubEnricher()
enriched = enricher.enrich(json_resume)

# Run evaluation

evaluator = Evaluator()
result = evaluator.evaluate(enriched)

print(result.summary())

```

## Summary

The InterviewStreet **hiring agent architecture** processes resumes through a linear pipeline with clear module boundaries:

- **Document Ingestion**: [`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py) extracts Markdown from PDFs
- **LLM Processing**: [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py) and [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py) handle section parsing with provider abstraction
- **Prompt Engineering**: [`prompts/template_manager.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompts/template_manager.py) manages Jinja templating
- **Data Enrichment**: [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) adds GitHub activity context
- **Scoring**: [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) applies fairness-aware rubrics
- **Orchestration**: [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) coordinates execution and provides CLI access

## Frequently Asked Questions

### How does the hiring agent architecture handle PDF extraction?

The architecture uses **PyMuPDF** via [`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py) to convert PDF pages into Markdown-like text. This extracted text then feeds into the `PDFHandler` class in [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py), which manages the subsequent LLM-based section parsing.

### What LLM providers are supported in the hiring agent architecture?

The system supports **Ollama** for local model execution and **Google Gemini** for cloud-based inference. These are abstracted behind provider classes (`OllamaProvider` and `GeminiProvider`) in [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py), allowing seamless switching via environment variables.

### Where are the evaluation criteria defined in the codebase?

The fairness-aware scoring rubric is implemented in [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py). This module applies criteria for open-source contributions, production experience, and technical skills while calculating bonuses, deductions, and generating human-readable explanations.

### How can I run the hiring agent pipeline locally?

Execute `python score.py /path/to/resume.pdf` from the repository root. Set `DEVELOPMENT_MODE=True` to enable CSV output caching. Configure your preferred LLM provider in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py) or via environment variables.