Requiem:為已崩潰程式撰寫悼詞的崩潰回報工具
Requiem: a crash reporter that writes a eulogy for the program that died
Requiem 是一款本機崩潰回報工具,會擷取程式的退出狀況、分析錯誤,並撰寫第一人稱悼詞。它使用 Gemma 3 1B 在本機推理,並在模型處理資料前遮蔽機密資訊。模型未運行時,工具會改為生成確定性悼詞,並將悼詞儲存至本機 JSONL。
This is a submission for the MLH x DEV Writing Challenge
What I Built
Every crash gets a funeral.
Requiem is a small tool you wrap around any command. When the program dies, Requiem does not just print a traceback and move on. It captures how the process died, works out what killed it, and then writes an obituary in the first person, as if the program were speaking at its own funeral.
The idea came from a bad habit we all have. Something crashes in production, we copy the stack trace into a chat window, and a few seconds later a cloud model explains the error back to us. Convenient, until you remember what is actually inside a traceback: file paths, hostnames, SQL, auth headers, customer names, and sometimes a token someone left in an environment variable. That is a lot of context to hand to a stranger.
So Requiem keeps the whole thing on your machine. It runs inference locally with an open-weight model, and before the model sees anything, a coroner pass strips the secrets out.
It works in four steps:
- Capture. Run the command under Requiem and record the exit code, the signal, stderr, stdout, and how long it took.
- Coroner. Parse the traceback, map the signal, read the exact failing line from your source, and redact tokens, keys, emails, home paths and IP addresses.
- Ghost. A local Gemma 3 1B server writes a first-person eulogy and a short diagnosis. If the model is not running, a deterministic obituary is generated instead, so the tool never depends on the network.
- Bury. The obituary goes into a local JSONL graveyard, and a card is printed to your terminal.
The part I am happiest with is the split of work. Code does what code is good at: parsing, redaction, signal mapping, file reads. The model does the one thing code is bad at, which is voice. Both halves are replaceable. Swap the GGUF for any other model. Change the prompt. Read the 400 lines of standard library Python and know exactly what happened.
Demo
There is no video yet, mostly because the demo is a terminal and the whole thing is more fun to read than to watch. Here is the real output from a demo crash:
┌─ REQUIEM ──────────────────────────────────────────────────┐
│ requiem-8f3a21 python3 examples/lost_config.py 112ms │
│ died of KeyError: 'user_id' │
├─────────────────────────────────────────────────────────────┤
│ WHERE │
│ examples/lost_config.py:14 in load_user │
│ return config["users"][user_id] │
│ CAUSE │
│ KeyError: 'user_id' - looked up a missing key in a dict. │
│ FIX │
│ Validate input or use .get() with a default. │
│ EULOGY │
│ I was only ever asked for keys I had. I never learned to │
│ say no, and now I say nothing. │
│ redacted:0 │
└─────────────────────────────────────────────────────────────┘
Try it yourself:
make llama # start the local model
PYTHONPATH=. python3 -m requiem run -- <command>
PYTHONPATH=. python3 -m requiem list
PYTHONPATH=. python3 -m requiem show requiem-xxxxxx
Add --no-model and it skips the ghost entirely and prints a deterministic obituary, which is useful on a plane or in CI.
The repo is github.com/mukuvi/requiem, MIT licensed. The original write-up for the challenge week is here.
Partner Technologies
I did not use a partner API in this project, and that was the point rather than an accident.
The thing Requiem processes is the most sensitive file a developer owns, and the entire reason it exists is that uploading a crash log to a third party is a bad trade. Adding a cloud call would have made the demo easier and the product pointless.
What it does use is Gemma 3 1B, an open-weight model, served locally through llama.cpp. That choice gave me two things a hosted API could not. First, the eulogy never leaves 127.0.0.1. Second, the model is a file. You can swap it for a different GGUF, run it on a weak laptop, or delete it and keep the deterministic path.
Working with a 1B model also forced better engineering. Small models do not forgive a vague prompt. I had to hand the ghost a structured cause and a clean failing line instead of dumping raw stderr at it, which turned out to be the same discipline that made the redaction pass work. The constraint made the tool simpler, not worse.
Hackathon Experience
I built this during Hacktoberfest 2026, the month that MLH and DEV run together, and I checked into Global Hack Week: Hacktoberfest in the middle of it.
This year was the first one without a pull request target, which sounds like a small rule change and quietly changes the whole month. Without a counter to hit, the only thing left to do is build something you actually want to exist. I ended up making four small tools across October, one for each weekly prompt, all local and all open source. Requiem was the last one, for the Ghost in the Machine week, and it is the one I would keep.
What I will remember is the rhythm more than a single moment. A new prompt on Monday, a working prototype by the weekend, and a room full of people on the other side of a Discord channel doing the same thing in their own timezone. Building in Nairobi means the livestreams land late, so most of my work happened between eleven at night and two in the morning, with a terminal on one side of the screen and the community feed on the other.
The other thing I will remember is how much a deadline the size of a week improves a design. Requiem exists in the shape it does because I had six days and no appetite for a framework. No database, no service, no dashboard. A subprocess wrapper, a redactor, a JSONL file and a model. When the month ended I did not have to throw anything away, which is rare for a hackathon project.
If you have a crash that deserved better than a stack trace, I would love to read its eulogy. The comments are open, and the repo takes issues.
Thanks to MLH and DEV for the month, and to everyone who read the other three write-ups and left a note.
來源:DEV Community · dev.to