[控场AI]
· 9 分钟阅读· 4,629 字

Doorstep:为行动不便者设计的本地AI散步应用

Doorstep:为行动不便者设计的本地AI散步应用

Doorstep 用本地开源模型为行动受限者提供单一散步建议,以身体上限而非动力为设计起点。

Doorstep 是一款为身体行动受限者设计的开源散步建议应用,颠覆了同类应用"用户缺乏动力"的默认假设。它让用户输入今天能走的最大距离作为上限,用 Overpass API 拉取 OpenStreetMap 邻里数据,在代码层面过滤出范围内所有地点,再交由本地运行的 Gemma 3 4B 模型从中推荐唯一一处值得前往的地方。距离过滤严格由算术完成,模型无权决定"走多远",从而避免语言模型幻觉对行动能力脆弱的用户造成实际伤害。应用全本地运行,无任何网络调用,因为健康状况与家庭住址的组合数据属于隐私敏感的医疗记录。它刻意取消连续打卡机制,将"糟糕的日子"定性为身体状况而非意志失败。通过对比两个印度城市的 OSM 数据,开发者还揭示了志愿者地图的系统性地理偏差:数据最稀疏的地方,往往是最需要此类工具的地方。

大多数督促你"走出门去"的应用都有一个隐含假设:阻止你出门的是缺乏动力。但有一款名为 Doorstep 的开源应用提出了完全相反的前提——如果你本来就想出门,而真正的限制是你的身体呢?

这是一个为 Hacktoberfest 开源 AI 挑战赛(Week 1: Touch Grass)打造的项目,它用一个本地运行的开源模型 Gemma 3 4B,重新定义了"散步建议"这件事。

一个被所有同类应用忽略的问题

开发者在动笔前读了这次挑战赛的约九十份其他参赛作品:任务生成器、步道指南、鸟鸣识别、落叶路线规划、强制锁手机逼你出门的应用……

它们无一例外地假设:阻止你的是动力不足。

但没有一个是为那些"已经很想出门却无法做到"的人设计的——术后三周的人、每天早上膝盖决定今天能走多远的人、八十岁只能走到街角再折返、有些日子连这都做不到的人。

Doorstep 问了一个别人都没问的问题:

今天能走多远?

这不是一个目标,而是一个上限。有些日子这个数字更小,而这是被允许的。

Doorstep 在今天可达范围内推荐一个地点

应用拿到今天的数字后,找出所有真正在这个范围内的地点,然后请一个本地开源模型从中挑选唯一一个值得一走的地方。界面示例是这样的:

今天能走多远?  [=====o----------------]  200 公尺

   Balbhim Mandir(神庙)
   138 公尺 · 有地方坐 · 有遮荫
   "一路大多有遮荫,终点有地方坐下。"

之后,它只会再问一个问题:你去了吗? 整个循环就这么简单。没有步数、没有配速、没有卡路里、没有连续打卡记录。

隐私,是产品的第一原则

Doorstep 持有关于你的两样东西:你的身体今天能承受多远的距离,以及这些距离精确的计量起点。两者结合在一起,本质上就是"一份附带家庭住址的医疗记录"。

这甚至给演示带来了难题。应用显示的是地名而非坐标——"130 公尺处的神庙""路尽头的咖啡馆"。即便屏幕上没有任何数字,一张在开发者真实住处运行的截图,也会把他的位置暴露到几条街的精度之内。

所以演示运行在一个开发者并不居住的城市的公共公园里,手动写入了几天历史以免面板空白。应用是真实的,OpenStreetMap 数据是真实的,Gemma 写的每一句话都是真实的——唯一造假的,就是地址。

正如开发者所说:"一个要求你提供住址的工具,应该能够在不公开其作者住址的前提下演示自己。"

Ollama 是一个让用户在本地计算机上运行开源大语言模型的工具,无需云端 API、无需账户注册,模型权重直接存储在用户自己的硬盘上。Gemma 3 4B 是 Google 发布的开源小型语言模型,参数量约 40 亿,可在普通消费级笔记本的 CPU 上运行,推理速度足以支持实时交互。这两者组合使得 Doorstep 的所有 AI 推理都在用户设备上本地完成——应用运行时,除首次下载 OSM 地图数据外,不产生任何出站网络请求。对于持有"可达距离 + 精确起点"这类敏感组合数据的应用而言,本地推理不是性能优化,而是隐私架构的基础——因为没有服务器,就没有可能泄露或被要求交出的数据。

核心架构:距离是算术,不是模型判断

Doorstep 用 Gemma 3 4B 通过 Ollama 本地运行,OpenStreetMap 的邻里数据只下载一次,技术栈仅是 Node 和一个 HTML 页面,守护进程绑定在本地回环地址。

真正重要的那条规则

开发者反复强调的一个设计原则是:模型决定"选哪个",但永远不决定"多远"。

每个地点在交给模型之前,都已在代码层面按今天的可达范围过滤:

const eligible = places.filter((p) => p.metres <= reach);

等 Gemma 看到这份列表时,上面的每一个选项都已经是安全的。它最糟也只能选一个无聊的。

这不是为了架构整洁。对这类用户来说,一个会热情地推荐"再远一点点"的语言模型,就等于一个把人困在离家两条街、无处可坐的应用。距离是这款产品里唯一不能靠判断、必须靠算术的东西。如果模型给出的地点不在列表上,会被当作幻觉而非建议,并回退到最近的可坐处。

当真的无处可去时

今天你周围 100 公尺内没有任何已标注的地点。

这是因为这里的地图信息稀少,不是因为你。

它不会偷偷扩大半径去凑一个结果,也不会凭空编造一张长椅。对这类用户而言,一个虚构的目的地比没有答案更糟——因为他们真的会走过去。

同一套代码,在不同城市是不同的应用

项目中最有洞察力的部分,是开发者抓取了两个相距约 300 公里的印度城市的地图数据后的发现:

较小的城市较大的城市
1200m 内地点28701
长椅024
已标注的树3566
200m 内任何东西无3 处

同样的代码、同样的半径、同样的查询。在较大的城市里,Doorstep 有神庙、咖啡馆和五百棵标注的树可选;在较小的城市里,它只能说"你门口范围内什么都没有"——不是因为街道空荡,而是因为 OpenStreetMap 不知道它们的存在。

开发者的第一反应是"印度没有标注的长椅",第二次抓取证明这是错的。真正的答案更有意思:OSM 是志愿者标注的,所以街道设施图层反映的是标注者住在哪里,而不是长椅在哪里。对一款承诺"200 公尺内有地方坐"的应用来说,这意味着数据最稀疏的地方,恰恰是最不可能有人为其量身定做应用的地方。

因此,"什么算作目的地"的清单,和你看着欧洲地图写出来的完全不同。在印度,神庙和寺院(有遮荫、安静、可坐)、公园、集市、街角商店被广泛标注;而长椅、饮水处、单棵街边树几乎没人标。有长椅时它是最佳答案;没有时,清晨七点的寺庙庭院就是一个真实的落脚处,且它在地图上。

OpenStreetMap(OSM)是一个由全球志愿者共同维护的开放地理数据库,类似于地图领域的维基百科。任何人都可以为自己所在的街区添加道路、建筑、长椅、饮水机等地物信息。Overpass API 则是 OSM 的查询接口,允许开发者按照地理范围和标签类型检索地图要素,例如"获取以某坐标为圆心、200 米半径内所有标注了 amenity=bench 的节点"。OSM 数据的质量与该地区活跃的贡献者数量直接相关,欧美城市往往有详尽的街道设施标注,而其他地区可能同样拥有长椅,却因为从未有人上传过坐标而在数据库中"不存在"。这种结构性偏差使得基于 OSM 构建的应用,其实际可用性在地理上严重不均衡。

一个差点上线的致命 Bug

地图来自 Overpass——一个由志愿者运营的免费服务,所以开发者写了一个循环尝试多个镜像。第一版这样解构响应:

({ elements = [] } = await r.json());

这个默认值是个陷阱。一个返回 HTTP 200 却没有数据的镜像,会产生一个空数组,而空数组是"真值",于是被当成成功——Doorstep 就会静默保存一张空地图。

这个 Bug 对用户的实际后果是:应用告诉一个人,他家门口范围内无处可去。这是整个项目可能说出的最令人沮丧的一句话,而起因只是一个 = []。

修复后,它把"200 但无 elements"视为镜像失败并换下一个。顺带一提,kumi.systems 返回 500,overpass.osm.ch 以 200 状态返回 HTML,只有 overpass-api.de 真正给出答案。

刻意不设连续打卡

连续打卡(streak)惩罚的是糟糕的日子。但在这里,糟糕的日子不是意志的失败,而是正在被承受的身体状况。连续打卡计数器会告诉一个身体"休息了一周"的人:你搞砸了什么。

所以 Doorstep 统计的是一个月里你出门的天数(一周难熬并不能抹掉它),以及出门那些天的平均可达距离——永远不计算你没出门的日子。模型还被明确要求:绝不提及距离、配速、进步、"再努力些"或把对方的健康状况当面抛回去。它被告知要像"一个注意到了什么的朋友"那样写,而不是教练。

连续打卡(streak)机制是健身与习惯类应用中极为普遍的设计,其逻辑来自行为心理学中的"损失厌恶"——中断一条连续记录比从零开始更令人不安,从而驱使用户维持行为。Duolingo、Fitbit、Apple 健身记录等主流应用都依赖这一机制提升留存率。然而这一设计对慢性病患者、术后恢复者或老年人群体存在系统性伤害:当"不出门"是身体的必要休息而非意志的失败时,连续打卡计数器的清零会叠加心理负担,甚至可能诱使用户在身体不适时强行出门以维持记录。Doorstep 以"月度出门天数"替代连续计数,使每一次能出门都被计入,而缺席的日子不产生任何惩罚信号。

为什么开源创新在这里至关重要

开发者给出了三个理由,而第一个足以单独决定一切。

1. 这是健康数据,且与你的住址绑定。 一个知道你今天走了 150 公尺、昨天走了 400 公尺的应用,记录的是你身体变好或变坏的轨迹,而它还知道所有距离的精确起点——因为它必须知道。一份带滑块的医疗记录,加上家庭住址,在同一个文件里。开发者坦言,正是"我连为一次黑客松都不愿把这两个数字一起公开"的本能,构成了把一切留在本地的论据。设置完成后,Doorstep 没有任何网络调用可供审计——因为根本没有网络调用。

2. 它必须在关掉信号的情况下工作。 地图只下载一次,之后它能在地下室公寓、停机的预付费 SIM 卡、没信号的巷子里运行。闭源 API 会让最需要它的那一刻——一个人站在门口决定要不要冒险出门——依赖于网络连接。

3. 每次回答零成本。 一个按请求计费的服务,是退休老人会关掉的服务。

还有一个开发者没预料到的理由:在小型本地模型上构建,反而逼着他把距离逻辑完全移出模型——因为他无法信任一个 4B 模型去处理"出错会伤人"的数字。一个前沿 API 可能足够令人信服,让他干脆放手让模型决定,从而交付一个更危险的产品。没有逃生出口,反而催生了更安全的设计。

小模型做对了它该做的事

Gemma 3 4B 在这里只做它真正擅长的一件事:读一份真实地点的短清单,说出今天哪一个值得去,而所有可能伤人的决定都留在代码里。它能跑在笔记本 CPU 上——这正是一款持有某人行动能力记录的应用能够留在他自己机器上的唯一原因。

Doorstep 的价值不在于技术多复杂,而在于它把"为谁设计"这个问题想得足够深。它提醒我们:AI 产品真正的伦理,往往藏在那些你决定"不让模型做什么"的地方。

#Doorstep应用#本地AI模型#Gemma 3#开源AI#OpenStreetMap#无障碍设计#隐私优先#Ollama
分享:

相关推荐