<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kartik Kumar</title>
    <description>The latest articles on DEV Community by Kartik Kumar (@geekykartik1).</description>
    <link>https://dev.to/geekykartik1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F99mvlsfu5tfj9m7ku25d.png</url>
      <title>DEV Community: Kartik Kumar</title>
      <link>https://dev.to/geekykartik1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geekykartik1"/>
    <language>en</language>
    <item>
      <title>I Built Resume Tailor: A Resume Rewriter That Runs Fully Offline on an Open-Weight Model</title>
      <dc:creator>Kartik Kumar</dc:creator>
      <pubDate>Sun, 18 Oct 2026 10:21:41 +0000</pubDate>
      <link>https://dev.to/geekykartik1/i-built-resume-tailor-a-resume-rewriter-that-runs-fully-offline-on-an-open-weight-model-3ohi</link>
      <guid>https://dev.to/geekykartik1/i-built-resume-tailor-a-resume-rewriter-that-runs-fully-offline-on-an-open-weight-model-3ohi</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

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

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Full source: &lt;a href="https://github.com/kumarkartik3977-netizen/Resume-Tailor" rel="noopener noreferrer"&gt;https://github.com/kumarkartik3977-netizen/Resume-Tailor&lt;/a&gt; — &lt;code&gt;app.py&lt;/code&gt; (Streamlit UI), &lt;code&gt;core.py&lt;/code&gt; (model calling, JSON extraction/validation, PDF and DOCX handling), &lt;code&gt;requirements.txt&lt;/code&gt;, &lt;code&gt;README.md&lt;/code&gt;, plus &lt;code&gt;sample_resume.txt&lt;/code&gt; and &lt;code&gt;sample_job_description.txt&lt;/code&gt; for the demo.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open-weight model&lt;/strong&gt;: &lt;code&gt;llama3.2:3b&lt;/code&gt; via Ollama, with an automatic fallback chain — &lt;code&gt;llama3.2:1b&lt;/code&gt;, &lt;code&gt;qwen2.5:3b&lt;/code&gt;, &lt;code&gt;qwen2.5:0.5b&lt;/code&gt; — so it degrades gracefully on low-RAM machines. Called through the &lt;code&gt;ollama&lt;/code&gt; Python package with a model selector in the UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI&lt;/strong&gt;: 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF parsing&lt;/strong&gt;: pypdf. &lt;strong&gt;Export&lt;/strong&gt;: python-docx for Word output (plus plain &lt;code&gt;.txt&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompting&lt;/strong&gt;: a strict system prompt forces the model to only rephrase/reorder real experience and return structured JSON (&lt;code&gt;tailored_resume&lt;/code&gt;, &lt;code&gt;match_score&lt;/code&gt;, &lt;code&gt;reasons&lt;/code&gt;, &lt;code&gt;missing_keywords&lt;/code&gt;) via Ollama's structured-output mode (&lt;code&gt;format=&lt;/code&gt; with a JSON schema), so the sampler is grammatically constrained to the exact shape - small models included.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt;: 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 &lt;code&gt;##&lt;/code&gt; 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Three things a closed API can't give you here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Privacy.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
