# What Is the interviewstreet/hiring-agent Repository? Architecture and Usage Guide

> Explore the interviewstreet/hiring-agent repository, a Python app for resume analysis. It converts PDFs to JSON, adds GitHub data, and provides fairness-aware evaluations with LLMs.

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

---

**The interviewstreet/hiring-agent repository is an open-source Python application that implements a modular Resume-to-Score pipeline, converting PDF résumés into structured JSON data, enriching them with GitHub activity, and generating fairness-aware evaluations using either local LLMs via Ollama or Google Gemini.**

The **interviewstreet/hiring-agent repository** provides a transparent, reproducible system for technical candidate evaluation. It transforms unstructured PDF résumés into standardized JSON Resume schemas while integrating external signals from GitHub profiles. Designed to run on a single laptop via Ollama or in the cloud via Gemini, this modular architecture enables explainable hiring decisions through a clear separation of parsing, enrichment, and scoring concerns.

## Architecture Overview

The system implements a **Resume-to-Score** pipeline that processes candidate documents through five distinct stages. Each module is provider-agnostic and communicates through well-defined Pydantic schemas, ensuring the workflow remains reproducible across different LLM backends.

### The Five-Stage Processing Pipeline

**1. PDF Extraction**  
The pipeline begins in [`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py), which delegates to [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py) to convert PDF pages into Markdown-like text. This process preserves structural elements including headings, hyperlinks, and tables while maintaining the document's semantic hierarchy for downstream processing.

**2. Section Parsing**  
The [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py) module segments extracted text into logical sections (experience, education, skills) and sends each section to the LLM using Jinja templates stored in `prompts/templates/*.jinja`. The LLM returns strict JSON matching the *JSON Resume* schema, which [`transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/transform.py) normalizes into proper format compliance.

**3. GitHub Enrichment**  
The [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) module detects GitHub usernames within the parsed résumé, fetches the candidate's profile and repositories, classifies projects by type, and prompts the LLM to select the top 7 most relevant projects for technical evaluation.

**4. Fairness-Aware Evaluation**  
The [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) module applies constrained scoring rules that check for open-source contributions, self-initiated projects, production experience, and technical skills. It implements explicit bonus and deduction logic while maintaining fairness constraints to reduce evaluation bias.

**5. Output Generation**  
Finally, [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) orchestrates the complete workflow, printing human-readable summaries to the console. When `DEVELOPMENT_MODE=True` in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py), it also appends CSV rows and caches intermediate JSON files for debugging and audit trails.

## Core Modules and Source Files

The repository organizes functionality into specialized modules, each with distinct responsibilities:

**[`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py)**  
Defines Pydantic schemas for the JSON résumé structure and implements unified LLM-provider interfaces through the `OllamaProvider` and `GeminiProvider` classes.

**[`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py)**  
Handles PDF-to-Markdown conversion and manages per-section LLM calls for structured extraction.

**[`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)**  
Integrates with the GitHub API to fetch profile metadata, repository statistics, and project classifications for technical candidate assessment.

**[`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)**  
Contains the fairness-aware scoring algorithms that evaluate candidates against predefined technical criteria with transparent scoring rules.

**[`llm_utils.py`](https://github.com/interviewstreet/hiring-agent/blob/main/llm_utils.py)**  
Manages provider initialization, request formatting, and response sanitization across different LLM backends.

**[`transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/transform.py)**  
Normalizes loosely-structured LLM outputs into strict *JSON Resume* format compliance.

**`prompts/`**  
Directory containing Jinja templates that encode extraction instructions, project selection criteria, and evaluation rubrics.

## Configuration and LLM Providers

The system supports dual LLM backends through a unified provider interface. Configuration is controlled via environment variables in the `.env` file:

- **`LLM_PROVIDER`**: Set to `"ollama"` for local inference or `"gemini"` for cloud-based processing
- **`DEFAULT_MODEL`**: Specifies the model name (e.g., `"llama3"` or `"gemini-1.5-pro"`)
- **`GEMINI_API_KEY`**: Required when using Google Gemini

The `OllamaProvider` and `GeminiProvider` classes in [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py) expose identical `chat()` methods, allowing the rest of the codebase to remain provider-agnostic regardless of the underlying API.

## Running the Hiring Agent Pipeline

### Installation

Set up the environment using Python 3.11 or higher:

```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

```

### Basic Usage

Execute the full pipeline against a résumé PDF:

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

```

This command triggers the complete workflow: [`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py) extracts text, [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) enriches data if usernames are detected, [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) computes scores, and [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) renders the final assessment.

### Direct LLM Provider Access

For custom integrations, instantiate providers directly:

```python
from models import OllamaProvider, GeminiProvider
from config import LLM_PROVIDER, DEFAULT_MODEL
import os

if LLM_PROVIDER == "ollama":
    provider = OllamaProvider(model=DEFAULT_MODEL)
else:
    provider = GeminiProvider(
        model=DEFAULT_MODEL, 
        api_key=os.getenv("GEMINI_API_KEY")
    )

response = provider.chat(
    messages=[{"role": "user", "content": "Summarize a software résumé"}]
)
print(response)

```

This abstraction allows uniform interaction regardless of whether the underlying engine is local or cloud-based.

## Summary

- The **interviewstreet/hiring-agent repository** provides a modular Python pipeline for converting PDF résumés into structured JSON and generating fairness-aware candidate scores.
- The architecture separates concerns across five distinct stages: PDF extraction ([`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py), [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py)), section parsing, GitHub enrichment ([`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)), evaluation ([`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)), and output generation ([`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py)).
- It supports both **local LLM inference via Ollama** and **cloud-based processing via Google Gemini** through a unified provider interface defined in [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py).
- The system is configurable through environment variables and includes a development mode for CSV output and JSON caching.

## Frequently Asked Questions

### What file formats does the hiring agent support?

The repository currently processes **PDF résumés** as input. The [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py) module uses PyMuPDF to extract text while preserving document structure, converting pages into Markdown-like format before LLM processing.

### Can I run the interviewstreet/hiring-agent without an internet connection?

Yes. By setting `LLM_PROVIDER=ollama` in your `.env` file and running a local Ollama instance, the entire pipeline executes offline. Note that GitHub enrichment requires internet connectivity to fetch profile data through the GitHub API.

### How does the evaluation ensure fairness?

The [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) module implements **fairness-constrained scoring rules** that evaluate candidates on objective criteria including open-source contributions, production experience, and technical skills. The scoring logic includes explicit bonus and deduction mechanisms while avoiding biased demographic indicators.

### Where are the LLM prompts defined?

All extraction and evaluation prompts are stored as **Jinja2 templates** in the `prompts/templates/` directory. These templates encode the JSON Resume schema requirements and scoring rubrics, making the LLM instructions version-controllable and modifiable without changing Python code.