# How `hiring-agent.py` Uses the Output from `evaluator.py` in the InterviewStreet Pipeline

> Learn how hiring-agent.py utilizes evaluator.py output. Discover how it processes resume evaluation data for reports and CSV export using ResumeEvaluator.

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

---

**The [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) script consumes structured evaluation data by instantiating the `ResumeEvaluator` class from [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py), calling its `evaluate_resume` method to obtain an `EvaluationData` object, and then passing that object to formatting functions for human-readable reports and CSV export.**

The `interviewstreet/hiring-agent` repository automates technical resume screening using LLM-powered evaluation. Understanding how the main orchestration script processes the output from [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) is essential for customizing scoring workflows or debugging the evaluation pipeline. The integration follows a strict four-step flow where unstructured resume text is transformed into a structured Pydantic model that drives the final scoring report.

## The Evaluation Flow: From Resume Text to Structured Data

The interaction between [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) (the hiring agent implementation) and [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) follows a predictable pipeline that converts raw resume data into actionable scores.

### Step 1: Instantiating the ResumeEvaluator

Inside [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py), the private helper `_evaluate_resume` begins by creating an instance of the `ResumeEvaluator` class defined in [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py). This instantiation happens at lines 66-69, where the code retrieves default model parameters from `MODEL_PARAMETERS` and initializes the evaluator with the specified LLM configuration.

```python

# In score.py (lines 66-69)

def _evaluate_resume(resume_data, github_data=None, blog_data=None) -> EvaluationData:
    model_params = MODEL_PARAMETERS.get(DEFAULT_MODEL)
    evaluator = ResumeEvaluator(model_name=DEFAULT_MODEL, model_params=model_params)

```

### Step 2: Composing the Resume Text

Before invoking the evaluator, the hiring agent prepares the input by converting JSON resume data into plain text. This composition phase (lines 70-82 in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py)) optionally enriches the resume with GitHub repository data and blog content using helper functions from [`transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/transform.py). The resulting string contains the complete candidate profile formatted for the LLM prompt.

```python
    # Build the prompt text (lines 70-82)

    resume_text = convert_json_resume_to_text(resume_data)
    if github_data:
        resume_text += convert_github_data_to_text(github_data)
    if blog_data:
        resume_text += convert_blog_data_to_text(blog_data)

```

### Step 3: Calling the Evaluator and Receiving EvaluationData

The hiring agent passes the composed text to `evaluator.evaluate_resume(resume_text)`, which sends the prompt to the configured LLM provider (lines 48-86 in [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)). The evaluator extracts a JSON blob from the LLM response and validates it against the `EvaluationData` Pydantic schema defined in [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py). This returns a strongly-typed object containing structured fields rather than raw text.

```python
    # Get structured evaluation from evaluator.py

    evaluation_result = evaluator.evaluate_resume(resume_text)
    return evaluation_result

```

### Step 4: Consuming the Evaluation Results

Back in the `main()` function of [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py), the returned `EvaluationData` object is stored in the `score` variable (lines 124-140). The `print_evaluation_results` function (lines 26-38) then accesses specific attributes—such as `scores`, `bonus_points`, and `deductions`—to generate a human-readable report and export data to CSV.

```python

# Consumption in main() (lines 124-140)

score = _evaluate_resume(resume_data, github_data, blog_data)

# Formatting for display (lines 26-38)

print_evaluation_results(score)

```

## Complete Implementation in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py)

The `_evaluate_resume` function serves as the primary bridge between the hiring agent and the evaluator. This implementation demonstrates the full sequence from instantiation to result consumption:

```python
from evaluator import ResumeEvaluator
from models import EvaluationData
from transform import (
    convert_json_resume_to_text,
    convert_github_data_to_text,
    convert_blog_data_to_text
)
from prompt import MODEL_PARAMETERS, DEFAULT_MODEL

def _evaluate_resume(resume_data, github_data=None, blog_data=None) -> EvaluationData:
    # 1. Create evaluator instance

    model_params = MODEL_PARAMETERS.get(DEFAULT_MODEL)
    evaluator = ResumeEvaluator(model_name=DEFAULT_MODEL, model_params=model_params)
    
    # 2. Compose resume text

    resume_text = convert_json_resume_to_text(resume_data)
    if github_data:
        resume_text += convert_github_data_to_text(github_data)
    if blog_data:
        resume_text += convert_blog_data_to_text(blog_data)
    
    # 3. Get structured evaluation

    evaluation_result = evaluator.evaluate_resume(resume_text)
    return evaluation_result

```

## The Data Schema: `EvaluationData`

The contract between [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) and [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) is enforced by the `EvaluationData` Pydantic model located in [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py). This schema ensures that the LLM output conforms to a predictable structure with typed fields for:

- **scores**: Numerical ratings for specific skill categories
- **bonus_points**: Additional positive attributes identified in the resume
- **deductions**: Negative indicators or missing requirements
- **summary**: Overall assessment text

By using this schema, [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) can safely access evaluation results without parsing raw JSON or handling ambiguous LLM responses.

## Summary

- **[`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) imports `ResumeEvaluator`** from [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) and wraps it in the `_evaluate_resume` helper function.
- **The evaluation pipeline** transforms JSON resume data into plain text, optionally appends GitHub and blog content, and sends the combined string to the evaluator.
- **`evaluate_resume` returns an `EvaluationData` object** (defined in [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py)) that provides typed access to scores, bonuses, and deductions.
- **`print_evaluation_results`** consumes this object to generate human-readable output and CSV exports, completing the hiring agent workflow.

## Frequently Asked Questions

### What is the role of `ResumeEvaluator` in the hiring pipeline?

`ResumeEvaluator` acts as the LLM interface layer. It accepts plain-text resume content, constructs the appropriate prompt using templates from [`prompt.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompt.py), sends the request to the configured model, and returns a validated `EvaluationData` object. This abstraction allows [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) to remain agnostic about specific LLM providers or API formats.

### How does [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) handle optional GitHub and blog data?

The `_evaluate_resume` function accepts optional `github_data` and `blog_data` parameters. When present, these are converted to text using `convert_github_data_to_text` and `convert_blog_data_to_text` from [`transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/transform.py), then concatenated to the base resume text before evaluation. This enrichment happens at lines 72-76 in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py).

### What format does [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) return to the calling script?

[`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) returns an `EvaluationData` Pydantic model instance, not a raw dictionary or string. This model provides type-safe access to evaluation fields including `scores`, `bonus_points`, `deductions`, and `summary`, ensuring that [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) can reliably consume the structured data without additional parsing logic.

### Where is the evaluation output formatted for display?

Formatting occurs in the `print_evaluation_results` function within [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) (lines 26-38). This function receives the `EvaluationData` object from `main()`, extracts the relevant fields, and prints a formatted report to the console. The same data structure can also be serialized to CSV for further processing.