Skip to content

Feature Request: Generate a revamped resume from the extracted data after scoring #383

Description

@Uknowme-h

Problem / Motivation

The pipeline currently ends at a scorecard: per-category scores, evidence, bonus points, deductions, key strengths, and areas_for_improvement. It tells a candidate what is weak but never produces an actionable output — there is no way to get a concrete, improved version of their resume out of the tool.

As it stands a candidate must manually translate "Open Source: 8/35 — personal repos don't count" into better bullet points themselves. This request adds a final pipeline stage that generates a revamped resume (same structure and section format as the original) by rewriting weak sections into stronger, rubric-aligned content.

Expected behavior

After the evaluation results are printed, a new CLI flag (e.g. --rewrite) runs a rewrite stage that:

  1. Takes the already-extracted, validated JSONResume data (never the raw PDF text) plus the role rubric and the evaluation output as input.
  2. Rewrites each editable section (basics summary, work highlights, project description/highlights, skills keyword ordering) to better match what the role's rubric rewards — quantified achievements, technical skill visibility, surfaced links, achievement-over-duties language.
  3. Never changes factual data: name, contact info, dates, company/institution names, URLs, education, and certificates are preserved exactly.
  4. Emits a revamped JSONResume (same JSON Resume schema, validated by the existing JSONResume model), written to resume_revamped_<basename>.json, plus an optional Markdown render.
  5. Optionally re-scores the revamped resume and prints a before/after delta so the improvement is measurable.

Proposed solution

Mirror the existing per-section extraction architecture rather than inventing a new one:

  • New module rewriter.py with a ResumeRewriter class that follows the exact pattern of ResumeEvaluator (evaluator.py): uses TemplateManager, initialize_llm_provider, and structured output via format=model.model_json_schema().
  • New templates prompts/templates/resume_rewrite.jinja (and a rewrite system message), consistent with the existing per-section Jinja templates in prompts/templates/.
  • Section-by-section rewrite calls, one per editable section, each receiving (section data, role rubric from roles/<role>/role.json, and the evaluation's areas_for_improvement / deductions). Small prompts reduce hallucination and token cost — same reasoning that already drives per-section extraction in pdf.py.
  • Protected vs editable fields enforced in Python after the LLM call: a deterministic post-processor restores any drift on immutable fields (name, dates, URLs, etc.). The LLM only writes prose; Python enforces facts.
  • Grounding: rewrites are driven by the structured JSONResume and the role's criteria.jinja rubric. No metrics are fabricated — quantifiable results are only retained/emphasized when present in the source (e.g. GitHub stars, project counts); otherwise bullets stay honest.
  • Determinism controls: low temperature (0.1–0.3) for rewrite calls, JSON-schema structured output.
  • CLI wiring: --rewrite flag in score.py, default off so existing behavior is unchanged.

Why this approach (vs. alternatives)

  • Rewrite from raw PDF text in one giant LLM call. Rejected: high hallucination risk, no schema guarantee, and it re-does work the pipeline already did. This repo already extracted clean, validated JSON — reusing it grounds the rewrite and prevents the model from inventing facts.
  • Ask the LLM to both rewrite and fact-check itself. Rejected as the primary mechanism: self-verification is weak for this; a deterministic Python guard on protected fields is stronger and free. (An optional LLM-as-judge pass could be a follow-up.)
  • Only print improvement suggestions (no output resume). That's the scope of Feature: explain why each section got its score and how to improve it (rubric-based, no extra LLM call) #246; this issue is the actual deliverable — a usable revamped resume.

Scope / non-goals for the first cut

  • PDF rendering of the revamped resume (would require a LaTeX/HTML engine) — deferred.
  • Interactive / web UI — deferred.
  • The rewriter only improves existing content; it does not add experiences, projects, or skills the candidate never listed.

Additional context

  • References Feature: explain why each section got its score and how to improve it (rubric-based, no extra LLM call) #246 (rubric-based improvement explanations) — this feature consumes its output as input.
  • Design informed by ResumeFlow (arXiv 2402.06221), an LLM pipeline that extracts structured resume JSON, rewrites section-by-section, and preserves personal details untouched.
  • Testing per CONTRIBUTING.md: smoke test with a cached resume JSON asserting (a) JSONResume validates, (b) all protected fields are byte-identical to the source; plus real runs under Ollama (default local model) and Gemini with before/after score comparison.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions