Sanvi

8 分钟

独立开发周记29:产品开始反过来管理我

今天本来只是想补一篇周记。

结果一翻项目记录,发现这已经不是周记了,更像事故复盘合集。

上一篇还是三月底,现在已经五月中。中间这一个多月,我每天都觉得自己在处理“最后一个问题”,然后第二天醒来发现,昨天那个只是开胃菜。

这就是做产品最烦人的地方。

代码写完以后,产品不会结束。

它会开始找你要债。

以前我总觉得独立开发最难的是一个人写很多代码。现在看,好像不是。

最难的是,你写出来的东西真的有人用了。

一旦有人用,问题就从“我能不能做出来”变成“我能不能负责到底”。

这个差别还挺大的。

毕竟前者像打游戏通关,后者像你突然发现游戏里的 NPC 都开始给你发工单。

StudyThai 终于不像玩具了

这段时间 StudyThai 的变化很明显。

不是功能数量变多,而是问题类型变了。

以前的问题大多是:“这个功能要不要做?”“这个页面怎么设计?”“这个 API 怎么写?”

现在的问题是:“用户为什么没回来?”“为什么付款状态不同步?”“为什么 Android 这个权限被 Google 卡?”“为什么用户说音频慢?”“为什么反馈里同一个问题看起来像十个问题?”

说白了,产品开始进入真实世界。

真实世界不关心你代码写得多辛苦。

它只关心:我点了,为什么不行?

Cap Snap:一个按钮后面全是坑

最近 StudyThai 里最像“新功能”的东西,是 Cap Snap。

也就是拍物识词。

用户看到一个东西,不知道泰语怎么说,拍一下,系统识别出泰语词、IPA、例句,然后可以收藏到生词本。

这个想法本身很直观。

你在泰国生活,看到某个水果、某个电器、某个路边摊的东西,你不一定知道中文叫什么,更别说泰语了。传统词典是你先知道词,再查解释。Cap Snap 反过来,是先看到东西,再生成词。

想法很顺。

实现不顺。

一开始我还幻想能本地处理多一点。手机本地识别,后端少花钱,隐私也好听。

结果真机跑下来,现实很冷静。

水果还行,一到锅、碗、剃须刀、反光物体,识别就开始发癫。手机端给后端几个标签,后端再靠标签猜具体物体,信息已经被压扁了。

就像你让一个人隔着门听声音猜菜名。

能猜对才奇怪。

最后方案还是变成:手机端做裁剪、方向校正、去背景,真正的识别交给视觉模型。

这件事给我的教训是,技术方案不要为了“看起来高级”服务。

本地化当然好,但本地化以后准确率烂,那就是把成本从服务器转嫁给用户。

用户不是来给你测技术路线的。

当然我自己一开始就是这么想的,所以这段属于自我批斗。

付费墙不是一张页面

StudyThai 另一条主线是付费。

我之前对 paywall 的理解太幼稚了。

以前觉得就是一个弹窗,告诉用户升级 Pro。

做移动端之后才发现,paywall 不是页面,是一条支付链路。

你要管 Stripe,也要管 App Store 和 Google Play。

你要管 RevenueCat,也要管自己数据库里的订阅状态。

你要管促销文案,也要管不同地区的价格显示。

你要管用户点购买,也要管用户点恢复购买。

你要管付款成功,也要管付款成功但后端还没同步。

这几个字看起来都很普通。

真处理起来,一个比一个恶心。

比如恢复购买,如果没有任何提示,用户会觉得按钮坏了。

比如 paywall 如果从另一个全屏 modal 里弹,iOS 可能直接给你脸色看。

比如 Google Play 账号迁移后,RevenueCat 的 Service Account 凭证会失效。

比如促销活动如果写死在代码里,改一次活动就像拆炸弹。

这些事情没有一个听起来像“核心功能”。

但它们坏了,用户不会说“你的非核心功能坏了”。

用户只会说:我付不了钱。

这个时候你就会发现,收钱这件事本身就是产品体验的一部分。

甚至可能是最贵的一部分。

因为这里出问题,损失不是“用户觉得体验不好”,而是“用户想给你钱,你没接住”。

这就很傻逼了。

AI 老师有记忆,不等于它会想起来

这段时间还做了 StudyThai Memory。

简单说,就是让 AI 老师可以读取用户的学习档案,比如学过哪些词、哪些词快忘了、哪些词掌握度低。

这样它回答时就不是一个泛泛的 AI 老师,而是能针对你的学习状态来讲。

这个方向我挺看好的。

但做完第一版之后,很快被现实教育。

你把工具给模型,不代表模型会用。

这跟现实公司差不多。

你给同事开了 Notion、Jira、Google Drive、Slack,然后他还是问你文件在哪。

工具存在和流程成立,中间差了十万八千里。

所以后面又补了一堆看起来没那么性感的东西:什么时候该查学习档案,什么时候不能查;Pro 用户才能用,免费用户不能绕;Redis 缓存不要拖慢回复;工具有没有真的调用,要有日志和埋点;出了问题要能降级,而不是直接把聊天炸掉。

说人话就是,agentic 产品不是把 tools 塞进去就完事。

你还得教它什么时候该用,怎么用,用坏了怎么办,以及怎么知道它到底有没有用。

这个功能现在我也不想说得太满。

它还是实验性的。

有时候像一个认真备课的老师,有时候像一个拿错教案的助教。

不过至少方向对了。

以前 AI 老师最大的问题是,它不知道你是谁。

现在它终于开始有机会知道一点点。

用户反馈比我想象中复杂

5 月初我把 GitHub 上 80 个 open issue 全部过了一遍。

这件事干完以后,我最大的感觉是:用户反馈不是 bug 列表。

它更像一堆混在一起的线团。

有的是数据错。

有的是题目设计不清楚。

有的是用户自己理解错。

有的是某个超级用户的高标准偏好。

有的是反馈系统自己记录错对象。

还有一些是功能建议,不是问题。

以前我看到 issue,很容易下意识紧张。

“完了,又出问题了。”

现在会稍微冷静一点。

问题当然要重视,但不能每条反馈都当成全体用户投票。

其中有个用户一个人提了 18 条,占了全部 open issue 的 22.5%。

这不是坏事。

愿意给你写反馈的人,比大多数沉默离开的用户有价值得多。

但你也不能把一个高敏感用户的痛点,直接当成所有人的痛点。

不然产品会被少数最响亮的声音牵着走。

说白了,反馈不是答案。

反馈只是线索。

你还要回到数据、路径和真实场景里判断。

这也是我最近觉得 StudyThai 开始“像产品”的原因。

不是因为功能更复杂了,而是因为我要开始做治理了。

数据治理、反馈治理、内容质量、转写准确率、支付路径、留存路径。

听起来都不像独立开发。

听起来像上班。

更惨的是,这班还是给自己打的。

留存问题把我打醒了

这段时间还做了一次付费转化审计。

一开始我的怀疑方向是,用户是不是喜欢开试用然后取消,或者免费权益是不是给太多了。

这个怀疑很正常。

毕竟当收入没有达到预期时,人会本能地怀疑是不是自己太善良了。

结果数据一看,方向基本错了。

真正的问题不是用户薅试用。

很多用户还没走到真正需要付费的地方,就已经离开了。

这就尴尬了。

你在后面精心设计了 paywall、试用、促销、价格锚点,结果用户前几步就掉头走了。

有点像你在终点线旁边准备了香槟,结果选手在起跑线旁边买了杯奶茶就回家了。

课程单节完成率其实还不错,说明单个学习体验不是完全不行。

问题更像是缺少把人拉回来的东西。

streak、push、每日目标、召回提醒,这些听起来很 Duolingo,也很烦,但它们确实是学习产品的一部分。

我以前对这些东西有点抵触。

总觉得做好内容就行。

现在发现,内容好只是基础。

学习这件事本来就反人性。

你不能指望用户每天靠热爱打开 App。

我自己都做不到,凭什么要求用户做到。

OpenOwl:终端应用会惩罚每一个乐观的人

OpenOwl 这边也继续往前推。

最近几个版本其实没有什么“听起来很酷”的 AI 功能。

主要是在修很基础的东西。

多文件拖拽。

滚动条交互。

大量终端输出时 UI 卡顿。

切换面板以后文件编辑器状态丢失。

Git 面板在隐藏状态下还偷偷工作。

退出 App 时没有确认。

打包、公证、DMG、GitHub release。

这些事情写出来很碎。

但终端应用就是这样。

你以为你在做一个开发者工具,实际上每天都在处理“为什么这么基础的东西会坏”。

复制粘贴会坏。

拖拽会坏。

焦点会坏。

滚动条会坏。

隐藏的视图还会继续收键盘输入。

一个 SwiftUI 页面里嵌 AppKit,再嵌 terminal surface,再接 libghostty,任何一层脾气不好,最后用户看到的都是你的 App 有问题。

我以前看到一些终端应用的小毛病,会觉得怎么这么基础都没做好。

现在我理解了。

不是他们不想做好。

是这个领域的“基础”本身就不基础。

OpenOwl 最近做了一次比较大的布局调整。

中心区域以后固定给终端,不再被 Files、Git、Deploy 这些面板替换。

右侧改成一个很窄的垂直 rail,需要的时候展开。

sidebar 里加了独立终端区,可以开一些不绑定项目的自由 shell。

这个改动的核心不是 UI 好看。

而是我终于承认,OpenOwl 的中心必须是 terminal。

文件、Git、部署都应该围绕终端,而不是跟终端抢位置。

这也是这一个月做下来最大的产品判断。

OpenOwl 不应该变成一个塞满 AI 功能的 IDE。

它应该先成为一个稳定、轻量、顺手的工作台。

AI CLI 你爱用什么就用什么。

我没必要再造一个“更懂你”的 AI 入口。

说真的,很多工具现在最大的问题不是 AI 不够多。

是地板还没铺平,就开始往墙上挂宇宙飞船。

我还砍掉了一个自己吹过的功能

这段时间 OpenOwl 还有一个变化,挺打脸。

之前我做过一个 local deployment 功能。

想法是,在 OpenOwl 里直接管理本地服务,比如某个项目的 dev server,点一下启动,点一下停止。

听起来很合理。

结果用了一段时间发现,不合理。

因为 OpenOwl 是 terminal-first。

既然终端就在中间,我为什么还要在 App 里造一套本地服务管理?

你都能写代码了,大概率也知道 pnpm dev 怎么跑。

这个功能不仅自己没那么必要,还给周围系统制造了很多复杂度。

比如退出 App 时,要不要提醒用户还有本地服务在跑?

比如服务状态跟终端状态怎么对齐?

比如部署面板到底是本地部署还是远程部署?

一个功能如果方向错了,它不会只是浪费自己的开发时间。

它还会持续给旁边的功能添堵。

最后我把它删了。

删完以后,项目反而清爽很多。

这件事也提醒我,独立开发最容易犯的错不是少做功能,而是多做了一个自己都不用的功能。

毕竟你一个人,没有产品经理拦着你。

这时候你自己就是那个最危险的产品经理。

内容生产也得产品化

还有一个这段时间一直在折腾的东西,是 content-engine。

这个东西的起点很简单。

我发现自己写周报越来越困难。

不是因为没做事,而是因为做太多,过几天就忘了。

等到要写文章的时候,只剩一个模糊印象:最近很忙。

这句话没有任何信息量。

所以我开始把内容生产也当成产品来做。

RSS 收集资讯,AI 做选题,researcher 查资料,writer 写稿,再派生 X 推文、小红书笔记,最后推到微信草稿。

里面还分 Sanvi 和 Rin 两种模式。

Rin 可以写更偏资讯评论的内容。

Sanvi 模式则必须参考我的 writing_style_guide.md。

但是这里我也踩了一个很典型的问题。

风格指南不是复读机。

如果 AI 只是学会了我的口头禅,比如“其实”“那么”“说白了”,然后把参考文章的结构换个皮,那不叫模仿风格。

那叫低配洗稿。

真正要学的是节奏、视角、判断方式和素材使用方式。

比如从一个具体小事切入。

比如承认自己也不知道。

比如技术概念要翻译成人话。

比如不要把失败包装成成长。

这些才是风格。

不是把我以前说过的话重新排列组合。

这也是为什么我现在越来越觉得,AI 写作最难的不是“写得像人”。

而是不要把人活过的东西变成模板。

模板很容易。

真实很难。

一人公司开始变成真的了

这一轮复盘下来,我发现“一人公司”这个词变得越来越具体。

以前它像一个愿景。

一个人,用 AI,做很多项目,效率很高,听起来有点爽。

现在它更像一个待办列表。

产品规划。

用户反馈。

移动端发版。

支付系统。

订阅同步。

数据分析。

服务监控。

内容生产。

客服解释。

还有半夜突然发现某个配置不对。

AI 确实让我能做更多事。

但它没有让这些事消失。

它只是把原来需要几个人分摊的事情,压缩到我一个人面前。

有时候我也会想,要不要找人一起做。

但很现实的问题是,很多时候我跟人解释半天,还不如我把上下文喂给 agent,然后让它先跑一版。

这个想法听起来不太政治正确。

但这是我现在很真实的体感。

不是人不重要。

而是协作本身有成本。

当 AI 把执行成本降下来以后,人的沟通成本就被放大了。

这可能也是接下来很多一人公司会遇到的问题。

不是能不能招人。

而是什么时候招人真的比多开几个 agent 更划算。

说真的我也不知道答案。

我现在只是被产品推着往前走。

最后

这篇写到这里,我感觉也不像周记。

更像一个人被自己的产品追着跑了一圈,回来喘口气。

StudyThai 让我意识到,真实用户会把你的所有偷懒都翻出来。

OpenOwl 让我意识到,基础体验比 AI 噱头更难。

content-engine 让我意识到,连“写我自己”这件事都不能偷懒。

AI 没有把我变成轻松的一人公司。

它只是让我真的开始像一家公司一样,被各种事情追着要交付。