2026年年中,为个人应用来点 Vibe Coding
有几个手机应用我已经想要好一阵子了,而且说实话,它们基本是只为我一个人做的。

Toucan Music 显示专辑封面
-
地点——别人跟我推荐餐馆或咖啡馆时,我长期以来都是把它们加进 Google Maps 的列表里。这个方式有各种烦人的地方,比如选中列表的时候页面会自动缩小。而且我也不想把数据一直锁在一个免费服务里。
-
人——我有脸盲症,对只见过几面的人很难记住。在大城市里社交时,这个问题尤其明显。这个应用的思路是帮我记起对方是谁,并用间隔重复训练法让我逐渐记住他们的脸。
-
音乐——这个是上周一时冲动做出来的。和很多人一样,我一直想在 Spotify 里用文件夹来整理专辑。之前我试过换回购买 MP3 的路子,但搞得太复杂,最终失败了,于是干脆自己做了一个定制版 Spotify 播放器。
所以过去这一个月左右,我凭着感觉(vibe coding)写出了 Toucan(选“仅本地”模式就能直接试用,你输入的数据都会留在浏览器里)。不管怎么说,源码在这里。不过说实话,我还没自信到敢说这是一个“正式发布”——具体原因下文再讲。
架构
上面提到的这些应用需要在手机上跑,还得把数据同步到网页端,这样桌面也能用。常规做法是给自己搭一个私人软件即服务(SaaS):配一台自己的服务器和数据库,然后再做一个手机应用。
这感觉有点用力过猛——笨重、臃肿,而且扩展性也不行。我一直很欣赏如今所谓的“本地优先”(local-first)软件运动。它的核心想法是:数据主要存储在各台设备本地,通过一个标准化的同步服务器在设备之间传递数据。这样操作会非常快,因为一切都只在本地进行;同步则在后台默默完成。你可以把它想成类似 Dropbox 的东西,只不过同步的是数据库里的数据。
其中有些数据相当私密——尤其是人脸,但哪怕是餐馆推荐里的姓名也很敏感。所以我倾向于把数据同步到自己的一台服务器上,那台服务器托管在一家很不错的本地 ISP(互联网服务提供商)那里。
结果挺失望的——居然没有标准的个人数据同步服务器软件。我本来期待至少有个像Nextcloud那样有一定人气的东西。你可能没听说过Nextcloud,它是一个自托管的文件同步服务器(以及更多功能)。
最后我和Fable选了Yjs,这是目前最流行的本地优先协议。我想要的只是一个能写入SQLite数据库的简单服务器(这样托管和备份都省心)。Fable找到了小众的Hocuspocus,简单且够用(不过事后发现它在数据库文件里的格式不透明,是二进制,但那是另一个故事了)。
我也花了一阵子琢磨能不能用Rust写界面,但最后还是图省事,用Javascript做了个渐进式网页应用(PWA)。装到我的安卓手机上之后(通过Chrome安装,不知为何Firefox不行),用起来跟原生应用没差别。网页版和手机版是同一套代码,行为一致。即便有LLM编程智能体帮忙,这也能省去大量麻烦。
基本流程

在咖啡店使用Toucan Places
大部分工作是在每月18英镑的Claude套餐上完成的,主要用Opus。Fable在前期规划上帮了不少忙,但我不确定它起了多大作用——有几个决定反正后来证明是错的,被重构掉了。
我的流程放到现在的LLM编程阶段算是很常规的:有个plans/目录,任何大改动先在那里做设计。我来编辑、拍板,然后清空上下文窗口,让智能体照着计划实现。
如果是重要的界面或设计改动,我会让Claude生成一个包含几种方案的设计制品。质量出乎意料地高,尤其是迭代几轮之后。
Bug和任务我则用一个简单的to-do文件管理。智能体完成后会逐项勾掉,然后我来验收并删除。
这些任务大多归在“Polish”(打磨)这个标题下。因为我要给出大量产品和用户体验方面的细致反馈。我在日常使用这些应用时会随手记下来。每个应用都有几十上百条。这也是我认为这事目前很难大规模推广给普通人的一个重要原因——详见下文。
我固执地没有升级到更贵的AI编程套餐。我手头有太多别的事要做,而且还挺享受被5小时窗口拦住的感觉——这东西太容易上瘾了。后来我学会了一招:代币用完的时候输入!sleep 3h(或随便多久),再按Ctrl+B把它放到后台运行(不然会有2分钟超时)。几个小时后Claude会自己醒来,额度重置后继续干活,哪怕我人不在旁边。
让它把活干好

定制的快照测试工具
LLM编程的情况下,那些长期以来被认为是好实践的东西变得更有价值了。比如严格配置的类型检查和100%测试覆盖率——关于为什么“100”这个数字特别神奇,参见Jonathan Lange的Galahad原则。
这些给智能体提供了基本的反馈回路,而它们现在也相当擅长对这些反馈做出合理的响应。不过,如果你不主动要求,它们还不会自己去搭这些东西。至少现在不会。
我曾在前端开发团队做过几年管理和编码工作,虽然我们做了很多好事,但始终没真正落实快照测试。而我一直想试试。
所以,比较早的时候,Claude就给Toucan做了一个工具:用无头浏览器给应用的每个页面截图。这真的非常有用——一方面它是集成测试,另一方面它能用来检查设计,还能让我自己做设计QA。它有一个给我看的网页视图(给LLM看的是JSON)、集成的像素级diff、大量筛选和视图选项、基础性能测量,还有命令行开关可以对另一个分支做快照对比。
这简直是无价之宝。
最终的结果是,我让代理去做的事,几乎都能直接完成。不过它通常会做一些我不喜欢的外观设计,或者把部分交互体验弄乱。有时候我还得跟它争论数据结构,或者争论系统里缓存该放在哪儿。
但总的来说,代码它是真的能写出来,而且不会弄坏别的东西。现有测试照常通过,新测试也会补上。它干起活来就像一个效率极高的资深软件工程师,只是上下文感知能力比较差——想要那方面也合格,恐怕得等到 2027 年底或 2028 年。去年的时候,我打心底里不觉得它能把编码做到这个水平。
我遇到过一个比较严重的 bug。有个给列表重新排序的新功能,我从来没测过。某天在外面,我在手机上按了一下,结果整个列表连同里面的内容全被删了!问题出在本地优先存储引擎的数组操作写错了。后来代理帮我恢复了数据,加上了各种日志功能,方便查看同步时到底发生了什么,还更新了文档,明确写着别再犯同样的错误。
最后,我听了 Jyn 的建议,加了一个自我改进的反馈循环。我的版本很粗糙——在 AGENTS.md 里加一段提示,让代理把任何让它费劲的事记到 SELF-IMPROVE.md 里,同时统计同一个问题出现的次数。我会查看这些记录,判断哪些值得处理,然后安排改进。
这个方法挖出了不少问题,比如快照视觉不稳定、node_modules 频繁变动(代理会反复尝试绕开)、性能问题、缺少工具等等。这套机制虽然还非常原始,但我估计未来几年我们都会花大量时间盯着这类东西——这就是所谓的「AI 开发者体验」。
重构
出于对国际标准和简洁性的执念,我一开始想用 Web Components 和原生 JavaScript 来做。我原本希望 Toucan 平台本身能足够强大,让每个应用都变成很短的、单一的 HTML 文件。结果没走通,后来我意识到代码越来越乱,而且有了大语言模型之后,构建步骤其实又便宜又简单,于是我们做了两次大重构。
一个是迁移到 TypeScript,另一个是迁移到 Preact(一个更轻量的 React 替代品)。两次都很顺利——快照测试帮忙确保了没有任何东西被破坏,事实上也确实没有。重构之后一切仍然像素级一致。不过,我并没有花太多时间手动检查代码质量——见下一节。
最初的图形设计相当粗糙。我花了很多力气才让它升级设计,不过最终还是做到了。我不得不强迫它正确地提取共享组件。一个设计能力比我强的人应该能把它做得非常好。不过,跟我自己动手做出来的东西相比,已经算很出色了。
未来
三个功能完整的移动应用,加上桌面版本。坦率地说,能用这么少的力气做出这么精致的东西,实在令人惊叹。
它们已经接近可供其他人使用的程度了,甚至有点危险地接近。如果这些是五年前我写的,我肯定会去推广它们,努力获取用户。
不过现在,这感觉有点……让人疲惫?这些应用对我来说有点太 vibe coding 了。安装和设置都有点古怪。它们做的事情也有点过于定制化。
对我来说,悬而未决的问题是:在一个智能体编程的世界里,大型协作开源项目该如何运作?我真正想要的是,让任何人都能轻松制作属于自己的、有状态且可同步的定制应用。这感觉很难,原因如下:
-
用户体验和产品反馈是一项技能,而且仍然很难做好。人们对移动应用的期望很高,我觉得很少有人愿意去经历必要的反馈迭代过程。
-
跨平台应用框架仍然相当笨重。在 Web 和移动端都好看的界面组件库很有限,PWA 对终端用户来说也不熟悉,编写多个应用需要专业技能,而且难以部署。
-
我并不真正觉得自己拥有这个产品。如果我在经营一家公司,这倒不是大问题。但我并没有仔细审查过代码——我也没必要这么做。在这个世界里,人们对开源有什么期待?我们如何让别人知道这是一个有质量、会持续维护的东西?我已经习惯了代码是开源中交付的关键部分。
-
本地优先(local-first)至今没有一个标准化的平台。可以想象这样一个世界:拥有一个能本地优先同步的个人数据存储库,就像拥有电子邮箱地址一样稀松平常。但现实并非如此。要在2026年推动这件事落地,该怎么做还不清楚——仅仅把它开发出来,已经不再是什么亮眼的成绩了。