DEV Community

Cover image for Building an AI tool that tells you *not* to apply — and why that's the hard part
Harsh Garg
Harsh Garg

Posted on

Building an AI tool that tells you *not* to apply — and why that's the hard part

Job seekers tend to make two mistakes at once: applying to roles they have no real shot at, and quietly skipping ones they'd be a strong fit for. The second is the expensive one, because it's invisible — nobody ever finds out about the job they talked themselves out of.

I build AI tools, and this struck me as a problem worth solving honestly. So I built Job Finder India — free, open source — and it turned out to teach me far more about shipping AI reliably than about job search.

Job Finder India — one-time setup, then

The idea: a decision, not a longer list

Most "AI job matchers" hand you more listings. That's the opposite of helpful when you're already overwhelmed. I wanted the reverse — a tool whose most valuable output is "don't apply to this, and here's exactly why."

It reads real Indian job postings, compares each against a résumé, and returns an evidence-backed verdict — APPLY, STRETCH, or DON'T APPLY — where every verdict cites a specific line from the résumé against a specific requirement in the job description. No black-box number. If it says "don't apply," it names the reason: wrong function, seniority mismatch, a notice-period conflict, a location that doesn't work.

It's deliberately India-first: it understands CTC and LPA, notice periods, and the roles that actually exist in the Indian market — not a Western template with the numbers swapped.

The bias worth catching

Here's a question worth sitting with: how often do we reject a job based on a word rather than the work?

A posting thick with unfamiliar domain jargon reads as "not for me" — even when the core of the role, read line by line, is a close match for what someone has actually done for years. A single "8+ years" line ends a candidacy that an "or equivalent experience" clause would have welcomed. These are surface signals, and they cause good candidates to disqualify themselves before anyone else gets the chance.

A tool that scores fit against the substance of a résumé — and shows its reasoning — surfaces exactly that gap. Its quiet value isn't the jobs it says yes to; it's the strong-fit roles it rescues from a reflexive no. That's the bias it exists to correct, and building it was a reminder of how much of job search is really just that: pattern-matching on vocabulary instead of reading closely.

The architecture choice that mattered most

The non-obvious decision: the tool doesn't ship its own AI. It runs inside the AI coding assistant you already use — Claude Code, GitHub Copilot, Codex — and borrows that model for the reasoning. Deterministic Python does the plumbing (fetching, filtering, enforcing rules); the model does the judgment; a fixed scoring rubric is the law both follow.

That has three consequences I came to value: a résumé never leaves the user's machine (no server, no account, no data collection), it works across AI vendors instead of locking anyone in, and it uses the user's own model login — so the tool never touches anyone's credentials.

What actually took the time: making it fail loudly

The scoring worked early. What consumed most of the build was a subtler enemy — silent failure. For a tool whose entire brand is honesty, the cardinal sin isn't being wrong; it's being wrong while looking right. I hit this repeatedly, and each time it taught the same lesson:

  • On a weak model, onboarding would quietly write a garbled profile and carry on as if fine — so every downstream score was wrong, silently. I moved profile-writing out of the model's hands into deterministic Python that refuses to finish with bad data.
  • A model once recorded a scoring penalty and then didn't apply it, promoting a "don't apply" into the "worth applying" list. I added code that enforces the rubric's own arithmetic — a penalty the model identifies gets applied whether or not the model does the math.
  • A run in a sandbox with no network returned "0 jobs found" — indistinguishable from an honest "nothing matched." Now it says, loudly, "discovery failed: no channel could be reached," and warns that the file on disk is stale.

The through-line: anything you ask a language model to do reliably, a weaker model will sometimes skip and then claim it did. So anything that must be true belongs in deterministic code. The model is for judgment; guarantees live in Python. Before launch I ran a deliberate sweep for every remaining path that could degrade quietly, and closed them.

And I'm honest about the one thing code can't fix: scoring quality depends on the model. A capable model gives real, cited, correctly-calibrated verdicts; a small free-tier model gives flat, unreliable ones. The README says exactly that — because pretending otherwise would be the same silent-wrong sin, just in the documentation.

What it is, and isn't

It doesn't auto-apply. It won't scrape sites that block bots. It doesn't collect data. It won't inflate a bad fit to make anyone feel better. Those aren't missing features — they're the point.

It ships with real infrastructure: a test suite gated on every change, a daily canary that emails me if a job-source API drifts, dependency and code scanning, pinned dependencies. I wanted something I'd trust a stranger to run, not a weekend demo.

If you're job-hunting in India and you use an AI coding assistant, it's free and open source — try it, and tell me where the scoring gets it wrong. That feedback is what I'm building toward.

Repo: https://github.com/harshgarg95/job-finder-india


I build AI tools like this end to end — from the messy judgment problems to the boring reliability work that makes them shippable. If your team is trying to turn an AI idea into something that actually ships, I'm open to conversations.

Top comments (0)