lazy-tidy 用本機 Gemma 3 4B 離線整理下載資料夾
I Taught a Local Gemma to Clean My Downloads Folder, Offline
Naeem Ahmed 編寫 Python 工具 lazy-tidy,以副檔名查表及本機 Gemma 3 4B 分類下載資料夾中的檔案,並可離線執行。示範中,18 個檔案有 12 個由副檔名規則分類、6 個交由模型處理,在 M1 Pro 上約 4 秒完成;預設只預覽,使用 --apply 才會移動檔案。
What I Built
My Downloads folder is a landfill. IMG_4821.heic, final_v3.docx, a LICENSE with no context, installers from months ago. Every few weeks I promise myself I'll sort it, and every few weeks I don't.
So I built lazy-tidy: a tiny Python script that sorts a messy folder into Documents, Images, Videos, Audio, Code, Archives, Installers and Other. It previews by default and only moves files when I pass --apply.
The "slow and steady" part: it uses the cheapest decision-maker first. Known extensions are sorted instantly with a lookup table. Only files the table can't place (Makefile, README, data.bin, photo.raw) are handed to a local open-weight model, Gemma 3 4B running through Ollama on my laptop.
Code: https://github.com/naeemahmedpnl/lazy-tidy
Demo
Before, a folder with 18 mixed files:
Preview first, and every line shows who made the decision, [extension] or [model]:
$ python tidy.py ~/tidy-demo
IMG_4821.heic -> Images/ [extension]
LICENSE -> Documents/ [model]
Makefile -> Code/ [model]
README -> Documents/ [model]
data.bin -> Archives/ [model]
photo.raw -> Images/ [model]
...
Done: 12 by extension, 6 by local model.
Preview only. Re-run with --apply to move files.
After --apply:
How It Works
- Extension first. A dictionary maps common extensions to categories. It is instant, free, and never wrong. In my demo it handled 12 of 18 files without touching a model.
- Local model for the leftovers. Anything unknown goes to Gemma 3 4B via Ollama with a prompt that asks for JSON only:
r = ollama.chat(
model="gemma3:4b",
messages=[{"role": "user", "content": prompt}],
format="json",
)
cat = json.loads(r["message"]["content"]).get("category", "Other")
return cat if cat in CATEGORIES else "Other"
-
Guardrails. If the model returns something invalid or the call fails, the file goes to
Other. If a name already exists in the destination, the file gets a_dupsuffix instead of being overwritten. Nothing moves unless I pass--apply.
Why Open Innovation Mattered Here
It works with no internet. I turned Wi-Fi off and proved it with a failing ping before running the script:
$ ping -c 2 google.com
ping: cannot resolve google.com: Unknown host
$ time python tidy.py ~/tidy-offline
...
Done: 6 by extension, 6 by local model.
python tidy.py ~/tidy-offline 4.067 total
Twelve files, six of them classified by the model, in about 4 seconds on an M1 Pro, fully offline.
My file names stay on my machine. Downloads contains invoices, resumes and personal photos. Even with just file names, that is information I would rather not send to a server I don't control, just to decide that LICENSE is a document.
It costs nothing. No API key, no per-call billing, no rate limits. I can run it on a schedule forever.
It is swappable. The model is one line, MODEL = "gemma3:4b". Changing to another open model is a one-line edit, and I can compare how different models handle the awkward files.
A closed API would have worked for this task too. But for something that touches the contents of my personal folders and should run quietly in the background, running it locally was the better fit, not just a nice-to-have.
Honest Limitations
-
The model only sees file names, never contents. My test files were empty
touchfiles, so this was purely name-based. -
It makes mistakes.
data.binwent toArchives, andOtherwould have been the better answer. It made the same choice in both runs. -
The small model is a guess on ambiguous names.
READMEandnotes_2026landing inDocumentsis reasonable, but it is a guess. - No undo. That is exactly why preview is the default. Only top-level files are handled, not subfolders.
What's Next
Read a short text snippet for ambiguous files, add an undo log, and run it on a schedule so the folder never gets bad again.
The Lazy Payoff
One command, a few seconds, no internet, and a folder I had ignored for months is tidy. Do the work once, then let the sloth handle it.
來源:DEV Community · dev.to


