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

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, which delegates to 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 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 normalizes into proper format compliance.

3. GitHub Enrichment
The 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 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 orchestrates the complete workflow, printing human-readable summaries to the console. When DEVELOPMENT_MODE=True in 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
Defines Pydantic schemas for the JSON résumé structure and implements unified LLM-provider interfaces through the OllamaProvider and GeminiProvider classes.

pdf.py
Handles PDF-to-Markdown conversion and manages per-section LLM calls for structured extraction.

github.py
Integrates with the GitHub API to fetch profile metadata, repository statistics, and project classifications for technical candidate assessment.

evaluator.py
Contains the fairness-aware scoring algorithms that evaluate candidates against predefined technical criteria with transparent scoring rules.

llm_utils.py
Manages provider initialization, request formatting, and response sanitization across different LLM backends.

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 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:

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

Basic Usage

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

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

This command triggers the complete workflow: pymupdf_rag.py extracts text, github.py enriches data if usernames are detected, evaluator.py computes scores, and score.py renders the final assessment.

Direct LLM Provider Access

For custom integrations, instantiate providers directly:

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, pdf.py), section parsing, GitHub enrichment (github.py), evaluation (evaluator.py), and output generation (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.
  • 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 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →