跳到正文
DEV Community· bayuh85·· 3 小時前AI 評分52

applyfit 可離線評分職位招聘廣告,並按個人檔案草擬履歷

applyfit: score job postings offline and draft a tailored CV from your own files

AI 導讀

applyfit 是一款 MIT 授權的 Python 求職工具,可在毋須 API key 或網絡連線的情況下,按職位要求、技能及偏好為招聘廣告評分,分數介乎 0 至 100。

正文

Repo: 👉 github.com/bayuh85/applyfit (MIT, Python 3.10+, 32 tests)

The problem

Job hunting as a developer usually looks like this: twenty browser tabs of postings, one "master CV" you keep rewriting by hand, and a chat window where you paste your entire work history again for every single cover letter. Two weeks later you can't remember which version you sent to whom, or why you even applied to that on-site contract that pays under your floor.

The expensive part isn't writing. It's deciding which postings are worth writing for, and keeping a record of what you sent.

What applyfit does

applyfit keeps the profile, the posting, the fit score, and the drafts as plain files on your machine. One folder per application. A model is called only when you ask for one.

The loop:

  1. add a posting from a file or a URL.
  2. score it from 0 to 100: must-haves met and missing, nice-to-haves, red flags, deal-breakers.
  3. tailor a CV that reorders your existing bullets and names the gaps.
  4. letter a short cover letter.
  5. prep an interview sheet: likely questions, STAR prompts tied to real bullets, and questions to ask them.
  6. board a status table (saved, applied, interview, offer, rejected).

The score needs no API key and no network. It's a deterministic keyword-overlap baseline: requirement bullets are checked against your skills (and their aliases) and the words in your profile, then mixed with salary, remote, and deal-breaker rules. If one of your deal-breakers shows up in the posting, the score is capped at 25.

A real run: two postings, one worth your evening

The repo ships a sample profile (Rowan, a backend engineer with 8 years of Python, Kubernetes, Postgres, AWS) and two sample postings. Here's what happens when you score both.

applyfit init --profile examples/profile.yaml
applyfit add examples/postings/northline-platform.md
applyfit add examples/postings/bramble-mobile.md
applyfit score northline-platform
applyfit score bramble-mobile

Northline Systems, Platform Engineer:

northline-platform  90/100  offline
Platform Engineer — Northline Systems

must-haves       5/5 met
nice-to-haves    1/2 met
keyword overlap  0.73
preferences      1.00

missing nice-to-haves
  - Istio or another service mesh

90/100 offline. 5 of 5 must-haves appear in the profile. Keyword overlap is 0.73.

Bramble & Co, Mobile Product Lead:

bramble-mobile  6/100  offline
Mobile Product Lead — Bramble & Co

must-haves       0/4 met
keyword overlap  0.00
preferences      0.60

deal-breakers
  - preference deal-breaker present: unpaid trial
  - preference deal-breaker present: security clearance
  - preference deal-breaker present: 24/7 on-call
  - posting is on-site and your profile requires remote work
  - posted salary tops out at 95000 USD, under your floor of 150000 USD

red flags
  - preference red flag present: relocation required
  - posted employment 'Contract' is outside the kinds you listed

90 vs 6. That took zero tokens and about a second. You now know where your evening goes: Northline. The only gap to address is the service mesh, and you know that before writing a single line.

applyfit board
id                  status  score  company            title
------------------  ------  -----  -----------------  -------------------
bramble-mobile      saved   6      Bramble & Co       Mobile Product Lead
northline-platform  saved   90     Northline Systems  Platform Engineer

Drafting the tailored CV

Now spend tokens, only on the posting that earned them:

applyfit tailor northline-platform

The prompt tells the model to never invent experience and to flag gaps instead. It reorders your real bullets and skills so the ones matching the posting come first. Even with --offline (no key) you get a draft that only copies and reorders facts already in your profile:

# Rowan Hale
**Backend engineer focused on reliable data-plane services**

## Skills

Closest to this posting:

- Python (expert, 8 years)
- Kubernetes (strong, 4 years) also k8s
- PostgreSQL (strong, 6 years) also postgres
- AWS (strong, 5 years) also amazon web services
- Distributed systems (strong, 6 years)
- Terraform (familiar, 2 years)

Then finish the application and mark it:

applyfit letter northline-platform
applyfit prep northline-platform
applyfit status northline-platform applied

Everything lands in one folder you can diff:

.applyfit/applications/northline-platform/
  posting.md  record.json  score.md  score.json  cv.md  letter.md  prep.md

Each model call prints a cost line on stderr (tokens in, tokens out, estimated dollars), and record.json stores the token counts of every call. The API key is never written to disk.

Install

git clone https://github.com/bayuh85/applyfit
cd applyfit
python -m venv .venv && source .venv/bin/activate
pip install -e .

To use a model, copy the env file and set a key:

cp .env.example .env
# edit ATMOROUTER_API_KEY
applyfit score northline-platform --llm   # model second opinion, offline baseline printed beside it

applyfit config prints the resolved base URL, API style, model, and a masked key.

Use it from Claude Code or Cursor (MCP)

applyfit mcp speaks MCP over stdio. Tools: add_job, score_job, tailor_cv, draft_letter, prep_interview, list_applications, set_status, show_profile.

{
  "mcpServers": {
    "applyfit": {
      "command": "applyfit",
      "args": ["mcp"],
      "env": {
        "APPLYFIT_HOME": "/absolute/path/to/.applyfit",
        "ATMOROUTER_API_KEY": "ar-your-key-here",
        "APPLYFIT_MODEL": "atmo/deepseek-v4.1-flash"
      }
    }
  }
}

Point APPLYFIT_HOME at the same workspace you use from the terminal, and your agent and your shell share one board. "Score the three postings I saved today and draft a CV for the best one" becomes a single request.

Why it runs on AtmoRouter

A job search is a pile of short calls: one score, one CV, one letter, one prep sheet, then the same four again for the next posting. That's exactly the pattern where a monthly seat makes no sense and pay-per-token does.

applyfit's default provider is AtmoRouter, a cheap AI API gateway and OpenRouter alternative: 109 models behind one OpenAI/Anthropic-compatible key, pay per token, on average 83.7% below official prices. The base is https://atmorouter.dev/v1; set APPLYFIT_API_STYLE=anthropic and the same client calls the Messages API at https://atmorouter.dev/v1/messages. The default model is atmo/deepseek-v4.1-flash, which is more than enough for reordering bullets and writing a three-paragraph letter.

Base URL, key, and model are all overridable, so any OpenAI-compatible endpoint works too.

Privacy

Profile, postings, scores, and drafts stay in the workspace directory. Offline score, tailor, letter, and prep never open a network connection. LLM commands send only the profile fact sheet and the posting text to whatever host APPLYFIT_BASE_URL names. No account, no telemetry.


If it saves you one evening of rewriting a CV for a job you'd never take, a ⭐ on the repo helps. Issues and PRs welcome.

來源:DEV Community · dev.to