Skip to content
ahsan876 edited this page Apr 17, 2026 · 1 revision

Scoring & analysis

How reveilio scores resumes against job descriptions and what the result contains.


How scoring works

Reveilio performs resume extraction and scoring in a single LLM call. The prompt instructs the model to:

  1. Phase 1 — Extract structured data from the resume (name, skills, experience, education, certifications, career gaps).
  2. Phase 2 — Score the candidate against the JD using weighted criteria.

The model returns a single JSON document with both the extracted data and the analysis. This is faster and cheaper than two separate calls, and produces more coherent results because the model reasons about the raw text and scoring criteria simultaneously.


The seven scoring dimensions

Each dimension receives a score from 0 to 100, plus a written reasoning explaining the score. Weights are configurable via configure(weights=...).

Dimension Default weight What it measures
skills 20% Direct keyword match between JD required skills and resume skills.
semantic_skills 20% Conceptual overlap. A candidate who knows Flask may score well for a Django role because the underlying concepts overlap.
experience 25% Years of relevant experience, role progression, seniority alignment.
education 15% Degree relevance, institution prestige, academic achievements.
certifications 10% Professional certifications matching JD requirements.
soft_skills 5% Communication, leadership, teamwork, and other interpersonal skills.
domain_relevance 5% Industry-specific experience. A fintech role benefits from finance experience.

The AnalysisResult object

Every call to analyze_resume() or score() returns an AnalysisResult with these fields.

Core scores

Field Type Description
overall_score float 0 to 100 weighted composite score.
confidence_level string "High", "Medium", or "Low". How confident the model is in its assessment.
recommendation string "Shortlist", "Needs Review", or "Not Suitable".
detailed_scores dict Per-dimension breakdown. Each key maps to {"score": 85, "reasoning": "..."}.

Qualitative analysis

Field Type Description
ai_summary string Concise executive critique, ~120 words. Written as an objective assessment.
strengths list What the candidate does well relative to the JD. Concrete and specific.
weaknesses list Gaps between candidate and JD requirements.
career_flags list Concerns such as frequent job changes, unexplained gaps, or misaligned career trajectory.
reasoning list Step-by-step logic behind the overall score.
experience_analysis list Deep dive into how the candidate's work history aligns with the role.

Advanced metrics

Field Type Description
kpis list KPIs derived from the resume (e.g. "Led a team of 12", "Reduced latency by 40%").
relevancy_metrics list Metrics like "Average Tenure per Company" with value, relevancy level (high/medium/low), reasoning, criteria definitions.
suggested_roles list Alternative roles the candidate might be a better fit for, each with a match score.
suggested_questions list 3–5 role-aligned interview questions. Only populated when recommendation is "Shortlist". Empty for other outcomes.

Extracted candidate data

Field Description
candidate_data.name Candidate full name.
candidate_data.email Email address.
candidate_data.skills List of extracted skills.
candidate_data.experience List of positions with title, company, duration, description, location.
candidate_data.education List of degrees with institution, year, location.
candidate_data.total_experience Calculated total years of experience.
candidate_data.career_gaps Detected employment gaps.
candidate_data.filename Name of the source file.

Single resume analysis

result = reveilio.analyze_resume("resumes/alice.pdf", jd)

print(result.overall_score)                           # 82.0
print(result.recommendation)                          # "Shortlist"
print(result.detailed_scores["skills"]["score"])      # 90
print(result.detailed_scores["skills"]["reasoning"])  # "Strong match..."
print(result.ai_summary)                              # 120-word critique
print(result.suggested_questions)                     # interview Qs

Batch folder analysis

analyze_folder() processes every supported file in a directory, scores them in parallel using threads, sorts results by overall_score descending, and assigns a 1-based rank.

results = reveilio.analyze_folder(
    "./applicants",
    jd,
    extensions=(".pdf", ".docx"),  # optional filter
    max_workers=4,                 # parallel LLM calls
    recursive=True,                # include subfolders
)

for r in results:
    print(f"#{r.rank} {r.candidate_data.name} {r.overall_score}%")

Error handling

If the LLM call fails for a specific resume (network error, malformed response, etc.), the scorer catches the exception and returns a safe fallback result with:

  • overall_score = 0
  • confidence_level = "Low"
  • recommendation = "Needs Review"
  • The error message in ai_summary

A single bad resume in a 500-resume batch will not crash the entire run. Detect error results by checking the summary:

errors = [r for r in results if "Error" in (r.ai_summary or "")]
print(f"{len(errors)} resume(s) failed analysis")

Customizing weights

Pass a custom weights dictionary to configure() to change what the scorer optimizes for. Weights are embedded directly into the LLM prompt.

reveilio.configure(
    provider="openai",
    api_key="sk-...",
    weights={
        "skills": 0.35,            # heavy emphasis on skills
        "semantic_skills": 0.15,
        "experience": 0.25,
        "education": 0.05,         # de-emphasize education
        "certifications": 0.10,
        "soft_skills": 0.05,
        "domain_relevance": 0.05,
    },
)

Continue to PDF reports.

Clone this wiki locally