# How to Create a New Hiring Campaign Using the CLI in Hiring Agent

> Learn to create a new hiring campaign using Hiring Agent's score py CLI script. Run the full evaluation pipeline and generate aggregated results in a CSV file.

- Repository: [HackerRank/hiring-agent](https://github.com/interviewstreet/hiring-agent)
- Tags: how-to-guide
- Published: 2026-06-26

---

**Hiring Agent does not expose a dedicated "campaign" sub-command; instead, you create a hiring campaign by invoking the [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) CLI script against multiple candidate resumes, which runs the full evaluation pipeline and aggregates results into a CSV file.**

The interviewstreet/hiring-agent repository provides a scriptable pipeline for evaluating engineering candidates. Unlike traditional applicant tracking systems with built-in campaign management, this tool treats a hiring campaign as a batch execution of the scoring pipeline against multiple PDF resumes. By leveraging the [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) entry point, you can orchestrate end-to-end evaluations—from PDF extraction to GitHub analysis—directly from your terminal.

## How the Campaign Pipeline Works

### Pipeline Components

The hiring campaign is realized through five distinct stages orchestrated by [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py):

1. **PDF Extraction** – [`pymupdf_rag.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pymupdf_rag.py) extracts raw text from candidate PDFs and converts it to a Markdown-like format.
2. **Section Parsing** – [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py) sends each resume section to your configured LLM (Ollama or Gemini) using Jinja templates stored in `prompts/templates/`.
3. **GitHub Enrichment** – [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) identifies GitHub profile URLs within the resume, fetches repository data, and selects the top-seven projects for scoring.
4. **Evaluation** – [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) applies the fairness-aware scoring rubric and generates a detailed assessment report.
5. **Output Generation** – [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) prints results to stdout and appends structured data to `resume_evaluations.csv` when `DEVELOPMENT_MODE=True` in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py).

## Environment Setup and Configuration

Before launching a campaign, configure your local environment and LLM provider.

### Install Dependencies

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

```

### Configure Environment Variables

Copy the example environment file and set your preferred LLM provider:

```bash
cp .env.example .env

```

Edit `.env` to specify the provider and model:

```bash
LLM_PROVIDER=ollama
DEFAULT_MODEL=gemma3:4b

```

## Running Your First Campaign

### Single Candidate Evaluation

Test the pipeline with one resume before scaling:

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

```

This invokes the full pipeline in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py), extracting content, enriching GitHub data, and printing the evaluation report to your terminal.

### Batch Processing Multiple Candidates

Since the repository lacks a native `campaign` command, wrap [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) in a shell loop to process multiple candidates:

```bash
for f in ./candidates/*.pdf; do
    echo "Evaluating $f"
    python score.py "$f"
done

```

Alternatively, create a Python wrapper script for more complex orchestration:

```python

# campaign.py

import glob
import subprocess

resume_files = glob.glob("candidates/*.pdf")
for pdf in resume_files:
    print(f"Scoring {pdf}")
    subprocess.run(["python", "score.py", pdf], check=True)

```

Run the wrapper with:

```bash
python campaign.py

```

## Reviewing Campaign Results

When `DEVELOPMENT_MODE=True` in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py), [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) appends each evaluation to `resume_evaluations.csv`. This file serves as your campaign database, enabling comparative analysis across candidates.

View the accumulated results:

```bash
cat resume_evaluations.csv

```

The CSV contains structured scoring data from [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py), allowing you to filter top performers or export to other reporting tools.

## Summary

- **Hiring Agent** implements campaigns as scriptable pipeline executions rather than monolithic commands.
- The [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) script serves as the primary CLI entry point, orchestrating [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py), [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py), and [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py).
- Run batch campaigns using shell loops or custom Python wrappers that invoke [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) iteratively.
- Enable `DEVELOPMENT_MODE` in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py) to persist results to `resume_evaluations.csv` for campaign-wide analysis.
- Configure LLM providers via environment variables before executing campaigns.

## Frequently Asked Questions

### Does Hiring Agent have a dedicated `campaign create` command?

No, the repository does not expose a dedicated campaign sub-command. According to the source code in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py), the architecture treats a hiring campaign as a series of individual scoring pipeline executions. You create a campaign by invoking [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) against multiple resume files in sequence, typically wrapped in a shell loop or orchestration script.

### Which file handles the actual candidate scoring logic?

The [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) module contains the fairness-aware scoring rubric implementation, while [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) acts as the CLI orchestrator that coordinates the pipeline. The evaluation logic processes data extracted by [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py) and enriched by [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) to generate the final assessment report.

### How do I switch between Ollama and Gemini for campaign processing?

Set the `LLM_PROVIDER` environment variable in your `.env` file to either `ollama` or `gemini`, and specify the model via `DEFAULT_MODEL`. The [`pdf.py`](https://github.com/interviewstreet/hiring-agent/blob/main/pdf.py) module reads these configurations to determine which LLM backend to use when parsing resume sections using the Jinja templates in `prompts/templates/`.

### Where are campaign results stored?

When `DEVELOPMENT_MODE=True` in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py), each execution of [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) appends a row to `resume_evaluations.csv` in your working directory. This CSV accumulates all candidate evaluations during your campaign, enabling batch analysis and comparison. If development mode is disabled, results print only to stdout.