这个博客,我想了整整两年。

说"想"其实不太准确,更像是一种执念。它在我还不会写前端后端、也不会写嵌入式代码的时候就已经有了。那时候我还在玩电子,偶然刷到了 @ushio 的 视频和网站,觉得很好玩,我也想要一个。后来我花了小半年,从零学会了 C,还学了一点 JS 和 CSS,用 Hexo 搭了一个静态博客,部署在 Github Pages 上,总算也有了自己的一片小天地。

后来,我又看到了 @Innei 的小站:设计精致,功能也很齐全。当时我只看了一眼就想要一个,甚至还赞助支持了。虽然后来没用上,但这钱花得也不冤,因为我借此摸到了 React 的源代码。那感觉就像最初接触 C 时一样——不就是代码嘛,有什么大不了的?总有一天,我要亲手写一个。

那是 2024 年,后来又过了 2024、2025、2026 年,一直到现在

从那以后,一切便再也停不下来了。

一发不可收拾

最初只是想给 @colmugx 的 Hexo 主题 Nlvi 加一个深浅色切换。我先用 Dark Reader 的 JS 胡乱拼了一个,很丑,不满意。接着去学 CSS 的 @media,然后做 JS 的 SPA 切换,再用 TailwindCSS 的 .dark class,再上 SSR 的 next-theme,最后是了一套 Cookie 加 Head Sync 内联脚本,才解决 FOUC 闪烁。前后折腾了四五种方案。

但这还只是冰山一角。接触 React 后,我从石器时代的 Hexo 和原生 JavaScript 一路折腾到 Next.js 13 的 Pages Router,又转头去看 Vue、研究单页应用路由、弄懂 index.html 的回退机制,项目更是重建了无数次。我买了服务器,折腾 Docker、Nginx 和 NAS;嫌 1Panel 太丑,就手写了 Canopy 面板;为了研究 NAS 存储阵列,又写了 RFS;配置 SSL 时被国内环境下频频抽风的 acme.sh 折磨得受不了,索性用 Rust 写了反向代理 Vane 和 Lazyacme。本来只是某天晚上花三小时写出的八百行垃圾代码,结果被群友一怂恿,硬是写了四个月,把 HTTP/3、零拷贝、分层模型和流引擎全塞了进去。后来还有 Seam,一个同样是天坑的全栈框架,以后再说吧。

过度工程化

接着,AI 时代到来,焦虑更是成倍增长。

最讽刺的是,这些东西本来都应该是在有了博客之后,一边记录一边做的。结果博客,想法越来越多,却没有一个地方能把它们记下来。一边是内心不停地谴责自己:说好了 Vane 要做完,就不能停;另一边是越做越远、越做越无力。我一直都记得自己要做什么,就是做不出来。仔细想想,我其实已经很久没有坐下来写过任何东西了。现在回头看,这一切都指向同一件事——过度工程。

我当时其实并不觉得自己跑偏了。Vane?反正博客以后也要部署,总得有个反向代理。Seam?反正迟早要写全栈,不如先把理想中的框架搭好。每一步都有理由,每一步都想着“以后用得上”。可问题是,“以后”永远不会到来,因为我从未真正开始……

失败

其实,做博客不需要反向代理,也不需要自研框架。当时的我却把它们当作前置条件,拿来充当那个看似合理、实则永远阻碍我动笔的借口,但它们从来都不是。真正的前置条件只有一个:坐下来,写出第一篇文章。

其实,我并非没有动手做过博客。恰恰相反,我前前后后做了三次。

第一次还是用 Next.js 13 Pages Router 的时候。那时我对单页应用(SPA)只有一知半解,服务端渲染(SSR)、静态站点生成(SSG)、增量静态再生成(ISR)这些概念更是一个都没弄明白,只因听别人说服务端渲染好,就也想用。结果写着写着,我发现自己根本不知道这些架构究竟要解决什么问题,只好半途而废。后来我转用 Vue 2,做纯粹的单页应用。为什么选 Vue?说来惭愧,只是觉得名字好听,反正也是新东西,就试试呗,结果同样没坚持多久。第三次我又回到 React,从一个 JSX 文件起步,学会了 TypeScript 和 TSX,弄懂了 CommonJS(CJS)与 ECMAScript 模块(ESM)的区别,也爱上了响应式编程,用起了 Lucide、Framer Motion、Radix UI 这些后来再也离不开的库——这次终于有点样子了。但我还是失败了,因为说到底,我只是在照猫画虎:别人用什么,我就跟着用什么;表面看着像那么回事,实际上完全不明白为什么要这么做。再加上 AI 幻觉推波助澜,许多东西确实能拼出一个跑得起来的最小可行产品(MVP),可一旦扩大规模,到处都是坑。

后来我又学了 React(Remix)Router 的 loader、Next.js 15 的 App Router 和 RSC,但那时日常生活已经很忙,没多少时间写代码,倒也没机会迎来第四次失败。现在想想,我的网站从 Next.js 13 一路写到 Next.js 15,前脚刚迁移完,还没上线,Next.js 16 beta 1 后脚就发布了。

放手吧

说“想开了”其实并不准确,我只是累了。

一张 macOS 终端窗口的截图(左上角有红黄绿三个交通灯按钮、深色背景、等宽字体),显示一张用方框线绘制的表格,内容是每日 LLM token 用量与费用,页面已滚动,表头行不在可见范围内。每一行是 2026-03-03 至 2026-03-13 之间的一个日期,配上当天使用的模型——haiku-4-5、opus-4-6,部分日期还有 sonnet-4-6——后面跟着五个数字列,可读作 input、output、cache-write 和 cache-read tokens 以及一个总计,最后是一个美元金额;总计从 2026-03-12 的 161,186,904 tokens、97.92 美元,到 2026-03-09 的 3,277,442,496 tokens、1,765.56 美元。cache-read 是占比最大的一列,常常达到数十亿,而 output tokens 只有几百万,费用与该总计高度相关。这看起来是某个用量统计 CLI 的输出,反映出连续多日的高强度 Claude Code 工作负载,在 2026-03-06 至 2026-03-09 期间达到峰值,约每天 1,700 美元。

AI 时代的节奏太快了。模型一轮接一轮地迭代,新技术一茬接一茬地冒出来,我越来越焦虑,好像一停下来就会被人甩在后面。最疯的时候,我一天写 16 个小时代码,Token 一天就能烧掉 1.9k 美元 (大概是二月份的事吧),整个人几乎废掉。但让这一切停下来的,不是什么顿悟,就是单纯的累了。在越绷越紧的节奏里,最后一根稻草压下来,我反而释然了,想开了,;这样,也挺好的。

我开始学着放手,放下曾经执着的东西,学会适可而止,明天的事留到明天再说。Vane 没做完?先搁着。Seam 还差得远?以后再继续。博客不够完美?先上线。开始彻底采用氛围编程:没问题就不管,出了问题再说。

奇怪的是,放手之后质量并没有变差。我想大概是因为之前那些编程的日子没有白费。早在 GPT-2 的年代我就开始用 AI 了,但那时候我还老老实实地写每一行代码、弄懂每一个概念。那段经历给了我底子。后来与其说是 Vibe Coding,不如说是 Context Coding——该有的判断力还在,并没有因为放手就犯什么低级错误,更没出什么事故。

正是之前所有的折腾,给了我如今放手的底气。

回到原点

最终方案反而很简单:全部放在 Cloudflare 上。R2 用作对象存储,D1 用作边缘数据库,KV 负责缓存,Worker 负责服务端渲染;全都采用无服务器架构,一台服务器也没有。

这个答案讽刺吗?太讽刺了。因为在抵达这个“简单”的终点之前,我绕了整整一大圈弯路。我曾计划自建服务,因此既要管理服务器,又要折腾 Docker 和容器。为此,我写了 Canopy 作为管理面板,写了 Lazycert 管理证书,写了 Vane 充当反向代理,还写了 Twig 监控资源并采集埋点数据。一大堆项目,全是为了伺候一台垃圾服务器。

存储也一样。我嫌对象存储太贵,想直接用自家服务器的硬盘,于是写了 RFS——一种为了实现原子级去重并合并为单文件而设计的虚拟文件系统,甚至复活了二十世纪八九十年代的注册表理念,最后还通过 FUSE 把它挂载了起来。结果呢?我花了更多时间重复造了个没那么好用的轮子,服务器还白白空转了一年,彻头彻尾是一桩亏本生意。

最后绕了一大圈,我还是回到了无服务器架构。Vercel 的理念很好,但我不喜欢 Next.js;而且 Vercel 的黑魔法太多,中间件还要提前编译后放到边缘节点运行,最终依然是割裂的,甚至闹出了几个公共漏洞披露(CVE),还不如干脆把所有东西都放在源站一起跑。Cloudflare Workers 就很好,走到了另一个极端:把不到 10 MB 的构建产物编译成 WebAssembly,让真正的业务逻辑也能在边缘节点运行,这才是我想要的。除了贵,几乎没什么缺点——不过话说回来,这也算不上缺点,毕竟省下的时间就是钱。

少即是多

这句话我听过无数遍,却花了两年时间才真正领会其中的含义。

回归工程的本质:「Make it function, make it correct, then make it exceptional.」我终于走上了正轨,先让它能用了。现在的博客简陋吗?简陋。不完整吗?确实不完整。但总比没有好。如果你连上线都做不到,一直在做那些“也许需要”的东西,一直追求看不见的完美,那最后只会什么都拿不出来。这不是妥协,而是工程上的取舍,反正我是想开了。所以,我真的想开了。不再执着于一个细节,反而走出了家门。手机相册里已经很久没有户外的照片了,便随手拍了一张路边的景色——毕竟已经很久没出门了嘛(

一张俯视拍摄的照片,画面中一道修剪整齐的常绿灌木矮篱斜穿而过,位于一道浅色花岗岩路缘石之后,左下角是一条灰色铺装和沥青路面。灌木丛整体茂密,但靠近路缘石处明显稀疏,露出光秃的木质枝干和一层褐色的落叶,叶片带着春季新生长的黄绿色泽;一株细长的树干从种植带中伸出,位于画面上缘,远处背景中是一片锈红色的花坛植物。光线明亮而具方向性,角度足够低,将一个画面外物体的长而柔和的影子投在铺装和路缘石上,暗示时间为傍晚时分。

回头看之前走过的弯路,我后悔吗?不后悔。有些事如果不亲自试一试,也许永远都想不明白。更何况在 AI 时代,想再走我当年的老路,基本已经没有机会了,太多工作流程都已被改变。另外,这个项目是 Taki,完全由 AI 编程完成,但这并不意味着它无法长期维护,也不意味着它没有人情味。其实是否使用 AI 并不重要。再说了,我喜欢的本来就不是写代码本身,而是把一样东西构建出来……