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

The hiring-agent.py script consumes structured evaluation data by instantiating the ResumeEvaluator class from 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 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 (the hiring agent implementation) and evaluator.py follows a predictable pipeline that converts raw resume data into actionable scores.

Step 1: Instantiating the ResumeEvaluator

Inside score.py, the private helper _evaluate_resume begins by creating an instance of the ResumeEvaluator class defined in 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.


# 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) optionally enriches the resume with GitHub repository data and blog content using helper functions from transform.py. The resulting string contains the complete candidate profile formatted for the LLM prompt.

    # 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). The evaluator extracts a JSON blob from the LLM response and validates it against the EvaluationData Pydantic schema defined in models.py. This returns a strongly-typed object containing structured fields rather than raw text.

    # 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, 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.


# 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

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:

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 and hiring-agent.py is enforced by the EvaluationData Pydantic model located in 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 can safely access evaluation results without parsing raw JSON or handling ambiguous LLM responses.

Summary

  • score.py imports ResumeEvaluator from 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) 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, sends the request to the configured model, and returns a validated EvaluationData object. This abstraction allows score.py to remain agnostic about specific LLM providers or API formats.

How does 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, then concatenated to the base resume text before evaluation. This enrichment happens at lines 72-76 in score.py.

What format does evaluator.py return to the calling script?

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 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 (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.

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 →