停电也能触发健康提醒:本地Gemma如何在断网时让程序员走出户外

尼日利亚开发者用本地Gemma模型把每天停电变成强迫自己起身活动的契机,完全离线运行。
尼日利亚开发者 dannwaneri 制作了开源小工具 Light don go,利用停电到发电机启动之间的空档,提示用户起身走动。工具完全离线运行——天气数据在有电时预先缓存,日落时间用 NOAA 公式本机计算,页面不加载任何网络资源。核心工程决策是严格的职责分离:代码负责所有数字事实,本地运行的 Gemma 模型只生成不含数字的建议语,再由 guard 规则校验。真实停电暴露了模型空闲五分钟后被 Ollama 卸载、停电时触发冷启动超时的 bug,用 keep_alive: -1 修复。项目以具体而微的真实场景,有力佐证了本地开源 AI 在断网、零成本、可调试方面的不可替代性。
在尼日利亚哈科特港,停电是每天都会上演的日常。电网一断,电扇停转、路由器熄灭、笔记本切到电池供电,接着有人喊一声"on the gen!"(去发电机那边)。开发者 dannwaneri 把这段"电网断电到发电机启动"的空档,变成了一个让自己起身走出户外的契机——他做了一个叫 Light don go(皮钦语"停电了")的开源小工具。
这个项目参加了 Hacktoberfest 开源 AI 挑战赛的"Touch Grass"(去接触自然)主题周,核心思路非常接地气:当笔记本切换到电池供电超过 30 秒,一个全屏页面就会盖在当前工作界面上,给出一条建议、一个 60 秒拉伸计时器,以及一个按钮——"I don stand up. Close am."(我站起来了,关掉它)。

一个为"断网环境"而生的本地 AI 应用
这个工具最值得关注的设计,是它完全不依赖网络。原因很直接:停电的那一刻,路由器也跟着断了,云端 API 在工具最需要"说话"的时刻恰恰不可达。
作者的解决方案是把所有网络依赖提前处理掉。在有电的时候,工具每 30 分钟保存一次 Open-Meteo 的逐小时天气预报;停电后只读取本地缓存文件。日落时间则用 NOAA 太阳方位公式在本机计算——对哈科特港 10 月 7 日算出 18:21,与 Open-Meteo(18:21)和 sunrise-sunset.org(18:22)几乎一致。
全屏页面本身也遵循同样的离线原则:不加载任何 Web 字体,不从 CDN 拉取任何资源。页面根据情境切换外观——白天温暖并倒计时到降雨或日落,夜晚则是暗色调,把建议留在"家附近"。这种对边缘环境的务实考量,恰恰是很多云优先产品容易忽略的地方。
Open-Meteo 是一个开放的气象数据 API,提供免费的逐小时天气预报,无需注册即可调用,数据来源包括多家国家气象机构的数值天气预报模型。NOAA 太阳方位公式(Solar Position Algorithm)由美国国家海洋和大气管理局发布,根据经纬度与日期推算日出日落时间,计算过程不依赖任何外部服务,只需本机的 CPU 和精确的地理坐标。两者的组合使"提前获取数据、断网后离线使用"的架构成为可能:天气数据在有网时定期同步并写入本地缓存文件,停电后工具只读取磁盘;日落时间则完全在本机实时计算,不存在缓存失效的问题。这种"有网时预取、断网时降级"的设计模式,在基础设施不稳定的地区具有广泛的参考价值。
代码负责事实,Gemma 只负责"说人话"
整个系统最有价值的工程决策,是作者对 AI 职责边界的严格划分。
模型选用的是 gemma4:e2b-it-qat,通过 Ollama 在纯 CPU 的 i5-1135G7 笔记本上本地运行,下载体积 4.3GB,冷启动约 14 秒,热启动 3.6 到 4.0 秒,约 15 到 20 tokens/秒。
作者最初让 Gemma 根据事实直接撰写整条消息,结果在 4 次测试中它丢掉了所有数字,还两次把意思彻底搞反——比如把"停电"写成"NEPA light don come"(来电了),把尚未启动的发电机写成"before the generator dies"(发电机快熄火前)。单纯校验数字根本抓不到这类错误,因为出错的句子里压根没有数字。
于是他把任务拆开:
- 代码写事实行:发生了什么、降雨或日落何时到来、还剩多少分钟、省下多少奈拉。消息里的每一个数字都来自代码。
- Gemma 只写"建议语":它只看到三样东西——地点、情境(正在下雨 / 干燥的白天 / 天黑后)和一条按规则挑出的活动。它看不到任何数字。
- 一个 guard(守卫)校验建议语:如果出现任何数字、超过 20 个词、或提到 NEPA / 灯 / 电 / 发电机,就直接拒绝。Gemma 有一次重试机会,仍失败则使用固定句子。最多两次模型调用,绝不进入循环。
拆分后,9 次测试全部一次通过,没有出现他观察到的语义错误。
作者也坦率承认 guard 的局限:它只检查数字和话题,不检查"是否说得通"。有一次 Gemma 写出"watch the rain inside the phone"(在手机里看雨)这样的怪句,照样通过了。更大的模型会犯更少这类错误,但跑不动这台笔记本。他明确接受了这个权衡——选择小模型,就意味着偶尔会有一句奇怪的话。这种对取舍的清醒认知,比盲目追求模型能力更有参考价值。
Ollama 是一个用于在本地运行大语言模型的开源工具,支持 macOS、Linux 和 Windows,提供类 OpenAI 的 HTTP API 接口,开发者无需了解底层推理框架即可调用模型。gemma4:e2b-it-qat 是 Google Gemma 系列的一个量化指令微调变体,qat 指量化感知训练(Quantization-Aware Training),相比事后量化在同等压缩率下通常能保留更好的生成质量。keep_alive: -1 是 Ollama API 的一个请求参数,告知服务端在本次调用结束后无限期保留模型权重在内存中,覆盖默认的 5 分钟空闲卸载策略。这个参数在文章的 bug 修复场景中至关重要——停电往往发生在模型已被卸载之后,保持常驻内存是确保"热启动"延迟而非"冷启动"延迟的唯一方式。
真实停电暴露的 bug:模拟测不出来的问题
项目日志里记录了 10 月 8、9 日的多次真实停电,其中第一次就暴露了一个关键缺陷。
12:23 停电时,工具成功检测到了,但 Gemma 超时了。作者在改动任何东西之前先做了测量:ollama ps 显示模型是被这次失败的请求刚刚加载的。Ollama 会在模型空闲 5 分钟后卸载,而他的预热跑在 11:53,到 12:23 时模型早已被卸载,于是在电池供电下遭遇冷启动,耗时超过 20 秒。
修复方案只是一个设置:keep_alive: -1,让 Gemma 常驻内存(占用 15.7GB 中的 3.9GB)。下一次 12:31 的停电,Gemma 一次就答上了。后来 13:34 的那次超时则是另一个原因——笔记本进入了 Windows 的 Modern Standby 睡眠。作者在归咎于修复方案之前,先查了事件日志确认。
他的总结很到位:默认配置破坏了工具唯一的承诺——在停电时正常工作,而"这个问题我在模拟里是发现不了的"。这正是把工具用在真实场景里的价值所在。
Windows Modern Standby(现代待机)是微软在第八代 Core 处理器之后引入的低功耗睡眠模式,取代了传统的 S3 睡眠。与 S3 不同,Modern Standby 下系统并未完全挂起——后台网络任务和应用仍可有限运行,但 CPU 密集型任务(如本地模型推理)会被大幅节流甚至挂起。这意味着笔记本在"看上去处于工作状态"时,Ollama 的推理请求可能因系统进入低功耗状态而超时,且该行为难以在普通测试环境中复现。作者通过查阅 Windows 事件日志(Event Log)确认了睡眠事件的时间戳,从而将此次超时与之前的 keep_alive 修复区分开来,避免了错误归因——这是系统级调试的一个典型范例。
工程细节:全屏页面与 98 个测试
呈现层是一个 HTML 文件,停电数据以 JSON 形式写入。Edge 用 --app --start-fullscreen 参数打开,没有地址栏也没有标签页。模型生成的句子作为"数据"注入,绝不作为 HTML 插入——有一个测试专门喂入包含 </script> 的建议语,验证页面不会被破坏。
整个项目有 98 个测试,其中一个会屏蔽所有网络套接字,确保在完全断网情况下仍能跑完整条停电流程。作者还故意"破坏"guard 8 次(放宽容忍度、移除校验),每次都有对应测试失败——这是一种验证测试本身有效性的好习惯。
为什么本地开源模型在这里不可替代
作者给出的理由简洁有力:网络和电一起死。
停电时路由器要等到发电机启动才恢复,云端 API 在工具需要说话的那一刻恰好不可达,而本机模型 4 秒内就能在无信号时给出回应。它每次停电的成本为零——当停电天天发生时,这一点很重要。
更关键的是,因为 Ollama 和模型都是开放的,作者才能看清第一次真实调用失败的原因(空闲模型 5 分钟后卸载),并改掉那个设置。换成闭源 API,"超时就只是一个超时",无从排查。
这个小项目把本地开源 AI 的核心优势——离线可用、零边际成本、可观测可调试——放在一个真实而具体的使用场景里,比任何泛泛而谈的宣传都更有说服力。而作者说,这个工具目前最好的成果不在日志里:是 9 日那个本该在等发电机中度过、却和表亲的孩子们一起玩的早晨。
相关推荐

uGAP:统一100+非洲地理数据集的AI平台
uGAP是开普敦大学团队开发的非洲地理空间AI平台,统一120余个非洲数据集并提供Python SDK,支持数据发现、处理与模型训练一站式工作流,已用于气旋洪水制图等实战场景。

Cursor能控制你的电脑了:AI代理可驱动桌面应用测试
Cursor 新增桌面控制能力,AI 代理可驱动 iOS 模拟器等桌面应用测试自己构建的功能。本文分析这一更新对开发工作流的影响、技术实现可能路径及可靠性考量。

Vibecoding自研推理引擎:理想丰满,现实骨感
Reddit开发者分享Vibecoding自研推理引擎的真实经历:用WebGL2和GLSL在浏览器跑GGUF Q4模型,却陷入tokenizer调试地狱。本文分析浏览器端LLM推理的工程难点,以及为何直接clone llama.cpp是更理性的选择。