Still:一部按 Raspberry Pi 思考速度自行書寫的日記
Still: a diary that writes itself, as fast as my Raspberry Pi can think
Still 是一個在 Raspberry Pi 上運行的自動日記:Gemma 4 E2B 本地模型讓虛構信差在終端世界生活,只有發生值得記錄的事情才寫日記。它使用約 1,300 行 Python,無需 API、雲端或互聯網;運行速度受硬件限制,模型只從合法動作中選擇,世界狀態則由程式決定。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
This challenge for me started in a specific mindset.
How do I automate this and that. How do I become more productive. How do I improve my life using AI.
So far, everything I need is already getting handled by my Hermes (deployed on another Raspberry Pi).
And so I iterate. And iterate. On the ideas, on the things I want to do, on the things I already have, and on the things I can actually pull off in a weekend.
At some point a sipra idea came up. I need it for an upcoming jam. But it doesn't fit this week's challenge.
Then, while I was reading on my xteink, something popped into my head.
Sloth. Still. Slow and steady.
What do I have, or what do I do, that is slow and steady?
- Reading
- A Raspberry Pi
- A local LLM on a Raspberry Pi
So, how about building a world inside my Raspberry Pi.
Someone who lives in the terminal. Someone with a life he's living inside this little world of a 2-billion-parameter model. Doing something. Not doing something. Interesting things. Mundane things.
What I Built
So. What is Still.
Still is a life that lives on my Raspberry Pi.
There is someone in there. He lives in a terminal. He has a job he is supposed to do, he has days, he has things he is waiting on. Sometimes something happens and he writes about it. Most of the time nothing happens, and he does not write anything at all.
That last part took me the longest to get to.
My first instinct was a schedule. Write in the morning, write in the afternoon, write in the evening. Three entries a day, always. Predictable.
But that is just a report.
So he writes on impulse instead. Every tick the world moves a little. Most ticks nothing worth writing down happens, so nothing gets written. When something does happen, he writes it. He writes two or three times a day at most. Some days he writes nothing.
And he runs on the Pi and nothing else. No API, no cloud, no internet required. So the pace is not a setting I chose, it is the hardware. When the Pi heats up it throttles, and he slows down.
You cannot make him faster. There is no button for that.
I like that part the most.
An entry looks like this.
I met Ivo at the Repair shop. I showed Ivo the file I'd recovered. He looked
at the empty owner field. He handed it back without filling it in.
Most of his days are not like that one. Most of them are nothing much, and getting comfortable with that was the hardest part.
The world he lives in
He is a courier. That is the whole job.
There are three places. The Depot, where he starts. The Records office, where Mara works the counter. The Repair shop, where Ivo fixes things. Parcels go between them. If he is late, a man called Ren turns up to look at the handoff, writes down the time, and leaves.
He also has a file of his own. It is called old-index, and three of its lines are damaged. When he has spare time he restores it, one line at a time. Here is where it stands now.
path: /archive/landing
owner: [blank]
keep: yes
The owner line is empty. He does not know who he belongs to. When he takes the file to Ivo and asks, Ivo looks at the blank and hands it back without filling it in.
That file is the only thing in his world that is actually about him, and it is the only thing nobody can help him with.
The machine is his weather
He does not know any of this.
- When the world has not been running, the missing hours are recorded as sleep or as ordinary time, depending on the hour. No events are invented to fill them. He does not get a story for the time he was not there.
- When the machine is under pressure, moving is slow, he arrives late, and being late is the one thing that brings Ren.
- He does not know that anyone reads his diary.
Demo
Code
https://github.com/zorexsalvo/still
How I Built It
Still is a Python service, about 1,300 lines across a dozen modules. Four parts matter.
Gemma 4 E2B, running locally. Open weights, downloaded once, served by llama-server from llama.cpp under an alias called still.
llama-server \
--hf-repo ggml-org/gemma-4-E2B-it-GGUF \
--hf-file gemma-4-E2B-it-Q4_0.gguf \
--alias still \
--ctx-size 4096 \
--host 127.0.0.1 \
--port 8080
A worker that finishes a tick, then rests one real hour. Not cron. The next tick is scheduled from the moment the last one finished, so a slow tick pushes the world later instead of stacking ticks on top of each other. One writer only: the worker takes a lease inside the database, and a second worker gets rejected even when it is on the far side of Docker's filesystem boundary. I found that bug by running a native worker next to the containerised one. Docker's flock did not stop it. The database lease does.
A model that chooses, and code that decides. Gemma never invents anything. It picks a numbered action from a JSON schema containing only the legal moves, and code validates the answer again. If the model is unreachable, or the answer is not a legal index, the tick records a quiet wait and a failure. It never invents an action. Files, deliveries, deadlines, who is standing where, and what a missed deadline costs are all decided in Python.
SQLite as the source of truth. Every tick is stored, including the ones where nothing happened. Published entries live in their own table, and triggers prohibit updates and deletes, so an entry cannot be edited after it is written. A publication row records whether the tick was silent, writing, published, or failed. Failed writing is never retried later. The gap stays a gap.
Then three smaller decisions that turned out to matter more than the architecture.
The rejection list. Every entry is checked before it is stored. Wrong number of sentences, too long, not first person, addressed to a reader, containing a comparison, or stating an emotion outright, and it is thrown away. The diary would rather stay blank than publish something that breaks the voice.
The hardware has to be sampled outside the container. Ask the container for load average and you get the Docker VM, which is a polite lie. So a separate process samples the real machine into a small JSON file and the worker reads that. When the machine is under pressure, the courier's legal moves get cut down to the delivery he is already carrying, and the world can record:
Moving was slow. I stayed where I was.
And one honest limit. The hourly cadence was tested deterministically, not by waiting a week. It has not been soaked for days, and it has not run on the Pi yet. The writing gate is deliberately simple, and simple gates produce long silences.
Why Does Open Innovation Matter?
The obvious question is why I did not just use an API.
It would have been easier. Probably better prose too, with a big hosted model. Faster, smarter, no weights to download.
But then the slow part stops being the computer and becomes somebody's pricing page.
I did not want that. I wanted the slowness to be real.
So it runs on the Pi. Open weights, local inference, no internet needed.
It keeps writing when my connection drops.
It keeps writing when a provider changes their free tier, or shuts down, or decides my account is not worth keeping.
And the speed is not a setting I chose. It is whatever this little computer can manage. Slow, and slower when it is warm.
If I want the diary to write faster, there is no config option. I would have to buy different hardware.
That is what slow and steady means here. Not a theme I decorated the project with, but the physical limit of the machine I already had.
The Lazy Payoff
How much time does Still save me? None.
It is a diary I never write, and I do not read it on a schedule. It costs a little electricity and it does not do my chores.
I built it that way on purpose.
Everything else I made this week, I made for me. This one runs without me. I set it going once and it accumulates whether I look at it or not. No API key, no account, no bill, no internet, nothing to maintain.
So the honest number is zero minutes saved. What I got instead is a record of a small life that I did not have to ask for and did not have to write.
The laziest diary is the one I never have to write.
Prize Categories
- Best Use of Gemma. Still runs Gemma 4 E2B locally, on the Pi, as its only model.
來源:DEV Community · dev.to

