DEV Community

william freund
william freund

Posted on

I Stopped Opening the Spreadsheet: Asking 19,426 Job Posts One Lazy Sentence

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

DEV Hacktoberfest Week 3 — "Slow and Steady". Built this week, from scratch, with an open-weight model (Gemma 3 1B, running locally).

What I Built

The most boring week of my October

Every year, China's national civil-service exam (国考) publishes its position table: 19,426 rows of departments, quotas, majors, degree requirements, locations, and footnotes. To find posts I could actually apply for, I spent a week scrolling, Excel-filtering, and re-checking constraints — degree, major, English certificates, party membership, grassroots experience, "remote western region" postings.

With my AI assistant's help I got it down to 23 genuinely eligible posts. And then I noticed something: every remaining question I had was a one-liner.

英语专业,不要四六级,招3人以上,太原的岗
English major, no CET-4/6 requirement, 3+ openings, in Taiyuan

招4个人的税务局岗
Tax bureau posts hiring 4 people

提供宿舍的岗
Posts that provide a dormitory

Each of those used to mean: open the spreadsheet, remember which column holds what, apply three filters, squint. So I built the laziest possible interface: type one sentence, get a ranked shortlist.

Demo

Meet CouchFilter 🛋️

$ python couchfilter_cli.py "英语专业,不要四六级,招3人以上,太原的岗"

问:英语专业,不要四六级,招3人以上,太原的岗
(Gemma 本地解析)

命中 1 个岗(按招考人数排序):
1. [300110021004] 国家税务总局清徐县税务局|一级行政执法员(四)|招 3 人
   地点:山西省太原市清徐县|备注:男性,在本单位最低服务年限为5年
Enter fullscreen mode Exit fullscreen mode

Or open the tiny web UI and ask from the couch:

python serve.py → http://127.0.0.1:8000 — one input box, one button, ranked cards.

Code

Repo: https://github.com/986036734/couchfilter

How I Built It

How it works (and where the model earns its keep)

The pipeline is deliberately split in two:

  1. Fuzzy part → Gemma 3 1B (open weights), running locally via Ollama.
    It turns one Chinese sentence into structured filters — a JSON object with location, minimum headcount, major, excluded terms, dormitory requirement, degree. Nothing leaves the machine; the position table never touches a cloud API.

  2. Exact part → plain Python.
    Filters are applied deterministically over the spreadsheet, so every result is reproducible and every rejection comes with a reason ("只招 2 人(要 ≥3)", "备注未写提供宿舍").

Why the split? A 1B model is great at understanding "招3人以上" means min_headcount: 3, but I don't want it deciding my career shortlist from vibes. The model translates; the code filters. If Ollama is down, a rule-based parser takes over and says so honestly.

Ranking is laziness-first: more openings first (better odds per application), then everything else.

Total new code: ~400 lines. Dependencies: openpyxl, requests, and a local model. The web UI is Python stdlib only.

Try it on your own table:

pip install -r requirements.txt
ollama pull gemma3:1b
python couchfilter_cli.py "你的问题" --table your-positions.xlsx
Enter fullscreen mode Exit fullscreen mode

Any 国考-style table works if the column layout matches (the C_* constants in couchfilter.py are the whole schema).

Why Does Open Innovation Matter?

CouchFilter is built around an open-weight model, Gemma 3 1B, running locally via Ollama. Because the model runs locally, nothing leaves the machine and the position table never touches a cloud API. The model does the fuzzy language part, and deterministic code does the filtering, so every result is reproducible and every rejection comes with a reason. If Ollama is down, a rule-based parser takes over and says so honestly.

The Lazy Payoff

The "slow and steady" philosophy

The theme this week is rewarding laziness, and I took it literally. The laziest query wins: no column names to memorize, no filter dialogs, no "wait, which sheet was it". The tool even tells you what it excluded and why, so you can loosen one constraint instead of starting over.

Prize Categories

  • Best Use of Gemma

Built 2026-10-24 for DEV Hacktoberfest Week 3. The 23-post shortlist is public recruitment data; the week of manual screening that produced it is a story for another post.

Top comments (0)