How hiring-agent.py Stores and Reports Submission Results: A Complete Guide

hiring-agent.py returns evaluation results as a structured JSON object to both STDOUT and the caller, without persisting data to disk by default.

The interviewstreet/hiring-agent repository provides a resume evaluation workflow that processes PDF submissions through an AI pipeline. Understanding how submission results are stored or reported by hiring-agent.py is critical for developers integrating this tool into automated hiring workflows or custom dashboards.

The Three-Step Evaluation Pipeline

The entry-point script orchestrates a linear pipeline across three core modules. Each stage handles a specific transformation of the submission data, with the final stage determining how results are exposed to the user.

Step 1: Resume Text Extraction via pdf.py

The pipeline begins in pdf.py, where the extract_text_from_pdf function parses the uploaded PDF and extracts raw text content. This text serves as the input for the AI evaluation stage.

Step 2: AI Evaluation via evaluator.py and llm_utils.py

The extracted text is passed to evaluator.py, specifically to the Evaluator.evaluate_resume method. This function constructs the prompt and delegates the LLM interaction to llm_utils.py. The language model returns a structured JSON payload containing scores, categories, and textual feedback.

Step 3: Result Formatting and Output via score.py

The JSON payload flows into score.py, which acts as the primary result handler. The print_evaluation_results function formats the data into a human-readable table for STDOUT, while the main function returns the raw JSON object to the caller. This dual-output approach ensures visibility for manual review and programmability for automation.

Where Submission Results Are Stored

By default, hiring-agent.py does not write evaluation results to a permanent file. The results exist only in memory during execution and are handled in two ways:

  1. Returned to the caller – The main function in score.py returns the Python dictionary (parsed from the LLM JSON) to the calling code.
  2. Printed to STDOUT – The formatted table output provides immediate visual feedback in the terminal.

The repository does include a caching mechanism, but it targets the input data, not the results. The cache/resumecache_*.json files store extracted PDF text to speed up re-runs, leaving evaluation results ephemeral unless explicitly captured by the user.

How to Capture and Persist Results

Developers can persist submission results by intercepting the returned JSON or redirecting STDOUT. Below are the three primary patterns for handling output.

Command-Line Usage

When running the script directly from the terminal, output flows to STDOUT:

python hiring-agent.py path/to/resume.pdf

To save these results, redirect the output to a file:

python hiring-agent.py path/to/resume.pdf > evaluation_results.txt

Programmatic Usage

For integration with Python applications, import the score module and capture the return value:

from hiring_agent import score

# Execute evaluation and capture the JSON result

result = score.main("resume.pdf")

# The returned object is a dictionary with structured data

print(result["overall_score"])

Persisting Results to JSON

To store results permanently, serialize the returned dictionary using the standard library:

import json
import pathlib
from hiring_agent import score

# Run evaluation

result = score.main("resume.pdf")

# Write to disk

pathlib.Path("evaluation.json").write_text(
    json.dumps(result, indent=2)
)

The JSON structure contains the following fields:

{
  "overall_score": 8.2,
  "categories": {
    "experience": 9,
    "education": 7,
    "projects": 8
  },
  "feedback": "Strong experience in data engineering..."
}

Key Source Files and Their Roles

The handling of submission results spans four critical files in the repository:

  • score.py – Entry point that calls the evaluator, prints formatted results via print_evaluation_results, and returns the JSON payload to the caller.
  • evaluator.py – Wraps the LLM call and constructs the structured evaluation dictionary containing scores and feedback.
  • pdf.py – Handles raw text extraction from PDF submissions to prepare data for analysis.
  • llm_utils.py – Manages API communication with the language model and prompt construction.

Summary

  • Default behavior: hiring-agent.py returns results as a JSON object and prints a formatted table to STDOUT, without writing to disk.
  • No built-in persistence: Evaluation results are not cached or stored permanently; only extracted PDF text is cached in cache/resumecache_*.json.
  • Capture methods: Redirect STDOUT for CLI usage, or capture the return value of score.main() for programmatic access.
  • Result structure: The JSON payload includes overall_score, category-specific scores, and textual feedback.

Frequently Asked Questions

Does hiring-agent.py save results to a database?

No, the script does not implement database persistence. According to the interviewstreet/hiring-agent source code, results are kept in memory and emitted via STDOUT and return values. Database integration would require extending score.py to add a storage layer.

What is the exact JSON structure returned by the evaluation?

The JSON object returned by score.main() contains three top-level keys: overall_score (float), categories (dictionary of string keys with integer scores), and feedback (string containing textual analysis). This structure is generated by Evaluator.evaluate_resume in evaluator.py and parsed from the LLM response.

How can I automate result collection in a CI/CD pipeline?

Capture the JSON return value programmatically rather than relying on STDOUT parsing. Import score from the hiring_agent package, call score.main(pdf_path), and serialize the result to your artifact storage system. This approach is more reliable than parsing the formatted table output.

Is there any caching of evaluation results?

No, the caching layer only stores extracted PDF text in cache/resumecache_*.json files to avoid re-parsing documents. Evaluation results are recomputed on every run and must be captured manually if persistence is required.

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 →