DEV Community

Kartik Kumar
Kartik Kumar

Posted on

I Built Resume Tailor: A Resume Rewriter That Runs Fully Offline on an Open-Weight Model

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

Resume Tailor — a local-first web app that rewrites your resume to match a job description using a local open-weight model (Ollama + llama3.2:3b).

Who would pay for it: job seekers, career changers, and freelance recruiters. Tailoring a resume by hand for each application takes 30–60 minutes and people still miss keywords that ATS filters care about. Resume Tailor does it in seconds, offline, for free — and it never invents experience you don't have.

Demo

Paste sample_resume.txt and sample_job_description.txt into the two boxes, click Tailor my resume, and you get back an ATS-friendly resume, a match score out of 100 with 3 reasons, and the missing keywords — downloadable as .docx or .txt.

Code

Full source: https://github.com/kumarkartik3977-netizen/Resume-Tailor — app.py (Streamlit UI), core.py (model calling, JSON extraction/validation, PDF and DOCX handling), requirements.txt, README.md, plus sample_resume.txt and sample_job_description.txt for the demo.

How I Built It

  • Open-weight model: llama3.2:3b via Ollama, with an automatic fallback chain — llama3.2:1b, qwen2.5:3b, qwen2.5:0.5b — so it degrades gracefully on low-RAM machines. Called through the ollama Python package with a model selector in the UI.
  • UI: Streamlit — paste or upload a PDF resume on the left, paste the job description on the right, get the tailored resume, match score, reasons, and missing keywords back.
  • PDF parsing: pypdf. Export: python-docx for Word output (plus plain .txt).
  • Prompting: a strict system prompt forces the model to only rephrase/reorder real experience and return structured JSON (tailored_resume, match_score, reasons, missing_keywords) via Ollama's structured-output mode (format= with a JSON schema), so the sampler is grammatically constrained to the exact shape - small models included.
  • Reliability: output is validated (length checks against the original resume, ATS-section and JSON-shape checks, type checks on every field) and normalized (score clamped 0-100, reasons capped at 3, placeholder values dropped, stray ## prefixes cleaned up). Malformed output triggers one retry at higher temperature, then falls back through the model chain before giving up with a clear error.

Why Does Open Innovation Matter?

Three things a closed API can't give you here:

  1. Privacy. Resumes are full of PII — phone numbers, addresses, employment history. Running llama3.2:3b locally means that data never leaves the laptop. For a tool people use while employed and job-hunting secretly, this isn't a nice-to-have, it's the product.
  2. Cost. A career-changer applying to 50 roles would pay real money per call on a hosted model. Local inference makes the marginal cost zero, which is what makes this viable as a side-hustle product for individuals, not enterprises.
  3. Control. Open weights let you swap models (the app has a model selector built in), tune temperature, and eventually fine-tune on a niche resume format — all without being locked into someone else's pricing or rate limits.

My Agent Session

My First User

Prize Categories

Top comments (0)