26y:健康、AI行业变化与自我反思
前往原站查看:https://innei.in/notes/211
前往原站查看:https://innei.in/notes/210
前往原站查看:https://innei.in/notes/208
该渲染由 Yohaku API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/notes/207
越来越没有年味了。
小时候,过年是一年中最盼望的日子。放寒假也意味着快要过年了。一般来说,前半个寒假都是在等待春节的到来。节前的那几天,家里人总会忙前忙后,从小年开始,就要开始大扫除,备年货了。
那个时候,我最期待的就是可以买烟花来放了,是那种长条形的,不是那种大户人家才放的起的,能在天上开花的烟花。那个时候,晚上总是很看到别人家在放烟花了,很是羡慕。那个时候那种大烟花并不便宜吧(现如今也不便宜,有色金属还是很贵的),而绚丽的画面只是一瞬。很多时间,都是花了大价钱只是为了这目睹、期待那一瞬,生活何尝又不是。
除夕那天,会花一个下午的时间备菜,做很多好吃的,一家人在一起吃饭,热热闹闹的。城里人都回村过年了吧,乡下每家每户都挺热闹的。我家在一个偏僻的地方,周围没有太多的人家,但是也能感觉到这种气氛。吃完饭,要放鞭炮了。噼里啪啦的,之后就到了收红包的环节了。还记得很小的时候,那个时候收到一个红包一张红票就很开心了,后来红包越收越大,再到现在,一点也没有当年的喜悦了。也是因为工作了,现在基本也都推辞了。
谁还记得以前的春晚是除夕夜必看的吗,那个时候没有现在的高科技,华丽的特效和舞台,也只有一个主会场,但是节目很好看,那时候还有赵本山出演的小品,很多节目也都很有新意,而现如今社会发展了,科技进步了,却越来越没有新意了。这一年一次的大型演出只是一个象征,不会再有更多的人关注了。
我已经不知道从何时起学会了熬夜。
曾经在春晚那天能够熬到凌晨,是一件非常不容易的事情。我至今还记得,有一次我曾经立下承诺要熬夜守岁,最后还是靠着咖啡才度过了那一晚。我很久已经没有再能体会到这种感觉了。现在,每天晚上睡觉到两三点已经是家常便饭,再也找不到当年那种怀着非常激动的心情、找不到那种少年的滋味了。
第二天的一早,也就是新年的第一天,大家伙儿都开始走亲访友,显得格外的热闹。在那个时候,不管是城里还是乡下,都还没有颁布烟花禁令。尤其是农村,每天从很早开始,就会被一阵阵炮竹声惊醒。热热闹闹地走向各家亲戚,也许一年也就这样一次机会,大伙儿在一起探讨着各种各样的话题。从小到大,我都觉得我的亲戚太少了。别家的孩子从大年初一到初八,串门串个不停;而我也就串个两三家就再也没有了。过年期间的大多数时候,我都在看着别人家里热热闹闹的,而自己这里空虚得很。看着别人家的孩子到处串门,收着更多的红包,而我却显得很可怜。现在回想起来,当时有这样的想法,也是觉得挺天真呐。
现在年味越来越淡了,大家伙也不再热衷于串门走亲戚。那个时候大家的生活收入虽然都没有现在好,但是人情味可比现在浓。现在大多数人只是走个形式、意思意思,大家都各自忙各自的去了。去旅游啊,也比这样好。
过了除夕,时间就会过得非常快了。
小时候,过了除夕相当于寒假就过了一半,要不了多久又要回学校上课了。而现在,过了除夕也就意味着快要和家人分开了,大家各自回到各自的岗位,可能很久才能再见一次了。那么现在这段时间又意味着什么呢?
我感觉啊,只不过还是普普通通、平凡的假期那几天吧。我和往常一样,今天是除夕,我写了一天的代码,就和平常没什么两样。
最后还是祝大家新年快乐。今天已经是年初一了,祝大家马年码到成功!

该渲染由 Yohaku API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/notes/206
新年的第一个月也快结束了,我想也是时候再来梳理一下最近这个月发生的事情了。
其实我是一个非常没有安全感的人。我发现我之前所有写过的生活类文章中,可能最离不开的两个字就是“工作”。这一方面是不确定性带来的焦虑感。
也是因为这样,在上份工作被裁之后,我基本无缝衔接了现在的工作。目前我已经快入职两个月了,相信关注过我的人应该知道我去了哪里。在这两个月的时间里,我正好赶上公司的项目处于新版本的冲刺阶段,所以这段时间非常忙。
在此期间,我也做了很多优化工作。前段日子我还专门写了一篇文章,总结了一些关于性能优化的要点。我觉得后面还是要生活和工作平衡一些吧。虽然说远程工作的话确实会比较难,也是最近发生了一些事情吧,让我对这个想法有了更深刻的思考。
年初的时候看了一部电影,名字叫《不过是上班》。
虽然这是一部喜剧片吧,其实喜剧的背后也更多都是悲观。艺术来源于生活,而生活往往比电影表现得更加残酷。当时看完之后,写下了这样一段话:
看了这部电影只能说我一个打工人感触还是挺深的吧。 只是影片中很多也是反映了当代职场以及社会的一些矛盾吧,某些公司喜欢找那些急需用钱家庭困难的员工,因为他们更容易被使唤也不敢辞职,男二也是这样,他兢兢业业每天加班,业绩提升的越快 KPI 涨得也越快,最后加班猝死了。但是即便是这样公司,会想办法处理伪造他的死亡说是酒精中毒,但其实只是过度劳累,最后只配得人道补偿¥50,000。我也经历过裁员,我也知道公司总是站在自己有利的一面,而我们和他们斗争太难了,我们的力量太小了,而公司很轻易的就能抹掉你曾经努力奋斗所付出的一切。 最后有句话其实挺升华的,不过是上班,希望我们都能找回自己的生活。
https://www.themoviedb.org/movie/1555232
其实我也感同身受,因为前段日子发生了一些事情,再加上我上家公司的一些经历,感觉公司想要抹掉你留下的痕迹真的太容易了。
我们个人就像是公司的一次性用品,被扔掉是很简单的事情。不过好在,我上个公司做的项目是开源的,在大众视野内还能看到一点痕迹,情况没那么严重。
https://x.com/__oQuery/status/2012047221337047044?s=20
近期网络上又是刷屏广州 32 岁程序员猝死的消息。所以还是不要把工作当成全部吧。
工作是工作,生活是生活。说什么“能者多劳”,也不一定会有回报。毕竟公司又不是你的,还是要为自己保留一点余力吧。
疲劳加班和为了工作长期熬夜是最傻最没有意义的事情。没有人感谢你的付出,没有人记得你做的事儿,没有人会佩服你,没有人会记得你,最重要的是,你的工作也远没有你想象的那么有意义。早日参透,早日收获。
其实还有一点,就是我更喜欢去创业公司的原因:我觉得在创业公司更加有归属感。
而且在那里做的东西也是我比较喜欢的,很有成就感。同时这些产品我可能自己也会去用,所以我真心希望它能变得更好。当然,我也不希望最后的结局是这样的。
话题扯远了,我们来说一下最近在写的东西。
这个月我开了一个 Claude Code。自从上一次被封号以来,我差不多有快半年没有使用它了。这一次用回来,新鲜感还是很强的。确实,它和以前相比能力提升了不少,现在开发的效率越来越高了,当然这也是基于在它的基础上。
现在大概用了半个多月吧,目前已经刷了 2.1B 的 token。
├──────────┼──────────────────────────────────────────────────────────────────────────────────────┼───────────┼──────────┼─────────────┼──────────────┼──────────────┼───────────┤
│ Total │ │ 33,368,8… │ 2,701,6… │ 81,526,248 │ 1,967,393,0… │ 2,084,989,8… │ $1180.61 │
└──────────┴──────────────────────────────────────────────────────────────────────────────────────┴───────────┴──────────┴─────────────┴──────────────┴──────────────┴───────────┘
最近这一个月以来,我也探索了很多 AI 工具。
现在的 AI 发展实在是太快了,我已经用过了:
谷歌 One 我也是买了一年,是之前有优惠的时候买的。
总体用下来的话,这些 IDE 其实都不如 Cursor,关于 Kiro 的话,它的 specs coding 能力一开始我觉得好像还挺完善的,但是用了几次之后,我也就不想再用了。总之现在编辑器的话,还是用 Cursor,别的话也很少用了。之前想花点时间把 mx-space 的 Admin 从 Vue 项目迁移到 React,基本上整个项目重启,工程量还是非常的大,所以现在还是搁置了。但最近换了一个思路:还是在现在的 Vue 项目上进行翻新,整体计划是把整个 UI 都重写了,然后把陈年技术栈都换掉了:
顺便终于把后端项目也经历一次大的重构,精简了一些模块,同时也终于把 CJS 迁移到 ESM 了,直接使用 tsdown 去 bundle 速度提升了不少,迁移到 ESM 之后,ESM pure 的依赖也不用预编译了。
https://github.com/mx-space/core/commit/9abe0711de82e78c3e25c7a0b7c77b4b65f8f16a
然后是:
就这样差不多搞了一周的时间,基本上已经全部都搞完了。当然现在还有很多小的 Bug,后面再慢慢去修复。值得一提的是,本次对编辑器有了非常大的提升。我也是在基于 CodeMirror 的基础上,做了一个所见即所得的编辑器,类似 Typora。当然,我对写编辑器并不是很擅长,这个工程确实也非常庞大。全程的架构都是由 CodeX 帮我设计的。不得不说,CodeX 在这方面的能力真的是非常强。
再辅助 Opus 4.5 来帮我写 UI,虽然现在还有一些 bug 挺让人烦恼的,但整体用下来,体验已经好太多了。我是觉得现在 AI 的成熟,让很多以前不敢想的东西,现在都能变成现实了。
以前是自己写代码实现一个功能,而忙得停不下来;现在则是通过 AI 源源不断地实现以前那些可能无法实现的东西。至少那些自己原本无法实现的东西,现在正一件一件地落地,这种正反馈和以前写代码时带来的满足感是一样的,让人停不下来。
当然,这种正反馈也让更多原本不会编程的人,能够体会到我们之前写代码时的那种热情。
值得一提的是,我现在让 AI 帮我做事也变得更加简单了。因为我现在也很少去打字告诉 AI 怎么做,甚至这篇文章我也几乎没有打字。在前不久的网友面基中, yetone 推荐了 Typeless,这个软件确实是厉害。相比我之前用的“闪电说”以及其他的一些语音输入法,它们虽然速度快,但准确率却很低,经常需要自己去修正,甚至还不如自己打字。
但是用上了这个之后就完全不一样了:
当然这也是有代价的:这个软件的订阅费非常贵。
新用户可以免费使用一个月,一个月之后:
但这不妨碍你们去试用体验一下它的效果,然后再做出评价。我觉得还是一分价钱一分货,至少现在我很愿意为它付费。
https://x.com/__oQuery/status/2010404209267790104?s=20
上面这个贴文是我当时评测的4款语音输入法的横评,大家可以参考,当然更多的是你自己去体验。
发上我的推荐链接,有钱大家一起赚,你能拿到 5 刀。 https://typeless.com/refer?code=UM6K0UK
![]()
现在已经彻底改变我的编程工作流了。不得不说,用上语音输入法之后,我感觉我的效率又提高了不少。可以同时多开几个 session 去开启更多的项目、做更多的事、实现更多的想法。
在前不久,我买了一台 128G 的 Mac Studio,我觉得这是一个非常正确的决定。因为现在项目开得越多就越需要内存,而且现在内存涨价非常厉害,我觉得买这台 128G 版本的机器真是太赚了。我现在同时会开很多个项目,除了工作的项目之外,也开了一堆 Side Project,让 AI 去探索、快速试错。
我也比较认同 yetone 的观点。我也是去年的时候发现,我其实热爱的是 Building,只是说以前没有 AI 这个角色去帮我 Coding,所以我们只能自己去 Coding 来 Build 一些东西。
https://x.com/yetone/status/2014977294276968532
最近这一个月左右的时间,我基本没有再去社交了。
大约在半个月前,我通过短视频看到了关于“向上社交”这个话题。过去的这几年,我觉得他说的很有道理。我一直以来也都在进行所谓的“向上社交”,强行去挤进大佬的圈子,并尽量尝试去融入。所谓“向上社交”,指的就是不在一个 level 上的社交。更多的是你去找对方,而对方基本不会来找你。
想要维持这种关系,感觉很难而且也很累。所以我现在的现状是:尽量减少这种关系。
我在 LobeHub 上建立了一个心理咨询团队,也尝试询问了我遇到的困境,
https://app.lobehub.com/share/t/RmZwPMEK
还是因为自己的自卑和不自信,往往会把自己放在下位。

该渲染由 Yohaku API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/tech/lobehub-performance-dx-optimization
LobeHub 是一个开源的 AI 聊天应用平台,专注于提供现代化的 AI 对话体验。它支持多种 AI 模型(如 OpenAI GPT、Claude 等),提供 Web 应用和桌面客户端(基于 Electron),并拥有活跃的开源社区。作为一款 React 技术栈构建的应用,LobeHub 在性能优化和开发体验方面面临着诸多挑战。
https://github.com/lobehub/lobehub
入职后的第一个月,我主要专注于项目性能优化和开发体验改进。回顾过往的工作经历,我发现每次加入新团队时,都会优先处理这类基础架构问题。这既是个人习惯,也是对项目长期健康的必要投资。
特别是在当前大语言模型普及的背景下,编程门槛大幅降低,“人人皆可写代码”的时代已经到来。
然而,AI 快速生成代码的能力也带来了新的挑战:代码质量的可控性下降,性能优化意识被削弱。以 React 开发为例,开发者往往过度追求性能指标,却忽视了代码质量和开发体验的平衡。作为 LobeHub 的早期用户,我深知其性能问题一直是社区关注的焦点,“很卡,特别卡”几乎是所有用户的共同印象。
因此,在本文中,我将系统性地总结过去一个月对 LobeHub 进行的性能优化工作,并通过具体数据展示优化前后的性能对比。
这个库是一个 CSS-in-JS 的 Flexbox 组件库。现在有了 Tailwind 的话,编写 Flexbox 布局也是能非常快写出来的。但由于 LobeHub 没有使用 Tailwind,所以就有了这样一个库,能够更快地编写 Flexbox 并设定其各种属性。由于是 Flexbox,所以在项目中大量使用。一个页面可能有几百个这样的组件,所以数量是非常庞大的。
通过火焰图的对比,其实单个组件的性能开销也还好,基本上在 0.1ms 左右。当然,如果是一个普通的 div 组件,这种开销通常小于 0.1ms。
但在组件使用非常多的情况下,0.1ms 的量级累积起来其实也会很大。当然,从性能上来说,其实感知的开销还好。但另外一个问题是:CSS-in-JS 这种方式,只要每个 Flexbox 的属性没有相同的地方,就会生成大量的 CSS。
由于它是 CSS-in-JS 的实现,生成的每一段 CSS 都会比较占用内存。特别是开发环境下。
下面那个测试链接也是我当时写的,主要是对比两种方案的性能、渲染时长和内存占用:
https://css-in-js-batch.vercel.app/
可以看到,虽然两者的开销差别并不是很大,但在内存占用方面,差距达到了大概十个量级左右。
当然,在生产环境下可能没有这么夸张,但依然会有明显的性能提升。
接下来这个问题,还是通过火焰图排查渲染的情况发现的。
在业务中,由于大量使用了动态生成的 CSS-in-JS 的 React Hook,产生了这个 Hook 的性能开销比较大的问题:
所以,如果一个页面上有几百个组件同时都在运行这个 Hook,那么这次 layout 基本上一定会花费大量时间来处理。
这个问题的发现,也是通过火焰图排查到有一些比较轻的组件,渲染却用了一毫秒。在开发环境下要花一毫秒左右的时间,就感到特别奇怪。
然后去排查是哪个 Hook 导致的,最后发现是一个 useStyle 的钩子。
找到问题之后,就比较好解决了,我们只要换一种方案就行。
在这里,我们提出了一种优化方案:不再使用动态生成 CSS-in-JS 的方案,而是使用静态方案。这样的话,性能上也会提升不少,毕竟在组件的运行时上不会再有额外的开销了。
https://github.com/lobehub/lobe-ui/pull/437
https://github.com/ant-design/antd-style/pull/205
上面这两个是比较重大的优化。这波优化全部完成之后,整个 APP 已经有了很明显的提升。
以前消息列表中的每个 Message Item 都需要花很长时间去渲染,而现在在开发环境的表现已经和之前在生产环境差不多了,在生产环境上则会更快。内存表现也是:现在可以保持在正常情况下 400-500 MB 的样子,甚至更低。
首屏的性能优化,主要做的是如何让用户从其他页面返回首屏时速度更快。
首屏的加载时间是非常影响用户体验的一个点。在 React 中,当一个页面切换到另一个页面时,上一个页面一般都会被销毁。如果首屏组件的逻辑很重,从另一个页面返回首页时,就需要等待首页的重建。
用户需要等一段时间,而这段时间页面相当于处于不可用的状态。
可以看到上面那张优化前的图。从其他路由返回到首页时,Desktop Home Layout 这个组件在重新渲染时大概花了 500ms。
使用 React 的 Offscreen(也就是 Activity 组件)优化之后,从其他页面返回到首屏的时间控制在 55ms 左右,几乎在点击的瞬间就可以完成跳转。
这是在开发环境下的火焰图表现,在生产环境下,它的速度会更快。
https://github.com/lobehub/lobe-chat/pull/10890
完成了上述内容后,在消息列表中,单个 MessageItem 的首次渲染性能有了非常大的进步。
但是,MessageItem 组件过于复杂,部分基础组件如果渲染开销较大,也会影响整个 MessageList 的性能。
首先重构了 AccordionItem 组件,这类组件在未展开时,内容区的 React 组件逻辑通常不必执行。因为它在 UI 中本身不可见,那么对应的组件逻辑也不应执行。
这是一种常见的优化手段,在比较复杂的组件中,能够显著提升性能。
https://github.com/lobehub/lobe-ui/pull/430
Tabs 也是基础的 UI 组件。在之前的 AntD 实现中,单个 Tooltip 的渲染性能开销非常大,在开发环境中平均需要 0.5ms。
![]()
在过去的多个PR中,我使用了 Base UI 以及组件单例的方案,重构了包括 Tooltip 和 Popover 两个组件。
目前在业务中,基本已经把 Tooltip 替换完毕了,Popover 的话还有剩余一些。更换之后,这两个组件的性能比之前有了很大的提升。
![]()
https://github.com/lobehub/lobe-ui/pull/448
还有其他一些基础组件也还有优化的空间,但目前还没有细看。
后续的计划如下:
关于裁剪 Electron 体积的话,其实我之前也分享过经验。
首先在 Mac 上,Electron Framework 的体积是可以裁剪的。它里面自带了很多语言包,占用大约 34MB 左右。我们可以把它们全部删掉,只留一个英语(en.lproj)就可以了。需要注意的是:
通过这种方式,直接就能省掉 ~30MB 左右的体积。
其次,我们可以优化 ElectronBuilder 打包 node_modules 的逻辑。
一般来说,如果 Electron 主进程(Main Process)的打包没有 Native Binding 的话,我们可以利用打包器把所有的三方依赖打进我们的 Bundle 里面。这样一来,程序就可以完全脱离 node_modules 去运行。
然后可以修改 ElectronBuilder 的配置在配置中将 node_modules 排除掉。
当然,这里考虑到后面可能会使用到 Native Binding,所以我在里面做了一层兼容性。
如果有 Native Binding 的话,我们可以把单独的 Native Binding 依赖加进配置,这样一来,这个依赖就会被打到 asar.unpack 里面。
详细的配置我就贴在下面,大家有兴趣可以看一看:
https://github.com/lobehub/lobe-chat/pull/11397
经过这些处理,大概裁剪了 100MB 左右。现在 App 的体积大概在 260MB 左右。
对于 60fps 的要求,一帧只有 16ms 的时间。
如果单个组件的性能消耗超过 1ms 以上,那么该组件首次加载的性能就会变得非常糟糕。因此,我们尽量要将单个组件的性能控制在 1ms 以内。在首屏的场景下,我们要实现最高程度的优化,控制首屏的 LCP。那么,我们就要尽量控制首屏组件的渲染性能。
![]()
如上面的火焰图所示,红色标注的这些组件都是性能不过关的组件。
可以看到,这些组件的渲染时间都超过了 1ms,在右侧的那些的单个组件的渲染甚至达到了 5-6ms。
由此可见,我们需要去优化这些信息。在展开这些组件之后,我们可以看到存在哪些 Hook,然后在组件中进行打点,以此排查是哪个 Hook 或者哪段逻辑存在性能瓶颈。
在下面这个 PR 中,我尝试解决了这些问题,将其优化到小于 1ms 毫秒。
![]()
https://github.com/lobehub/lobe-chat/pull/11718
详细的优化过程可以查阅上面 PR 中的改动。
使用路由的动态加载,可以有效地分割包体积,提升 WebApp 在首屏中首次加载的 JS Bundle。从而提升首屏的 LCP。但带来的问题是,在 SPA 应用中由于得不到较好的优化,在之后的路由跳转中,首次会出现 Loading Element。但这个首次加载的包体大小,在本地的 Electron 应用中并不是问题,所以在这类场景中,我们并不需要使用动态加载的方式。在下面的 PR 改动中,我使用 AST Grep 进行了优化,针对 Electron 打包场景对代码进行了重写,将动态引用全部改为同步引用的方式。
https://github.com/lobehub/lobe-chat/pull/11690
带来的好处显而易见:在 LobeHub 2.0-next.330 之后的版本中,首次在聊天框中输入内容以及跳转到聊天界面时,都不会再出现闪烁的情况。
上面就是一些性能优化的点。
接下来,我想说一说影响开发体验(DX)的一些优化吧。
首先是我很早以前跟空谷提过的建议:把 i18n 的 key 扁平化,不要使用对象嵌套的方式。
这样做的原因主要有以下几点:
也是终于把这个事情给做掉了。
还有一个也是我想想安利一下的,就是我之前写过的一个库:electron-ipc-decorator。我也把这个库给实装了。
因为之前的实现需要一个 dispatch,然后再去做 subscribe,类型化也不太安全,而且 dispatch 的 type 也都是 hardcode 的一个 string 编码,我感觉不是很好。
所以我把自己这一套也换了上去,现在写起来比较方便。
https://github.com/lobehub/lobe-chat/pull/10679
剩下的话其实还是在做一些计划。
比较大的一个重构点,应该就是把 Next.js 迁移到 Vite。这个计划的工程量很大,目前还在筹划中。我也做了一些实验,应该还是有可行性的。
如果这个能成功的话,那应该也是很多开发者的一个福音了。
不管是团队内的人还是社区的人,现在应该都能很明确地感受到,现在 Next.js Server 启动的话,大概要十多个 G 的运行内存。如果你是 16G 的机器,基本上是没有办法开发的。
而通过实验做下来的结果是:Vite 可以控制开发时的运行内存,只需要大概 1G 多一点就行了。相比之下,内存占用和现在相比大概减少了 10 倍左右。

该渲染由 Yohaku API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/tech/how-to-use-ai-for-assisted-creation
如标题所见,在最近的编写的一些文章中,我使用了 AI 的辅助。其实早在过去一年编写的手记中,也常规的使用这个方式,只不过更多的用于标题的生成,我对文章的取名一直非常头疼,后来就写完整篇之后让 AI 综合全文的内容帮我提取几个关键字来取几个文艺点的标题。
在最近编写的文章中,如那篇「回头看见自己」中基本都是 AI 辅助编写的。我在「此站点」中增加了一个 Q&A:
在 25.11 月发布的文章都会公开:在编写文章时是否使用了 AI 的辅助。
可能很多人会反对使用 AI 进行创作,编写博客等等。那么当你看到文章顶部的 AI 声明之后你有权利选择直接关闭。
我个人并不反对使用 AI 辅助写作,当编写技术文章时,我可以借助 AI 帮我快速根据相关实现绘制流程图,以便读者更加清晰的理解,而在前 AI 时代,则往往需要花费大量的时间,或者因为这个理由而放弃绘图。当编写生活记录时,我往往借助 AI 帮我取一个标题,我承认我不是一个大作家,写不出更好的文笔或者叙事结构,我想记录故事,而 AI 帮我整理故事。
编写这篇文章首先是澄清关于 AI 的使用,另外也同时分享如何使用 AI 写出更好的文章。
首先是一个问题,你认为使用 AI 辅助创作会节省大量时间吗?至少对我来说,需要分为两个维度。
在编写技术类文章时,确实会大幅节省,而且比手作的内容会更加完整。正如前面所说,在手作的时候,在画流程图会花费大量时间,往往会因为时间成本而放弃;在内容结构上也会精简掉很多。而借助 AI ,它可以阅读项目的代码,再加上你告诉他当时的实现思路,它可以很迅速的分析然后编写出叙事清晰的文字、流程,甚至使用 excalidraw 绘制图表。
在编写手记生活类文章,并不会节省时间,甚至会花费很多的时间,至少对我来说是这样。AI 并不知道你的生活发生了什么,生活不是代码,无从读起。我会把所有的经历说给 AI 听,这个过程中,相当于我已经完成了一遍文章的编写。在没有借助 AI 之前,差不多到这个时间就截稿了。取上标题和分段,就直接发布了。而现在,需要让 AI 结构,整理,调整上下文过度。然后我还要校对几次确保没有把我需要表达的内容曲解。有些措辞我感觉不好,就会多次询问 AI 修改等等。花的时间不止一点。
在编写 Better Auth 的多租户用户鉴权的构想 文章时,初次使用借助 AI 辅助作图的能力。比如解释为什么的时候,可以画一个图:
![]()
![]()
再加上文章中有很多 Demo 代码,实际上都是实际业务中的代码抽离出来删掉很多多余的逻辑的,这个过程如果手动去改的话还挺容易删出问题,而且还需要增加注释和删除代码后的格式化问题,之前很多 demo 代码我都懒得管。而 AI 通过读项目,可以非常快速的写完 demo 代码,并且加上注释:
![]()
在今年的年终总结 2025 · 仍在路上,半径之外 中,使用了 LobeHub 进行故事整理。
在开始之前我使用内置的 Agent Builder 构建了一个专门的写作助手:
![]()
![]()
随后在文档中进行内容创作:
![]()
我会分段的和 Agent 讲故事,他会把故事写到文章里。你会发现这个过程中,我自己也会完全写作一遍,我的陈述和最后的插入的内容基本也是一致的。
在最后的过程中,可以进行小标题的重构:
![]()
然后进行一次 review,把很多段落重新调整,阅读一遍,发现有些措辞不太好,但是也不知道怎么改会比较好,我会询问 GPT。
![]()
找到一种我想要表达的方式,而不是过分的曲解。
再比如取名:
![]()
在这个案例看来,这篇年终总结所花费的时间比往年的更长,故事叙述大概花了 4 个多小时,然后是结构整理,改一些过度承接,取名等等。
感谢你能看到这里,此篇文章为手作。

该渲染由 Yohaku API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/notes/205
去年年底提了车。今年年初,家里人都回来了,我也正好需要磨练车技,就带着他们去了周边很多地方。
买车这件事我一直觉得离我很远。那时我已经远程工作快两年,住在小县城里也基本足不出户,实在想不出它能带来什么改变。无非是带来更大的花销,生活又多一笔隐形的负担。
有车之后,最大的变化是生活不再局限在一亩三分地:我拥有了随时出门的自由。往年我也经常往返于杭州、上海,和从前的同事、朋友见面,但这些安排总得提前几天买好车票、把行程安排妥当。现在最好的地方在于,我不必再提前计划。而现在可以只是一个临时的念头,就能立刻出发,对我这种 P 人来说实在太友好了。偶尔也可以玩到很晚,不需要因为赶不上定的高铁票而在外面借宿一晚或者被时间限制不得不在约定的时间提前结束活动。我可以在凌晨上高速,安静地把车开回去,顺便体验夜路驾驶的乐趣。
![]()
今年第一次出国旅游,目的地是新加坡。第一次出国的新鲜感很强。新加坡华人很多,基本都说华语,没有什么语言障碍;好吃的也多,好玩的也多,算是开眼看世界了。旅行本身没有太多戏剧性,更多是把自己从熟悉的坐标系里挪开一下,同样的生活节奏,在别的城市里会显得轻一点。
今年买了一台人生第一台相机,富士 XT-5,开始走上摄影的败家之路了。
由于买不到套机,我是加价买的16-50 的套头,再加一个 35 定。用了一阵子之后,很快就意识到焦距不够长。没办法拍到远处的东西,感觉还不如手机。于是又添了一支 70-300。结果买了没几天就撞上 618,价格直接掉了 1k,心在滴血。但事已至此,也只能用一句“早买早享受”给自己收尾。相机到手后的第二天就去了湖州拍照。也正是在那次出行里,我意识到长焦有多适合我这种 I 人,主要是拍妹妹更好了(不是)。
有了相机之后,也开始 push 自己多出去走一走了。背上相机,记录一些原本会被忽略的静止瞬间,也会多留意身边的事物了。七月,时隔一年再次来到南京,这次停留得更久。去了朋友即将毕业的大学校园,也去了朋友即将“毕业”的小米园区;夜里在老西门闲逛,白天去了红山森林动物园。在城市里慢慢走、慢慢看,相机也成了我重新认识一座城市的方式。
随着去的地方越来越多,我也开始意识到,需要一个属于自己的空间来存放这些被记录下来的瞬间,需要一个像照片的个人博客一样的地方。
印象很深的是,那正好是五月份,Sonnet 4 的发布,在编码能力和工具调用能力都有了明显提升,「Vibe Coding」这个说法也开始出现。第一次使用这个模型时的感觉非常惊艳:只需要非常简短的描述,就能生成一个完整、可用的简单项目。
也是在那个时候,我完成了第一个大部分代码都由 AI 完成的项目,Afilmory。
https://github.com/Afilmory/Afilmory
有了 AI 之后,很多以前不敢想的事情都变成了现实。比如在 Afilmory 这个项目里,通过多次和 AI 反复探讨实现细节,最终做出了一个支持超高像素的 WebGL 图片预览器,这在过去几乎是不太敢轻易尝试的事情。
后来随着越来越频繁地使用 AI,我也慢慢想明白了一件事:我之所以一直喜欢写代码、喜欢做 ToC 的项目,并不是因为代码本身有多迷人,而是因为我享受把一个想法打磨成产品的过程,反复调整细节,直到它真正好用。现在有了 AI,这个过程的门槛和成本被明显降低了,我可以更快地把想法做出来,让它跑起来,并且产生真实的价值。
从那之后,我也算是真正“开上了自动挡”。到现在为止,已经借助 AI 完成并上线了不少项目:比如 Torrent Vibe,还有后来重构成 SaaS 的 Afilmory 也算是一个真正意义的比较大的项目,还有一些摄影相关的小工具。这些项目都已经跑在生产环境里,并且运行得相当稳定。
今年也是见证了 AI 的飞速发展,模型厂商内卷,几乎每个月都有更好用的模型出来,还有针对编码场景的特调版本。前半年在使用 AI 的时候,还需要编写完整的流程,探讨编码计划,一步一步引导式,最后甚至要写一个 Plan;后来进化到使用上下文工程,开始写 PRP。到了后半年 CodeX 的出现,它可以长时间执行一个任务,通过探索所有相关代码一路跑下去。我第一次用它的时候,一口气跑了一个小时最后完美实现需求,那种感觉很难不被惊艳到。凭着非常优秀的上下文和压缩能力,我一度觉得它的上下文高得有点可怕,基本不需要我再刻意去感知它。
一不小心又说了太多 AI 的故事了,容我控制下情绪。
年初花了一两个月做 React Native 的移动端 App。为了打磨细节,也顺手研究了不少 iOS native 的东西,甚至手搓了一些原生模块,只是为了性能能更好一点。我还自己实现了一套 React Native 的 Navigation,底层是基于 React Native Screens。初衷很简单:大家都在用的 React Navigation 那套声明式写法会影响后面的 DX,我总觉得它应该更接近 iOS UIKit 的 Navigation,所以就自己对齐了一遍。前半年 AI 还没现在这么能打,很多东西基本都是手搓,时间和精力确实花了不少,但也挺有意思的。
https://innei.in/posts/tech/build-simple-navigation-with-react-native-screens
工作这块,一整年基本还是围着一个 RSS Reader 打转。后面有一段时间,我几乎把所有精力都在 RSS Reader 的 AI 实现部分上。其实很早就能放 Demo 出来,但效果一直不满意,就这么拖着,迟迟没有发布。前前后后折腾了半年,最后效果也并不好。
这半年倒也不算完全白忙。我学到了不少 AI 相关的知识,也认识了一些业界有名的大佬,和他们的对话里学到很多。这也是一个契机,以至于后面我加入了一个 AI 的创业公司。
后面的故事就没那么顺利了。熟悉我的人大概也知道是怎么一回事。如果不知道,也没必要刻意去吃瓜了。
总之我去年被裁了,今年又被裁了。我是什么裁神爷,一年干黄一个项目。
后来我又加入了一家创业公司。我还是很喜欢创业公司的,即便已经是工作三年的老登了,仍怀着创业的热情。
为什么说是“又”:短短 5 年里,我加入了 4 家创业公司,其中有一家实习了一年半;剩下两家,一家呆了一年,一家呆了一年半不到一些。如果可以的话,我也想一直干下去。
我也在中大厂待过一段时间,所以我很清楚自己喜欢什么样的氛围。至少现在,初心犹在。
我没有把“被裁”当成故事的结尾。我还不太会安稳,只能让自己不停往前走。做点事,心里才踏实。
今年也买了不少设备。除了 XT-5 和一堆镜头之外,也换了手机。一年一换几乎成了常态,真的有点败家。
还买了一台投影仪,现在终于可以躺在床上追剧了。
电脑也换了:Mac Studio M4 Max,128G 顶配内存。买之前想了很久,一直犹豫。后面因为要跑大项目,咬咬牙直接上了顶配。现在开发同时起四五个项目都不卡,太值了。
我人生里一共拥有过四台苹果电脑。这台是我人生中购入的第二台苹果电脑。
第一台是 MacBook Pro 16 的一款 Intel 芯片机型,那是我刚进入社会实习时老板发的 bonus,也算是开启了我后面的开发之路,我很感激他。
第一台 Mac Studio 是我在第二家创业公司时送的,一直陪我开发到现在,也很感谢它。
而我自己买的第一台是 MacBook Air M2,到现在已经三年多了。我平时在家的时间多,所以也一直没有换。
这些机器堆在一起,像是把我的几年拆成了几段:有人给过我起步的机会,也有人在路上借我一把力。我不太擅长表达,但都记得。
今年看了不少剧,大部分都是韩剧。最近还在追《模范出租车》第三季。
也玩了一些 3A 大作,比如《死亡搁浅 2》。和前作一样,沉迷送快递,乐此不疲。
后面玩了《羊蹄山之魂》,画风绝美。和前作相比,可玩性更高了,有一种玩塞尔达的感觉:总是在赶路的时候,被偶遇的事件吸引走。
我喜欢随机事件把我带跑偏。现实里跑偏要付出代价,游戏里跑偏反而是奖励。
今年写得比去年少,掰着手指算也就 30 篇。可这一年并不空,只是没写出来。
以上就是全部的内容,感谢能看到这里。
![]()
![]()
我没指望未来会突然变好。只希望明年风小一点,我能更稳地往前走。
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/notes/204
这段时间,事情一件接一件。先从日常说起吧。
最近看了新的 IP:疯狂动物城,前作看了一半之后忍不住直接去电影院先去把 2 看了。
https://www.themoviedb.org/movie/1084242-zootopia-2
复仇爽剧:模范出租车出第三季了,速看。
https://www.themoviedb.org/tv/119769-taxi-driver
上个月说的羊蹄山之魂通关了,正在二周目新游戏+。最近有点忙,还没有时间玩。
然后再来说说一系列的难受的事情。
裁员那天,HR 找我聊。我以为会是一次体面的告别,甚至在某个瞬间,我还真的把它当作“和平结束”。
我接受得很平静。没有赔偿,只有十天的通知费,设备还要折旧回收。
这和老板之前的说法不一样——他说会有一笔金额,最后并没有兑现。说到底,给不给,很多时候更像是取决于公司怎么选择,我也很难指望一定会有结果。我当时理解香港这边的规则和大陆不太一样,很多保障并没有那么到位,至少对我来说是这样。相比之下,大陆的劳动法在这件事上,确实更能保障一点。
后来我写了一篇文章,是对这段时间的总结、复盘和经验整理。我写到了一些我认为真实发生过的事情,于是被要求删掉。他们似乎不希望外界因此去质疑产品的未来。但在我看来,这个项目对外的更新与动作已经停滞了一段时间,我很难再用更乐观的词去形容它。
我还是删了。调整内容,重新发布。
删掉的那几个小时,反而让吃瓜的人传得更开:更多人开始围观一个可能从来没用过的产品,开始猜测、开始补全故事。
我没想过会这样。我只是把文字放在自己的博客里,没有在任何社交媒体发链接。可它还是自己长出了腿,走得比我想象的远。
总之,事情已经发生了。只是我没想到,最安静的地方,也会有回声。
后来的事情,让我开始感到气愤。
我从一些同样被裁的人那里,听到了很多过去从未得知的细节。起初我也知道:所谓「事实」,往往只是当事人愿意倾述的版本;人们更愿意相信自己想相信的那一套。可再往后,一些细节在不同人口中反复出现,我很难再把它当成纯粹的「版本」。
而这些信息里,我感受到的是一种让我很不舒服的做法。我很难把它当成善意。
我甚至有种恍惚:我正在经历的流程,像是他们已经很熟悉的流程。很多表达让我感觉更像是在引导情绪,让人先心软,再一点点降低预期。
有些话当时听起来很重,像是在替你争取,像是站在你这边。可很快我又看到各种说法开始变化,解释一层层叠上来,最后结论还是往下走。有人情绪激动,场面也变得很难堪,我也在那种尴尬和同情里破防。
我就是在那一刻意识到:这不是沟通,也不是协商。我当时的感受是,这一切太熟练了,像是事情最终会走向哪里,大家心里早已有数。
我当时接受得很平静,而此刻回想起来,更像一个小丑。
我其实并不在意有没有赔偿。入职之前我就查过资料,也问过 GPT,知道香港的法律大抵如此:很多东西写不写进合同、给不给到位,最后都落在“愿不愿意”上。换句话说,我对结果并不意外。
让我气愤的不是钱。是前后说法的落差,是那种被轻轻带过的感觉。
是他们先把话说得像承诺,让你以为自己会被认真对待;又在最后一刻轻描淡写地收回,仿佛从来没有说过。你甚至很难抓住一个明确的“反悔瞬间”,它更像是一种温柔的推诿:说过,但不算数;答应过,但没保证;本来想给,但现在不行。
直到那天的晚上,老板出面发布了第一个公关帖子。
在发帖前后,我注意到他之前转发过的一些内容不见了。这种变化让我很难受,像是我们被悄悄从叙事里抹掉了:那是裁员当天,我们在 X 上发帖找工作,他还转推了,看起来像是"好聚好散"。
可现在,那些转推都不见了。仿佛他从未表态过,仿佛我们从未存在过。舆论开始发酵,像一把火终于找到了引线。
我很气愤那些让我觉得不真诚的说法,但我还是忍着。
很多认识我的朋友,在我把事情的全貌讲清楚之后,都站在我这边。有人在评论区替我打抱不平,也有一些从未谋面的、一直默默关注我的人给我留言。谢谢你们。那一刻我才意识到,原来我并不是一个人在扛。
可真正让我彻底破防的,是这篇公关帖之后发生的另一件事:后来我看到有人公开说“还在招人”。这和我当时的处境放在一起,让我非常困惑。
我后来从别人转述里听到,确实有人收到了类似的招聘信息。真假我不想再追究,但它带来的观感已经足够刺痛。
一边是把所有开发裁掉,一边又在招人。即使我已经大概能猜到这个项目的结局,我仍然会本能地怀疑:他们到底在招什么?他们到底在维护什么?他们到底在演给谁看?而更可怕的是,我已经不会再相信他们说的任何一句话了。
这件事荒诞到像段子,可它真的在发生。
于是开始出现各种猜测。我不想替任何猜测背书,但我能理解大家为什么会这么想,因为许多细节拼在一起,确实让人很难安心。
我那一刻是真的崩溃了。回想过去一年多,自己亲手从零开始打磨那个项目,很多夜晚、很多细节、很多你以为“会留下些什么”的东西,最后把我推到这个下场。突然就显得很可笑。
后面我开始反击。
我把我知道的、我听到的、那些彼此矛盾的说辞一条条摆出来,把不满也摆出来。不是为了吵赢谁,而是因为我突然明白:如果我继续沉默,他们就会替我把故事写完——写成一个“大家都理解、都体面、都没问题”的结尾。
第二天,情绪被推到了顶点。
奇怪的是,这段时间里没有人再来找我“沟通”、也没有人再来做公关。倒像是他们自己开始上演一出反向公关。
先是招人的事。我看到那条内容挂了一会儿,后来又不见了。
然后,有一位老板在公开场合说了这样一句话:
“大意是:创业不是慈善,加入前就该知道风险。”
后面那半句更锋利:他甚至还在强调公司对我们“没有任何可以挑出问题的地方”。
我当时看到这段话,心里一下子就凉了。
原来他们最后选择的立场不是“解释”,也不是“道歉”,甚至不是“沉默”。而是把一切包装成一句轻飘飘的逻辑:你选择了创业,所以你就应该承担一切;你受伤了,也只是你没想清楚风险;至于他们许下过什么、表演过什么、推诿过什么,都可以被这句话一笔抹平。
你们的委屈不是委屈,你们的付出也不算付出——你们只是在“应该如此”。
而真正荒诞的地方在于:他们一边说“风险自担”,一边又需要你相信他们;一边裁掉所有开发,一边又试图招新人;一边要求大家体面收场,一边又在公众叙事里把责任切得很干净。
我从来没指望创业像童话。我只是没想到,最后会被当成一个“应该懂事”的道具。
更荒诞的是,话说到这里还没有结束。那个说出“创业不是慈善”的老板,转头又出现了一些私下的说法,像是在推动大家选边站,也像是在形成某种“口径”。于是新的版本开始流出来。而且每一个版本都比上一个更像谣言。
他说我是自愿离职的,不是被裁的。
他说公司裁员不给赔偿,是因为“你没签国内合同,这是你当时的选择”。可事实是:这根本就不是“选择”。对我来说,那份合同从一开始就没有真正的可选项。你甚至没有站在十字路口,你只是被推着往前走,走到最后再被反过来指责:你看,是你自己走的。
这两天我真的累了。我开始想结束这一切,不想再把更多人的时间和精力卷进来。朋友的,围观者的,甚至我自己的。
可偏偏就在我想把情绪压下去的那天晚上,他发了第二篇公关小作文。很长,很“认真”。开头先说外界的讨论被片段化信息带偏了,说这次人员调整是正常的商业决策:为了长期发展、为了降低成本、为了对用户负责,并且不是突发,而是按节奏推进。接着,他把矛头对准了“某一位离职员工”,暗示情绪之所以失控,是因为有人在夸张表达、带动对立。
我看完反而更气愤。是因为他把重点换掉了。他没有正面回应那些承诺为什么会消失、那些话为什么会变成空气。他只是把故事重写成另一种更安全的版本:公司在做正确的事,而问题出在“表达方式”和“情绪”。
更让我不舒服的是,他把生活也拖进了工作里。奖金、回忆、一起旅行、一起拍照,这些东西被摆出来。我承认,加班可能是我自己的选择,奖金也是对方的选择。我只是觉得,选择不等于可以互相抵扣。钱当然重要,但它换不回生活,也换不回那些被占用的深夜和周末。
至于所谓朋友,我更不愿意被拿来当论据。老板和员工之间存在强利益关系,权力和选择从来都不对等。它可以是合作,可以是尊重,甚至可以是欣赏,但很难是朋友。朋友不会在争议发生时,用私人回忆来证明自己更正确。那更像一种提醒:你应该懂事……,你应该感恩,你不该把事情说成这样。
那一刻我意识到,对我来说这更不像沟通。他们只是要一个体面的结尾——而这个体面里,不包括我。
我再也压不住情绪,于是主动联系了他。在那段漫长的沟通里,我其实只想尽快结束这个闹剧。
越聊越像陷进去的泥。一边是迫切想停下来的疲惫,一边是被情绪推着走的冲动。再加上一点点生活外的交情,哪怕只是曾经的礼貌,曾经的温和,我心软了。我以为只要把话说开,把情绪压下去,事情就能回到“到此为止”的轨道上。
但现实不是这样运作的。
我在对话里意外透露了一些来自前同事的说法。它原本只是倾诉,只是“我听说过”。可话转了几层之后,性质就变了。传到另一个老板耳朵里,它可能就不再是信息,而变成了立场。不再是叙述,而变成了证词。于是那个说过“创业不是慈善”的人,随后我也听到,有人反复联系前同事,话里话外像是在把责任重新分配。
我成了夹在中间的人。两边都不满意,两边都觉得我有问题。我既得罪了他们,也伤到了那些曾经支持我的人。
最后,事情还是结束了。非常不愉快。
我得到了什么呢。得罪了两边的人,伤害了曾经站出来替我说话的人。然后我发现这一切都无法挽回。那一晚,我对自己的鲁莽感到深深的自责。情绪冲昏了头脑,像个小孩子一样,急着证明,急着结束,急着把痛苦从胸口掏出来给别人看。结果只换来两败俱伤。
我甚至开始反问自己,我预想的结局到底是什么。是一个道歉,一个解释,一句真话,还是一个终于可以睡觉的夜晚。可到了最后,什么都没有。只有更大的噪音,和更难收拾的残局。
那天回家的路上,我在车里坐了很久很久。车外的世界还在动,灯在走,我却像被按在原地。然后我给前同事发了一段很长的消息,更像是一封迟到的道歉。
发完那段话,我才意识到一个更刺人的事实。有些话一旦说出口,就不再属于你了。它会在别人手里变形,会被拿去站队,会被拿去证明某个叙事。你站在中间,怎么解释都像狡辩,怎么沉默都像默认。
那一晚,我第一次认真地承认,我不是输给了他们的公关。我输给了自己的冲动。
那天之后,我删掉了 X。直到一周之后,世界仍然在运转,吃瓜的人已经散伙,一切又恢复了平静。
平静来得很快,快到像是什么都没发生过。可有些东西并不会因为热度退去就被证明是误会,它只是被遗忘了。
那个曾经说还会继续迭代维护的人,直到现在也没有看到对应的变化。对我来说,那句话更像是一种当时的安抚,而不是后续会兑现的计划。
而我也慢慢确定了一点,我很难再信任他们对外的表述。不是因为我想否定什么,而是因为我已经看过太多前后不一致。
不是因为真话太复杂,也不是因为真话太难讲。我能想到的解释是,真话一旦说出口,就会让体面露出裂缝。于是更多时候,他们选择沉默,选择拖延,选择用一句句看起来正确的话,把真实的部分藏起来。
在那一周里,我无意经过一座寺庙。我进去站了一会儿,很诚心地祈祷,希望自己能在安稳中找到一块生存地。
出来的时候,看见门口有两块石头,上面分别刻着两个字。
放下 接受
像是冥冥之中在告诉我,事情已经到这里了。
回去的路上我又路过一家书店。玻璃上印着一句话,我站在那儿看了很久。
希望你能记住我,记住我曾经这样存在过。 ——村上春树
我不知道为什么那一刻忽然很想哭。也许不是因为谁,也不是因为那个项目,而是因为我突然意识到,我真正害怕的并不是失去工作。
我害怕的是,我花了那么多时间和心力,最后连“好好告别”都不被允许。连一句真话都不能留下。连我曾经那样认真地存在过,也要被改写成不合时宜。
感谢你能看到这里。
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/experience/looking-back-at-myself
前几天收到通知,所在的团队解散了,我这段工作也一起画上句号。
虽然这个月一直隐隐觉得情况不太妙,但真的落在自己身上的那一刻,人还是会愣一下。有点空,有点失落,也有种「啊,原来已经走到这一步了」的感觉。
想了几天,还是决定把这一年多的经历和一些个人反思写下来,当作一个存档。以后哪天心态稳定了,再回头看,至少能更清楚地知道自己这段时间到底经历了什么、学到了什么。
最早接到这个机会时,我刚经历人生第一次裁员。那段时间整个人状态挺糟的,对未来特别迷茫,对自己也没什么信心,各种躯体反应、抑郁、焦虑、失眠一股脑地冒出来。
就在那时候,有人找我聊到这个项目。那会儿项目还非常早期,很多东西都停留在想法、脑图和讨论里,连像样的 demo 都还没有。但对当时的我来说,有人愿意拉我一把,给我一个能重新把注意力投进去的事情,本身就挺不一样的。
现在回头看这段经历,哪怕后来大家的路径和选择各不相同,我依然很感谢当时那次「拉一把」。它确实是在我比较低谷的一个时间点,给了我一个出口。
另一方面就是一个很简单的判断:我本身就对这种类别的产品很感兴趣。
我一直喜欢做 ToC 的产品,喜欢琢磨交互细节、体验和界面呈现。
再一次从零开始创造一个东西,其实是很酷的事情,而且自由度也很高。这个项目在早期也给了我很多发挥空间。
如果只看事情本身,这一年多其实过得很密。
因为项目很早期,很多基础的东西都需要从头搭起来,我主要做了这些:
那段时间,我基本是 设计、前端、产品 三件事一起干。经常是白天写代码、改交互,晚上还在想组件要不要再重构一下,周末偶尔继续打磨。
我对细节的执着,在那个阶段被放大得很明显。经常为了一个 1px 的对齐,或者一个 hover 状态,盯着屏幕看半天,不停调 spacing,调整节奏。
后面我的 commit 数一直往上爬,前端那块几乎所有角落都翻过一遍,一些历史遗留的问题也是趁着重构的时候顺手清。
有人跟我说,我这状态有点像把公司项目做成了个人项目。虽然有点玩笑的成分,但确实说明了当时那种「恨不得所有细节都先过一遍我眼睛」的投入。
从纯工程师视角看,这一年我学到的东西挺多的。
以前更多是「完成别人安排的需求」,现在多少对这个产品的形状、系统架构、体验节奏,有了一些自己的判断。
接下来这部分,就不局限在这个项目本身了,更多是我在这段时间里,对「怎么做一个产品」的一些感受。
我不打算给任何人下结论,只讲我自己以后会怎么做得不一样。
在早期阶段,我确实更偏向「先把东西做出来」「先做一个好玩的产品」,对商业化的思考会往后放。事后回头看,对我自己来说,教训是:
不一定一开始就要把每一块都推到极致,但至少要在心里留一条大致的路: 这个产品大概是为谁做的,这些人未来有没有「愿意为它长期买单」的可能。
如果脑子里完全没有这条路,日常决策就很容易被短期数据牵着走。很多看上去漂亮的增长,不一定是在为未来打基础,有时候只是让你在一条不太适合长期生存的路径上走得更远。
现在再做任何项目,只要心里有一点「它有机会变成一个长期产品」的念头,我都会尽量在比较早的阶段,先粗略想清楚:
这不只是这次经历的感受,其实是这几年所有项目叠加起来给我的提醒。
另一个对我很深的提醒是:激励是一种筛选器。
各种奖励、玩法,在短期内都非常有效,这点我在这个项目以及别的一些项目里都见过。
但它筛出来的,更多是「对激励敏感的人」,而不一定是「对产品本身有强需求的人」。
如果前期一直用这种方式去拉新,很容易导致:
以后再做类似的产品,我会更谨慎地区分:
这个反思同样不是在评价哪个项目好或不好,而是提醒自己:
不能只被短期数字牵着走,要时刻记住自己真正希望留下的那一拨人是谁。
这段经历里,还有一个挺扎心的感受:
大家都很努力,事情也很多, 但有时候你隐约知道,自己是在用努力填前面没想清楚留下的坑。
你越是全力往前冲,就越难停下来问自己一句:
如果照现在这个方向一路做到极致, 那个终点真的是我想要的吗?
这个问题不针对任何人,只是对我自己的一种提醒。以后我会更刻意留出一点「按暂停键」的空间,哪怕只是定期问自己这个问题。如果长期答不上来,可能就说明有哪里不太对劲了。
这几年回头看,会有一个很强的感觉:
有些窗口期是真的会关上, 关上之后再做同样的事,难度完全不一样。
不只是这一次,我接触过的好几个项目都有类似的影子。在某个阶段其实都迎来过一小波关注或讨论度,如果那时能更早地意识到:
后来的剧本可能会不太一样。当然,也未必就一定成功,但至少不是在热度退去之后再来补前面的课。
这件事给我的提醒是:
前面说了很多产品、商业、技术上的东西,但对我个人来说,这段经历还有一块很重要的是「人」。
不管后来每个人的选择如何,这件事本身我是一直记在心里的。
有时候就是这样。你在别人低谷的时候伸一把手,对那个人来说,意义会很长。
所以,对这段经历,我的情绪是很复杂的:
它既不是简单的「成功」或「失败」两个字可以概括的,更像是一次把很多课提前塞给我的密集训练。
短期内,要面对的还是很现实的问题。找下一份工作,解决生活,慢慢让自己从这段紧绷的节奏里抽离出来。
但可以确定的是,以后再谈「做一个可持续的产品」,我的态度会比以前更加谨慎,也会多一点敬畏。
如果你刚好也在经历类似的阶段,或者也在做一个早期项目,希望这些碎碎念能给你一点参考。哪怕只是让你提前避开我走过的一两个坑,也算是这段经历留下的价值之一。
谢谢你看到这里。
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/experience/put-this-year-in-a-drawer
前几天收到通知,所在的团队解散了,我这段工作也一起画上句号。
虽然这个月一直隐隐觉得情况不太妙,但真的落在自己身上的那一刻,人还是会愣一下。有点空,有点失落,也有种「啊,原来已经走到这一步了」的感觉。
想了几天,还是决定把这一年多的经历和一些个人反思写下来,当作一个存档。以后哪天心态稳定了,再回头看,至少能更清楚地知道自己这段时间到底经历了什么、学到了什么。
最早接到这个机会时,我刚经历人生第一次裁员。那段时间整个人状态挺糟的,对未来特别迷茫,对自己也没什么信心,各种躯体反应、抑郁、焦虑、失眠一股脑地冒出来。
就在那时候,有人找我聊到这个项目。那会儿项目还非常早期,很多东西都停留在想法、脑图和讨论里,连像样的 demo 都还没有。但对当时的我来说,有人愿意拉我一把,给我一个能重新把注意力投进去的事情,本身就挺不一样的。
现在回头看这段经历,哪怕后来大家的路径和选择各不相同,我依然很感谢当时那次「拉一把」。它确实是在我比较低谷的一个时间点,给了我一个出口。
另一方面就是一个很简单的判断:我本身就对这种类别的产品很感兴趣。
我一直喜欢做 ToC 的产品,喜欢琢磨交互细节、体验和界面呈现。
再一次从零开始创造一个东西,其实是很酷的事情,而且自由度也很高。这个项目在早期也给了我很多发挥空间。
如果只看事情本身,这一年多其实过得很密。
因为项目很早期,很多基础的东西都需要从头搭起来,我主要做了这些:
那段时间,我基本是 设计、前端、产品 三件事一起干。经常是白天写代码、改交互,晚上还在想组件要不要再重构一下,周末偶尔继续打磨。
我对细节的执着,在那个阶段被放大得很明显。经常为了一个 1px 的对齐,或者一个 hover 状态,盯着屏幕看半天,不停调 spacing,调整节奏。
后面我的 commit 数一直往上爬,前端那块几乎所有角落都翻过一遍,一些历史遗留的问题也是趁着重构的时候顺手清。
有人跟我说,我这状态有点像把公司项目做成了个人项目。虽然有点玩笑的成分,但确实说明了当时那种「恨不得所有细节都先过一遍我眼睛」的投入。
从纯工程师视角看,这一年我学到的东西挺多的。
以前更多是「完成别人安排的需求」,现在多少对这个产品的形状、系统架构、体验节奏,有了一些自己的判断。
接下来这部分,就不局限在这个项目本身了,更多是我在这段时间里,对「怎么做一个产品」的一些感受。
我不打算给任何人下结论,只讲我自己以后会怎么做得不一样。
在早期阶段,我确实更偏向「先把东西做出来」「先做一个好玩的产品」,对商业化的思考会往后放。事后回头看,对我自己来说,教训是:
不一定一开始就要把每一块都推到极致,但至少要在心里留一条大致的路: 这个产品大概是为谁做的,这些人未来有没有「愿意为它长期买单」的可能。
如果脑子里完全没有这条路,日常决策就很容易被短期数据牵着走。很多看上去漂亮的增长,不一定是在为未来打基础,有时候只是让你在一条不太适合长期生存的路径上走得更远。
现在再做任何项目,只要心里有一点「它有机会变成一个长期产品」的念头,我都会尽量在比较早的阶段,先粗略想清楚:
这不只是这次经历的感受,其实是这几年所有项目叠加起来给我的提醒。
另一个对我很深的提醒是:激励是一种筛选器。
各种奖励、玩法,在短期内都非常有效,这点我在这个项目以及别的一些项目里都见过。
但它筛出来的,更多是「对激励敏感的人」,而不一定是「对产品本身有强需求的人」。
如果前期一直用这种方式去拉新,很容易导致:
以后再做类似的产品,我会更谨慎地区分:
这个反思同样不是在评价哪个项目好或不好,而是提醒自己:
不能只被短期数字牵着走,要时刻记住自己真正希望留下的那一拨人是谁。
这段经历里,还有一个挺扎心的感受:
大家都很努力,事情也很多, 但有时候你隐约知道,自己是在用努力填前面没想清楚留下的坑。
你越是全力往前冲,就越难停下来问自己一句:
如果照现在这个方向一路做到极致, 那个终点真的是我想要的吗?
这个问题不针对任何人,只是对我自己的一种提醒。以后我会更刻意留出一点「按暂停键」的空间,哪怕只是定期问自己这个问题。如果长期答不上来,可能就说明有哪里不太对劲了。
这几年回头看,会有一个很强的感觉:
有些窗口期是真的会关上, 关上之后再做同样的事,难度完全不一样。
不只是这一次,我接触过的好几个项目都有类似的影子。在某个阶段其实都迎来过一小波关注或讨论度,如果那时能更早地意识到:
后来的剧本可能会不太一样。当然,也未必就一定成功,但至少不是在热度退去之后再来补前面的课。
这件事给我的提醒是:
前面说了很多产品、商业、技术上的东西,但对我个人来说,这段经历还有一块很重要的是「人」。
不管后来每个人的选择如何,这件事本身我是一直记在心里的。
有时候就是这样。你在别人低谷的时候伸一把手,对那个人来说,意义会很长。
所以,对这段经历,我的情绪是很复杂的:
它既不是简单的「成功」或「失败」两个字可以概括的,更像是一次把很多课提前塞给我的密集训练。
短期内,要面对的还是很现实的问题。找下一份工作,解决生活,慢慢让自己从这段紧绷的节奏里抽离出来。
但可以确定的是,以后再谈「做一个可持续的产品」,我的态度会比以前更加谨慎,也会多一点敬畏。
如果你刚好也在经历类似的阶段,或者也在做一个早期项目,希望这些碎碎念能给你一点参考。哪怕只是让你提前避开我走过的一两个坑,也算是这段经历留下的价值之一。
谢谢你看到这里。
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/tech/better-auth-multi-tenant-auth-concept
最近又把 Afilmory 捡起来做的,这次受 ChronoFrame 影响,我也决定给它加一层 CMS 能力,顺手往「做一个 CMS 的 SaaS 平台」这个方向靠一靠。
既然要做多租户 SaaS,身份验证这块就躲不过去。Better Auth 本身没有内建 multi-tenancy 的概念,所以整个用户模型、OAuth 流程、以及和 ORM 的边界都需要重新想一遍。
这篇主要是把我现在的构想和落地方案整理一下,后面如果再踩坑也方便回头翻。
一开始我想得比较直觉:
既然是多租户,那干脆让每个租户自己配置 OAuth / 鉴权,后端就给每个租户开一个 Better Auth 实例:
这种做法的问题其实也很明显:
所以这条路基本可以确定是走不远的。
后来想了一圈,感觉更合理的一种模型是:
Auth Provider(Better Auth 实例)只有一个,是全局单例。但在业务层面,同一个人可以在多个租户下拥有不同的身份。
比如:Innei 在 Tenant A 里是 Admin,在 Tenant B 里只是一个普通 User;Cupchino 在 Tenant A 是 User,在 Tenant B 刚好是 Admin。
也就是说:「账号」是同一个 GitHub / Email,但落到租户里,都是不同的 user 记录,权限、数据都完全隔离。
这个关系可以简单理解成:tenant 有很多 authuser,同一个 GitHub 账号,可以在多个 tenant 下绑定多个 authuser。
Not support render this content in RSS render
即便是使用同一个账户登录后在不同的租户下都会是一个不同的用户。不同租户下的数据完全隔离,但是 auth provider 却是一个单例。
在数据库定义上,处理 better-auth 基准的字段之外,需要额外增加一个 tenantId 标识。
// Custom users table (Better Auth: user)
// Note: Multi-tenant design - same email can exist in different tenants
export const authUsers = pgTable(
'auth_user',
{
// Add this
role: userRoleEnum('role').notNull().default('user'),
tenantId: text('tenant_id').references(() => tenants.id, {
onDelete: 'set null',
}),
},
(t) => [
// Multi-tenant: same email can exist in different tenants
unique('uq_auth_user_tenant_email').on(t.tenantId, t.email),
index('idx_auth_user_tenant').on(t.tenantId),
],
)
// Custom sessions table (Better Auth: session)
export const authSessions = pgTable('auth_session', {
// Add this
tenantId: text('tenant_id').references(() => tenants.id, {
onDelete: 'set null',
}),
})
// Custom accounts table (Better Auth: account)
// Note: Multi-tenant design - same social account can exist in different tenants
export const authAccounts = pgTable(
'auth_account',
{
tenantId: text('tenant_id').references(() => tenants.id, {
onDelete: 'set null',
}),
},
(t) => [
// Multi-tenant: same social account can exist in different tenants
unique('uq_auth_account_tenant_provider').on(
t.tenantId,
t.providerId,
t.accountId,
),
index('idx_auth_account_tenant').on(t.tenantId),
],
)
export const tenants = pgTable(
'tenant',
{
id: snowflakeId,
slug: text('slug').notNull(),
name: text('name').notNull(),
},
(t) => [unique('uq_tenant_slug').on(t.slug)],
)
Not support render this content in RSS render
在 better-auth 的实例初始化中,需要额外定义扩展字段:
betterAuth({
session: {
freshAge: 0,
additionalFields: {
tenantId: { type: 'string', input: false },
},
},
account: {
additionalFields: {
tenantId: { type: 'string', input: false },
},
},
user: {
additionalFields: {
tenantId: { type: 'string', input: false },
role: { type: 'string', input: false },
creemCustomerId: { type: 'string', input: false },
},
},
})
这里所有 tenantId 都标成 input: false,意思是:外部请求不能直接写这些字段;只能通过我们自己的 hooks / adapter 在服务端填充,避免被前端篡改。
只定义字段还不够,还需要在「创建 user / session / account」的时候,把租户信息真正写进去。
核心就是:在这些 before 钩子里,通过 ensureTenantId() 拿到当前请求上下文对应的租户,然后写到数据里。
betterAuth({
databaseHooks: {
user: {
create: {
before: async (user) => {
const tenantId = await ensureTenantId()
if (!tenantId) {
throw new APIError('BAD_REQUEST', {
message: 'Missing tenant context during account creation.',
})
}
return {
data: {
...user,
tenantId, // 设置租户 ID
role: user.role ?? 'user',
},
}
},
},
},
session: {
create: {
before: async (session) => {
const tenantId = this.resolveTenantIdFromContext()
const fallbackTenantId =
tenantId ?? session.tenantId ?? (await ensureTenantId())
return {
data: {
...session,
tenantId: fallbackTenantId ?? null, // 设置租户 ID
},
}
},
},
},
account: {
create: {
before: async (account) => {
const tenantId = this.resolveTenantIdFromContext()
const resolvedTenantId = tenantId ?? (await ensureTenantId())
if (!resolvedTenantId) {
return { data: account }
}
return {
data: {
...account,
tenantId: resolvedTenantId, // 设置租户 ID
},
}
},
},
},
},
})
做到这里,写入这条链路基本是多租户感知的了。同一个 GitHub 登录到不同子域名,就会在各自的租户下创建独立的 user / account / session。
真正比较坑的是 读 的这部分。
Better Auth 在 OAuth 回调时,会做类似这样的事情:
code 和 state;state 找到之前那次登录请求;email / providerId / accountId 后,去 DB 里查用户。问题就在第 3 步: Better Auth 默认只会按 email / provider 查用户,并不会自动加上 tenantId。
这会导致一个很危险的情况:
user@tenantAemail + provider 查tenantA 的那条也就是说,上游业务层明明已经区分了租户,但到了 Better Auth 内部这层,它是看不到 tenant 的。 只要 ORM 层不管租户,框架就没法帮你保证隔离。
Not support render this content in RSS render
既然 Better Auth 本身不知道 tenantId,那就只能从适配器这层把它「强行带进去」。
思路是这样:写一个 tenantAwareDrizzleAdapter,把 multi-tenant 的边界下沉到 ORM / Adapter 层。
这个适配器的职责:
在每次查询前,调用 ensureTenantId() 拿到当前租户;
对于 user / account 相关的查询,自动追加:
where ... AND tenant_id = currentTenantId
对于写入,自动把 tenantId 补到数据里(如果上层没写的话)。
这样一来,在 Better Auth 看来:
tenant_id = ... 条件;实现细节就不展开了,大致就是在 Drizzle 的 query builder 一层做 wrap,把所有跟用户相关的查询 /写入都套上 tenant 条件。
对应的代码在这里:
Not support render this content in RSS render
在多租户、多子域名的 SaaS 里,一个很常见的诉求是:
a.example.comb.example.com这两个租户都想复用同一套 GitHub(或其他)OAuth 应用,而不是每个子域名各配一套。
问题在于,大多数 OAuth Provider(比如 GitHub)在配置回调地址(redirect_uri)时,都要求是精确匹配,不能写成通配符,比如:
https://*.example.com/api/auth/callback/githubhttps://auth.example.com/api/auth/callback/github也就是说,在 Provider 那边,你只能填一个固定 URL。但在我们这边,又希望最终的回调是落到各个租户自己的域名上:
https://a.example.com/api/auth/callback/githubhttps://b.example.com/api/auth/callback/github所以这里需要引入一个专门做 OAuth 回调分发的网关,比如:
https://auth.example.com/api/auth/callback/github这样,Provider 侧只认一个「入口」,网关负责把这个入口再按租户「分流」出去。
网关怎么知道这次登录属于哪个租户?
当 GitHub 把用户重定向回:
https://auth.example.com/api/auth/callback/github?code=...&state=...
的时候,请求里看不到诸如 tenant=a 这种显式信息。我们又不想在网关上维护什么 session 或额外的状态。
这里可以利用 OAuth 协议里本来就存在的 state 参数来解决:让上游的认证服务负责把「租户信息」塞进 state 里,网关只负责解包并转发。
一个典型流程大概是这样(对应 @oauth-gateway 这个服务的设计):
a.example.com 点击「使用 GitHub 登录」。be/apps/core 里的 Better Auth)在构造 GitHub 授权 URL 的时候,不是直接生成一个 state,而是:
innerState(给 Better Auth 自己用){ tenant: "a", innerState: "<better-auth-state>" }wrappedState浏览器被重定向到 GitHub 授权页面,之后 GitHub 回调回统一地址:
https://auth.example.com/api/auth/callback/github?code=...&state=<wrappedState>
state,拿到:
tenant(比如 "a")innerState(要还给 Better Auth 的那份)tenant 和基础域名(比如 example.com)拼出目标地址:
https://a.example.com/api/auth/callback/github?code=...&state=<innerState>网关直接返回一个 302:
Location: https://a.example.com/api/auth/callback/github?code=...&state=<innerState>
从 a.example.com 自己的后端视角看,只是收到了一个完全正常的 GitHub OAuth 回调;它只关心 code 和 state=<innerState>,根本不需要知道中间还经过了一个网关。
Not support render this content in RSS render
目前这套设计,大概是把多租户问题拆成了三层:
数据模型层
每个租户有自己的 user / account / session,
唯一键全部变成 (tenantId, …)。
ORM / Adapter 层
用 tenantAwareDrizzleAdapter 把 tenantId 自动拼进所有查询 / 写入,
对 Better Auth 这种上层框架来说是透明的。
OAuth 流程层
借助 state + OAuth Gateway,在多域名、多租户的场景下共享一套 Provider 配置,
同时又能把回调正确落回对应租户的后端。
感谢你看到这里。如有不足欢迎在评论区指出。
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/experience/after-leaving-folo-backup
前几天收到通知,Folo 解散了,我这段工作也一起画上句号。
虽然这个月一直有不太妙的预感,但真的落在自己身上的那一刻,还是会愣一下,有点空,有点失落,也有种「啊,真就走到这一步了」的感觉。
想了几天,还是决定把这一年多的经历和反思写下来,当作一个存档。以后哪天心态稳定了,回头再看,应该会比较清楚自己这一段到底经历了什么。
最早接到 Folo 这个机会时,我刚经历了人生第一次裁员,整个人状态挺糟的,对未来特别迷茫,对自己也没什么信心,出现了严重的躯体反应,抑郁和焦虑,整夜整夜的失眠。那个时候,DIYgod 找我聊了 Folo 的事情,那个时候项目刚开始,连 demo 也没有,当时没想那么多,只记得那段时间我整个人挺焦虑的,能有人拉我一把,就已经很不一样了。所以现在回头看这段经历,哪怕项目最后没有按大家一开始想的那样走下去,我对 DIY 其实还是挺感激的——那确实是在我比较低谷的一个时间点,给了我一个出口。
然后就是那种比较简单的判断:做这个项目本身我也感兴趣。我很喜欢做 ToC 的产品,一直以来。
老实说,再一次从零开始创造一个产品也是挺酷的,而且很有自由度。
如果只看事情本身,这一年多过得其实挺密。
早期很多基础的东西,基本都是我一点点搭起来的:
同时我还兼着产品,一边写代码一边想功能,很多功能其实是带了不少个人偏好的。打磨细节也是我非常执着的一个点,经常真的是为了一个 1px 盯着屏幕看半天,调 spacing、对齐、hover 状态这些小东西。
那段时间基本上是:设计、前端、产品我都在干。周末有时候还在琢磨组件要不要再重构一下,或者把哪个交互再改顺一点。
虽然每天都会干到很晚,有时候周末也在打磨,但那个阶段整体还是挺开心的,有那种「在把一个东西从一团糊糊慢慢变顺眼」的满足感。
后面我的 commit 数也爬到仓库第一了,前端那一块几乎所有角落我都翻过一遍,很多历史遗留的地方也是趁重构的时候顺手清掉。
有群友跟我说,我这状态有点像面包,把公司项目做成了个人项目,这话虽然有点玩笑的成分,但当时确实是那种「恨不得所有细节都先过一遍我眼睛」的状态。
从纯工程师视角看,这一年我学到的东西挺多。以前只是「写别人安排的需求」,现在多少对整个产品的形状和系统有了一些自己的判断。
当然,光技术上长进不代表项目能活下去。
Folo 最大的坑,其实在一开始就埋下了:我们起步的时候,并没有认真想过商业化。
早期的 Folo 带点 Web3 的影子,搞过邀请码、搞过活跃激励,拉过一批那种对玩法和「赚点什么」很感兴趣的用户。
在那个时间点,这种判断也不算离谱,只是现在回头看,问题其实挺大:
后面环境变了,我们开始往 Web2 + AI 这个方向靠,想把它变成一个「正常的订阅制阅读 / 时间线工具」。这时候割裂感就出来了:
中间这段过渡期挺别扭的:老用户觉得你变了,新用户又不知道你以前是谁,两边都没完全站稳。
更讽刺的是,Folo 曾经「有点小辉煌」的那段时间,整体热度很高,数据也还可以,圈子里讨论不少,甚至有很多人在闲鱼出售大量邀请码。
没有认真设计商业化路径,也没有趁着那波势头去融一轮钱,让项目多一点缓冲时间。现在看,那大概是这个项目离「也许能活久一点」最近的一次,只是当时谁都没把它当回事。
等热度退下去,我们才开始回头想商业化和融资,那时候难度已经完全不是一回事了。在这个阶段,当大家开始严肃讨论「订阅」「营收」「可持续」这些问题时,之前没想清楚的东西就一起堆过来了:
那段时间的感觉挺真切的:你以为自己是在从 0 开始做付费,实际上更像是在从负数一点点往 0 爬。
我尽量简单讲,不写成那种鸡汤总结。
一开始我们确实是抱着做玩具的心态去做的,甚至觉得:
现在不缺钱就不考虑商业化,也不为后续铺路,直接封死路口
但现实就是:如果脑子里完全没有一个「谁会掏钱、为什么掏」的粗略想法,那么你在日常做决策的时候,很容易被短期数据带着跑。
很多「看上去很不错的增长」不一定是在为以后做准备,有时候只是让你在一条不太对的路上越走越远。
以后再做任何项目,只要心里有一点「它有机会商业化」的念头,我应该都会尽量早点把商业模式大致想一想,再说是不是要认真做下去。
所以,我最近做的 Afilmory Cloud,不管有没有人用我都会放开付费计划的口子。
这里再打一下广告:https://afilmory.art 欢迎来用。
这个教训应该会刻在我脑子里挺久。
各种代币、积分、奖励、活动,这些东西短期非常有效。 但它的本质是一个「筛选器」:
这两类人不完全重合。
当你后期要靠订阅、靠长期价值来活的时候,前者才是关键用户。
但如果前期一直在放大后者,那后面就会非常难办。
这段时间我经常有这种感觉:
但内心深处其实知道,现在的很多努力是在补前面那些没想清楚留下的坑。有时候你越投入,越难有力气抽身去想「要不要换条路」。
这件事对我最大的提醒就是:
忙不是问题,关键是要定期停一下,问自己:
如果我们照现在的方向一路做下去,哪怕做到极致,那个终点是我能接受的吗?
如果这个问题迟迟回答不上来,那多半说明有不对劲的地方了。
这两年回头看,会有一个很强的感觉:有些窗口期是真的会关上,而且关上以后,再做同样的事情,难度是完全不一样的。
Folo 在那段热度最高的时候:
如果那时候我们不把它当玩具,而是稍微认真一点:
后来事情的走向可能会不一样。
当然也不一定就能成功,但至少不是现在这种「热度没了再去补前面的课」。
这件事给我的提醒就是,产品有节奏,市场也有自己的节奏:
以后再做一个项目,如果感觉它处在一个「可能是风口边缘」的位置,我大概率会更早去想:
要不要趁这个时间点做点更重的决定,而不是一味地觉得「反正先当玩具做,想钱以后再说」。
前面讲了很多产品、商业、技术上的东西,但对我个人来说,这段经历里面,还有一块很重要的是「人情」。
不管项目最后是什么结果,这件事本身我是一直记在心里的。
有时候就是这样,你在别人低谷的时候伸一把手,对那个人来说,意义会很长。
所以即使团队解散了,我对这段经历的情感并不是简单的「失败」「浪费时间」,更多是一种复杂的混合:
短期要面对的,还是比较现实的问题:找下一份工作、解决生活、慢慢把心态从这个项目里抽出来。
之后,对“做一个可持续的产品”这件事,会比之前更谨慎,也更有敬畏感。
感谢能够读到这里,如果有什么不错的机会的话,也欢迎评论区撩。
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/experience/after-leaving-folo
文中所有内容都只是我个人的经历和感受,不代表 Folo、团队或任何投资人的立场。
这篇文章是经过 AI 润色和调整的。
前几天收到通知,所在的团队解散了,我这段工作也一起画上句号。
虽然这个月一直隐隐觉得情况不太妙,但真的落在自己身上的那一刻,人还是会愣一下:有点空、有点失落,也有种「啊,原来已经走到这一步了」的感觉。
想了几天,还是决定把这一年多在 Folo 的经历和一些个人反思写下来,当作一个存档。以后哪天心态稳定了,再回头看,至少能更清楚地知道自己这段时间到底经历了什么、学到了什么。
最早接到 Folo 这个机会时,我刚经历人生第一次裁员。那段时间整个人状态挺糟的,对未来特别迷茫,对自己也没什么信心,各种躯体反应、抑郁、焦虑、失眠一股脑地冒出来。
就在那时候,DIY 找我聊到 Folo。那会儿项目还非常早期,很多东西都停留在想法、脑图和讨论里,连像样的 demo 都还没有。但对当时的我来说,有人愿意拉我一把,给我一个能重新把注意力投进去的事情,本身就挺不一样的。
现在回头看这段经历,哪怕后来大家的路径和选择各不相同,我依然很感谢当时这通「拉一把」:那确实是在我比较低谷的一个时间点,给了我一个出口。
另一方面就是一个很简单的判断:我本身就对这种阅读 / 时间线类的产品很感兴趣。
我一直喜欢做 ToC 的产品,喜欢琢磨交互细节、体验和界面呈现。
再一次从零开始创造一个东西,其实是很酷的事情,而且自由度也很高。Folo 在早期也给了我很多发挥空间。
如果只看事情本身,这一年多其实过得很密。
因为 Folo 很早期,很多基础的东西都需要从头搭起来,我主要做了这些:
那段时间,我基本是 设计、前端、产品 三件事一起干。 经常是:白天写代码、改交互,晚上还在想组件要不要再重构一下,周末偶尔继续打磨。
我对细节的执着,在那个阶段被放大得很明显: 经常为了一个 1px 的对齐,或者一个 hover 状态,盯着屏幕看半天,不停调 spacing、调整节奏。
后面我的 commit 数一直往上爬,前端那块几乎所有角落都翻过一遍,一些历史遗留的问题也是趁着重构的时候顺手清。
有人跟我说,我这状态有点像把公司项目做成了个人项目。虽然有点玩笑的成分,但确实说明了当时那种「恨不得所有细节都先过一遍我眼睛」的投入。
从纯工程师视角看,这一年我学到的东西挺多的。
以前更多是「完成别人安排的需求」,现在多少对 Folo 这个产品的形状、系统架构、体验节奏,有了一些自己的判断。
接下来这部分,就不局限在 Folo 这个项目本身了,更多是我在这段时间里,对「怎么做一个产品」的一些感受。
我不打算给任何人下结论,只讲我自己以后会怎么做得不一样。
在早期阶段,我确实更偏向「先把东西做出来」「先做一个好玩的产品」,对商业化的思考会往后放。事后回头看,对我自己来说,教训是:
不一定一开始就要把每一块都推到极致,但至少要在心里留一条大致的路: 这个产品大概是为谁做的,这些人未来有不存在「愿意为它长期买单」的可能。
如果脑子里完全没有这条路,日常决策就很容易被短期数据牵着走。很多看上去漂亮的增长,不一定是在为未来打基础,有时候只是让你在一条不太适合长期生存的路径上走得更远。
现在再做任何项目,只要心里有一点「它有机会变成一个长期产品」的念头,我都会尽量在比较早的阶段,先粗略想清楚:
这不只是对 Folo 的感受,其实是这几年所有项目叠加起来给我的提醒。
另一个对我很深的提醒是:激励是一种筛选器。
各种奖励、玩法,在短期内都非常有效,这点我在 Folo 以及别的一些项目里都见过。
但它筛出来的,更多是「对激励敏感的人」,而不一定是「对产品本身有强需求的人」。
如果前期一直用这种方式去拉新,很容易导致:
以后再做类似的产品,我会更谨慎地区分:
这个反思同样不是在评价哪个项目好或不好,而是提醒自己:
不能只被短期数字牵着走,要时刻记住自己真正希望留下的那一拨人是谁。
这段经历里,还有一个挺扎心的感受:
大家都很努力,事情也很多, 但有时候你隐约知道,自己是在用努力填前面没想清楚留下的坑。
你越是全力往前冲,就越难停下来问自己一句:
如果照现在这个方向一路做到极致, 那个终点真的是我想要的吗?
这个问题不针对任何人,只是对我自己的一种提醒: 以后我会更刻意留出一点「按暂停键」的空间,哪怕只是定期问自己这个问题。 如果长期答不上来,可能就说明有哪里不太对劲了。
这几年回头看,会有一个很强的感觉:
有些窗口期是真的会关上, 关上之后再做同样的事,难度完全不一样。
不只是 Folo,我接触过的好几个项目都有类似的影子:在某个阶段其实都迎来过一小波关注或讨论度,如果那时能更早地意识到:
后来的剧本可能会不太一样——当然,也未必就一定成功,但至少不是在热度退去之后再来补前面的课。
这件事给我的提醒是:
前面说了很多产品、商业、技术上的东西,但对我个人来说,这段经历还有一块很重要的是「人」。
不管后来每个人的选择如何,这件事本身我是一直记在心里的。
有时候就是这样:你在别人低谷的时候伸一把手,对那个人来说,意义会很长。
所以,对这段在 Folo 的经历,我的情绪是很复杂的:
它既不是简单的「成功」或「失败」两个字可以概括的,更像是一次把很多课提前塞给我的密集训练。
短期内,要面对的还是很现实的问题:找下一份工作、解决生活、慢慢让自己从这段紧绷的节奏里抽离出来。
但可以确定的是,以后再谈「做一个可持续的产品」,我的态度会比以前更加谨慎,也会多一点敬畏。
如果你刚好也在经历类似的阶段,或者也在做一个早期项目,希望这些碎碎念能给你一点参考——哪怕只是让你提前避开我走过的一两个坑,也算是这段经历留下的价值之一。
谢谢你看到这里。
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/notes/201
前几天收到通知,Folo 解散了,我这段工作也一起画上句号。
虽然这个月一直有不太妙的预感,但真的落在自己身上的那一刻,还是会愣一下,有点空,有点失落,也有种「啊,真就走到这一步了」的感觉。
想了几天,还是决定把这一年多的经历和反思写下来,当作一个存档。以后哪天心态稳定了,回头再看,应该会比较清楚自己这一段到底经历了什么。
最早接到 Folo 这个机会时,我刚经历了人生第一次裁员,整个人状态挺糟的,对未来特别迷茫,对自己也没什么信心,出现了严重的躯体反应,抑郁和焦虑,整夜整夜的失眠。那个时候,DIYgod 找我聊了 Folo 的事情,那个时候项目刚开始,连 demo 也没有,当时没想那么多,只记得那段时间我整个人挺焦虑的,能有人拉我一把,就已经很不一样了。所以现在回头看这段经历,哪怕项目最后没有按大家一开始想的那样走下去,我对 DIY 其实还是挺感激的——那确实是在我比较低谷的一个时间点,给了我一个出口。
然后就是那种比较简单的判断:做这个项目本身我也感兴趣。我很喜欢做 ToC 的产品,一直以来。
老实说,再一次从零开始创造一个产品也是挺酷的,而且很有自由度。
如果只看事情本身,这一年多过得其实挺密。
早期很多基础的东西,基本都是我一点点搭起来的:
同时我还兼着产品,一边写代码一边拍脑袋想功能,很多功能其实是带了不少个人偏好的。打磨细节也是我非常执着的一个点,经常真的是为了一个 1px 盯着屏幕看半天,调 spacing、对齐、hover 状态这些小东西。
那段时间基本上是:设计、前端、产品我都在干。周末有时候还在琢磨组件要不要再重构一下,或者把哪个交互再改顺一点。
虽然每天都会干到很晚,有时候周末也在打磨,但那个阶段整体还是挺开心的,有那种「在把一个东西从一团糊糊慢慢变顺眼」的满足感。
后面我的 commit 数也爬到仓库第一了,前端那一块几乎所有角落我都翻过一遍,很多历史遗留的地方也是趁重构的时候顺手清掉。
有群友跟我说,我这状态有点像面包,把公司项目做成了个人项目,这话虽然有点玩笑的成分,但当时确实是那种「恨不得所有细节都先过一遍我眼睛」的状态。
从纯工程师视角看,这一年我学到的东西挺多。以前只是「写别人安排的需求」,现在多少对整个产品的形状和系统有了一些自己的判断。
当然,光技术上长进不代表项目能活下去。
Folo 最大的坑,其实在一开始就埋下了:我们起步的时候,并没有认真想过商业化。
早期的 Folo 带点 Web3 的影子,搞过邀请码、搞过活跃激励,拉过一批那种对玩法和「赚点什么」很感兴趣的用户。
在那个时间点,这种判断也不算离谱,只是现在回头看,问题其实挺大:
后面环境变了,我们开始往 Web2 + AI 这个方向靠,想把它变成一个「正常的订阅制阅读 / 时间线工具」。这时候割裂感就出来了:
中间这段过渡期挺别扭的:老用户觉得你变了,新用户又不知道你以前是谁,两边都没完全站稳。
更讽刺的是,Folo 曾经「有点小辉煌」的那段时间,整体热度很高,数据也还可以,圈子里讨论不少,甚至有很多人在闲鱼出售大量邀请码。
没有认真设计商业化路径,也没有趁着那波势头去融一轮钱,让项目多一点缓冲时间。现在看,那大概是这个项目离「也许能活久一点」最近的一次,只是当时谁都没把它当回事。
等热度退下去,我们才开始回头想商业化和融资,那时候难度已经完全不是一回事了。在这个阶段,当大家开始严肃讨论「订阅」「营收」「可持续」这些问题时,之前没想清楚的东西就一起堆过来了:
那段时间的感觉挺真切的:你以为自己是在从 0 开始做付费,实际上更像是在从负数一点点往 0 爬。
我尽量简单讲,不写成那种鸡汤总结。
一开始我们确实是抱着做玩具的心态去做的,甚至觉得:
现在不缺钱就不考虑商业化,也不为后续铺路,直接封死路口
但现实就是:如果脑子里完全没有一个「谁会掏钱、为什么掏」的粗略想法,那么你在日常做决策的时候,很容易被短期数据带着跑。
很多「看上去很不错的增长」不一定是在为以后做准备,有时候只是让你在一条不太对的路上越走越远。
以后再做任何项目,只要心里有一点「它有机会商业化」的念头,我应该都会尽量早点把商业模式大致想一想,再说是不是要认真做下去。
所以,我最近做的 Afilmory Cloud,不管有没有人用我都会放开付费计划的口子。
这里再打一下广告:https://afilmory.art 欢迎来用。
这个教训应该会刻在我脑子里挺久。
各种代币、积分、奖励、活动,这些东西短期非常有效。 但它的本质是一个「筛选器」:
这两类人不完全重合。
当你后期要靠订阅、靠长期价值来活的时候,前者才是关键用户。
但如果前期一直在放大后者,那后面就会非常难办。
这段时间我经常有这种感觉:
但内心深处其实知道,现在的很多努力是在补前面那些没想清楚留下的坑。有时候你越投入,越难有力气抽身去想「要不要换条路」。
这件事对我最大的提醒就是:
忙不是问题,关键是要定期停一下,问自己:
如果我们照现在的方向一路做下去,哪怕做到极致,那个终点是我能接受的吗?
如果这个问题迟迟回答不上来,那多半说明有不对劲的地方了。
这两年回头看,会有一个很强的感觉:有些窗口期是真的会关上,而且关上以后,再做同样的事情,难度是完全不一样的。
Folo 在那段热度最高的时候:
如果那时候我们不把它当玩具,而是稍微认真一点:
后来事情的走向可能会不一样。
当然也不一定就能成功,但至少不是现在这种「热度没了再去补前面的课」。
这件事给我的提醒就是,产品有节奏,市场也有自己的节奏:
以后再做一个项目,如果感觉它处在一个「可能是风口边缘」的位置,我大概率会更早去想:
要不要趁这个时间点做点更重的决定,而不是一味地觉得「反正先当玩具做,想钱以后再说」。
前面讲了很多产品、商业、技术上的东西,但对我个人来说,这段经历里面,还有一块很重要的是「人情」。
不管项目最后是什么结果,这件事本身我是一直记在心里的。
有时候就是这样,你在别人低谷的时候伸一把手,对那个人来说,意义会很长。
所以即使团队解散了,我对这段经历的情感并不是简单的「失败」「浪费时间」,更多是一种复杂的混合:
短期要面对的,还是比较现实的问题:找下一份工作、解决生活、慢慢把心态从这个项目里抽出来。
之后,对“做一个可持续的产品”这件事,会比之前更谨慎,也更有敬畏感。
感谢能够读到这里,如果有什么不错的机会的话,也欢迎评论区撩。

该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/notes/200
又是一个月。我想以后尽量保证每个月能写一篇手记,至少记录一下自己的生活历程。虽然我的生活依旧混乱而枯燥,状态也并不算好,未来的变数更是大得让人不安——总之,又是在焦虑之中。那就慢慢说来吧。
有了 AI 之后,很多想法能更快落地。这种速度有时候让人觉得久违的兴奋,像是突然抓住一根绳子,可以朝某个方向继续拉下去。
上上个月提到我正打算重写 Mix Space,项目其实已经开了头,但因为其他更“重要”的项目,又不得不先搁置一段时间。所谓重要,其实也都还是 side project。怎么让这些项目变现,我现在也仍在探索中。
前天些天和厂长也是进行了一段时间的黑客马拉松,突然的想法复刻一个 trustMRR,但是是基于 App Connection 的数据。原因也是还没人做,然后 trustMRR 上了几天就赚了好多钱。我们要尽快做出来。
最后的结果是,由于前期没有调研清楚,导致最后不了了之了。虽然现在还是上线了 Apple MRR,但效果没有预期的那么好。不过这次确实吸取了经验——调研真的很重要,不然好几晚的熬夜就白费了。
不过现在用 AI 做 UI 确实越来越快了,Apple 的设计花了不久就搞出来了。只是再强的 AI 也只是加速器,细节部分还是得靠人去打磨。
![]()
我现在最主要再做的项目还是做 afilmory。前段日子,这个项目被抄了 UI,然后做了一个 Nuxt 版本的带 server 的。我感觉到有点压力了。原本我是不想做 server 的,这下不得不做了。花了两周的业余时间指挥 AI,把整个 dashboard + server 写出来了,我是完全按照 SaaS 去设计的,代码目前是开源的,但是应该不会写任何文档。我想通过 SaaS 的中心化的方式,让更多的人通过一个实例管理更多的 afilmory,后面就可以做一个大众的画廊。当然这个服务从 day 1 开始注定不会是 Free 的。
https://github.com/Afilmory/Afilmory
基础功能算是 ready 了,但还不够上线。我也顺便整理一下目前的成果。
:::gallery
![]()
![]()
![]()
:::
dashboard 采用 Linear design language,web 则是 Glassmorphic Depth Design System。不过 web 的 UI 后面应该会再进行一波大改,我不太想让别人轻易抄过去继续用。
《羊蹄山之魂》这个游戏真的挺好玩。前作对马岛我也通关了,但最近对比了一下,其实感觉完全是两款不同的游戏。除了美术一致,玩法几乎全改了。打击感更好,花样更多,完全没有罐头味,而且风景绝美。
目前我玩了三十多个小时,刚到第二章。每次做任务时都会被狐狸或金鸟吸引跑偏,总之主线完全不着急。等我通关之后,也许能再深入聊一聊。
最近又因为工作的事情焦虑,遇到一些调整,可能年前要重新找工作了。如果有合适的机会也可以推荐一下。对于工作稳定这件事还是太难了,总是会遇到意想不到的变数。
有时候我会突然停下来,想一想自己现在的生活轨迹:重复、枯燥、像是在原地绕圈,怎么走都走不出既定的范围。
意义感这种东西,好像越来越难抓住。偶尔甚至会觉得未来的路,不知道该通往哪儿。
还有那个静悄悄的孤独,一直都在。不是喧闹的悲伤,而是一种温度很低的空白,让人意识到很多时候我确实是一个人在走。
想到父母终会老去,而我可能只能陪他们走完最后一段路,就会突然涌起一种说不出口的无力感。甚至偶尔也会浮现一个念头:等他们离开之后,我好像也不会再有什么必须坚持下去的理由。

该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/notes/199
TIP 本文图片皆为随手拍,下面的链接可以查看本次旅行中较为合格的出片合集(已调色)。
来到世界的第二十五年,第一次踏上了别的国土。
人生第一次出国,前往新加坡。开启一段长达五天的旅途。
十月十一日出发,错峰出行。
下午四点到达樟宜机场。晚餐和朋友们吃了松发肉骨茶。
![]()
该店也是狮城的一大特色,机场就有,去的时候还有很多人排队。黑胡椒味的排骨汤挺特别的,汤是可以免费续的。
吃饱喝足,在星耀樟宜逛了一下,首先打卡网红瀑布。
![]()
然后去到了观景台,使用广角拍下了他的全貌。
![]()
另外这里还有滑滑梯可以玩。
酒店 Check In 之后,去小印度逛了下。那片地方第一感受就是非常的混乱,确实有种来到印度的感觉。查了一下历史,之所以被称为小印度,是当年英国殖民统治期间,印度人居住的地方。
![]()
在此之前,我一直以为新加坡是一个高度文明并且法律严苛的城市,制定了非常多的罚款,其中就包括对横穿马路的罚款。而真正来到这里,你看到的是许许多多的人横穿马路。这里的道路,很少设有人行道,大概只有在一个比较的大的十字路口才有,很多双向道路只能通过横穿马路的形式穿过。
多数情况下,坡的交通并不拥堵,井然有序。最重要的原因可能是在新加坡用车成本很高,除了车辆需要进口之外,还需要支付巨额的用车证。我在街上几乎找不到在中国满大街的特斯拉,而在这里一辆标续的 Model 3 需要将近 20W 新币。在路上跑的基本还都是很老的油车,电车并不多见。
这里的打车并不便宜。为了保护当地就业,也只有新加坡公民才能开网约车或出租车。
第二天的行程。前往鱼尾狮公园。
![]()
这一天是周日,傍晚时分,人依旧非常多,很多排队拍接水照片。
鱼尾狮的对面都是金沙酒店了。这里大概就是类似上海的外滩了。
![]()
坐船去对面,去苹果店摸了一下 air,真的好薄好喜欢。
![]()
水上玻璃球。
滨海湾金沙中的室内划艇。
![]()
赌场。
晚上吃的印尼椰浆饭,在食阁里面,价格实惠。13 新左右。椰浆泡过的米,吃起来挺香。这家店也是米其林指南推荐。
![]()
新加坡遍地都是美食,哪怕是食阁也有很多小店都是米其林指南推荐或是曾经被推荐过(新加坡食阁:通常是开放式、有屋顶但不封闭的公共餐饮区,由政府或大型物业统一管理。座位是共享的,几十个摊位围绕而设。食阁类似中国的美食广场、小吃街、夜市档口区)。
食阁是新加坡饮食文化的核心象征,聚集了马来、中餐、印度菜等多民族美食。也正是这样在这里可以吃到各地的美食。
晚上去了牛车水。牛车水的英文名是 Chinatown,意为唐人街。
在19世纪的新加坡,还没有自来水系统。 那时候,住在这一带的华人居民——主要是福建人和潮州人——要靠牛车运水从安祥山(Ann Siang Hill)或珍珠山(Pearl’s Hill)一带的水源处,把水拉回家中使用。
所以这一区域便被称为 “牛车水”(Hokkien:Gu Chia Chwee、潮州话:Gau Chia Chui),字面意思就是「用牛车运水的地方」。
当时的新加坡是英国殖民地,英国人实行 “族群分区居住”(Ethnic Enclaves) 政策:
此时的牛车水还在庆祝中秋,正巧此时也是印度人庆祝过年的节日。所以在这里几乎也是看到非常多的印度人。
![]()
![]()
![]()
![]()
![]()
War Memorial Park
圣安德鲁大教堂
下午天实在太热了,后面就去室内避暑了。来到了国家博物院,门票 18 新。
![]()
![]()
纪念币 12 新。
![]()
南洋华人也曾被鸦片毒害。
![]()
1942年2月15日,英国宣布在新加坡投降。新加坡进入日本的军事占领时期,并被改名为“昭南岛”(日语意为“南方之光”)。战争在其他地方仍在继续,而新加坡人民则在食物和燃料短缺、疾病肆虐以及日本人的暴力与骚扰下艰难生存。
直至1945年,日本无条件投降,新加坡才重新迎来解放——这座“东方的直布罗陀”,在战火与苦难中,重新看见了曙光。
坡的近代历史:
🇬🇧 1945:结束日本占领,但仍是英国殖民地
1945 年 9 月,日本正式向盟军投降。盟军(主要由英国军队领导)重新接管新加坡,成立了 英国军政署(British Military Administration) 来恢复秩序和重建。
📍这一时期(1945–1946)新加坡实际上仍然由英国直接管理,属于“军事管制”状态。
🇬🇧 1946:成为英国“直辖殖民地”
1946 年 4 月 1 日,军政结束。英国正式宣布新加坡成为 “英属直辖殖民地”(Crown Colony of Singapore)。 这一举措也意味着新加坡从马来亚分离出来,拥有独立的殖民地行政系统,但仍受英国统治。
🏛️ 1959:获得自治权
经过多年政治改革与选举,1959 年,新加坡终于获得 内部自治(self-government),李光耀(Lee Kuan Yew)成为首任民选总理。 不过,当时新加坡的外交与国防仍由英国掌控。
🇲🇾 1963–1965:短暂并入马来西亚
1963 年,新加坡与马来亚、沙巴和砂拉越共同组成 马来西亚联邦。 但由于政治与种族冲突不断,1965 年 8 月 9 日,新加坡被迫退出联邦,才正式成为独立的共和国(Republic of Singapore)。
|
年份 事件 状态 1942–1945 日本占领(昭南岛时期) 日军统治 1945–1946 英国军事管制 盟军管理 1946–1959 英国直辖殖民地 英国统治 1959–1963 内部自治 李光耀政府成立 1963–1965 并入马来西亚 马来西亚联邦一员 1965 | 正式独立 | 新加坡共和国成立 |
![]()
从 1942 年的“昭南岛”到 2012 年的“世界之城”,新加坡仅用了 70 年。 它从一座战争创伤的殖民港口,成长为现代化、绿色、智慧的城市国家——这段历程,是关于重建、团结与远见的奇迹。
出了博物馆往上走就是福康宁公园。网红树洞在这里,即便是工作日的周一和错峰出行,这里仍有很多人在排队拍照。
![]()
晚上在 Funan 二刷鬼灭之刃,首刷是看的枪版,二刷必须支持一下。善逸帅的不行。
![]()
然后出门走了一段距离就是克拉玛头。
![]()
玩了一下弹弓,非常的刺激。
![]()
今天的行程从滨海湾花园开始。天气非常的热,购票进入云雾林。室内还是比较凉快。
:::gallery
:::
OCBC Skyway
:::gallery
:::
侏罗纪主题的食阁
![]()
晚上,聚餐。
![]()
最后一天的行程非常的紧凑了,4 点必须到达樟宜机场。所以这天找找的就起床了,办完退房,行李寄存,直奔圣淘沙环球影城了。这天是周三,环球影城依然有很多人,有两个项目排了挺久但是最后因为天气原因、设备故障浪费了许多等待时间。
游玩的路线是 Sesame Street Spaghetti Space Chase -> TRANSFORMERS The Ride: The Ultimate 3D Battle -> Accelerator -> Revenge of the Mummy -> Battlestar Galactica: Human vs. Cylon -> Shrek 4‑D Adventure
| 顺序 | 项目名称 | 所属园区 | 类型 | 刺激度 |
|---|---|---|---|---|
| ① | Sesame Street Spaghetti Space Chase | 🏙️ New York | 亲子暗轨/轻松启程 | 🌱 低 |
| ② | TRANSFORMERS The Ride: The Ultimate 3D Battle | 🚀 Sci-Fi City | 3D 模拟战斗体验 | ⚡ 中高 |
| ③ | Accelerator | 🚀 Sci-Fi City | 旋转类轻度项目 | 🌿 低 |
| ④ | Revenge of the Mummy | 🏺 Ancient Egypt | 室内黑暗过山车 | 🔥 高 |
| ⑤ | Battlestar Galactica: Human vs. Cylon | 🚀 Sci-Fi City(回头) | 双轨对冲过山车 | 🚀 极高 |
| ⑥ | Shrek 4-D Adventure | 🏰 Far Far Away | 4D 动画剧院 | 🍃 低 |
其他的项目时间关系来不及了,只能遗憾离开。
总结本次旅行还是比较充实的,也没有特种兵。每天的行程也不是很多,挺适合我这种老年人的。本次旅行人均花费 5000CNY 上下。
感谢导游:Whitewater, Song, DIYGod
下次还去!