Mole 出 Mac 版这三个月,教会我怎么做独立产品

Categories: Share

最近看到不少聊独立开发的内容,想着把 Mole 从开源 CLI 做到 Mac 付费软件这一路的思考、还有哪些事情做下来是真的有效的,给大伙聊一聊,也许能给正在做自己作品的朋友一些输入。

去年国庆我在三亚的泳池边写了几百行代码,做了个 Mac 清理的命令行工具 Mole CLI 开源到 GitHub 上,本来只想给自己和同事用。结果不到一年收了 60K star,陆续发了 50 多个版本,112 位来自全球各地的开发者提交过代码,解决掉 812 个功能建议和 Bug。

其实我一直没太意识到用的人有多少,直到有一次,因为在 README 上挂了两张用 Vercel 加速的图片,流量把账单跑超了,欠了 Vercel 80 刀。那会儿才反应过来,桌面端可以做了。

之前收到最多的一类邮件来自国外用户,大意都差不多:我父母也用 Mac,我妹妹也用,但他们不会开终端,能不能做一个不用敲命令就能用的版本。这件事拖了挺久,主要是觉得 CLI 本身还没到成熟的地步,后来用两个周末把 Mac 桌面版做了出来。当天晚上十点发布,那一夜手机几乎每 10 秒响一次购买通知,iPhone 直接发烫掉电,法国、德国各种币种都有,最后为了睡觉不得已把邮箱通知关了。现在回头看,那个首发版本其实挺单薄的,两个周末能做出来的东西能有多完整,很多功能是后面几个月才一点点补上的,等于是一批用户先掏了钱,再陪着我把它做完。有件事先说清楚,开源的一直是 CLI,它免费,以后也会一直更新,Mac 桌面版是另做的,付费。

三类以前没有的垃圾

后面聊的大半是技术判断,不过它们其实都指向同一件事。我做产品一直信不做什么远比做什么重要,放到一个会删你文件的工具上,这句话就变成了不删什么。

我几乎全天开着 Claude Code 和 Codex 写东西,过了一段时间才意识到,AI 工具产生垃圾的方式和以前的软件很不一样,大致分三类。

第一类是编译产物,这个不新鲜,但 AI 把量级放大了。以前一天手写几百行代码编译三五次,现在一个下午让 agent 跑十几轮,每轮都要编译一次。Rust 项目的 target、前端的 .next 和 dist、Xcode 的 DerivedData 增长很快,我自己有一次清出 86G,全是这些东西。第二类是 AI 工具自己的旧版本和容器缓存,Claude Code、Cursor Agent、GitHub Copilot 这几个命令行工具都是自动更新的。更新方式是把新版本整个下载到一个新的版本目录,一个版本约 250MB,旧的不会删,几个月下来这里积着十几个再也用不到的版本。第三类是模型文件,Ollama 和 LM Studio 拉下来的模型、HuggingFace 的缓存,常常几十 G。

前两类 Mole 会清,第三类一个字节都不碰。后来我慢慢把这件事想成三档,扫到的每样东西先归个类,再决定它默认要不要勾上。第一档可再生,HTTP 缓存、GPU 缓存、编译产物和多数日志都算,所有者退出、路径明确就可以清。第二档重建代价高,包管理器的注册缓存、本地模型权重、iOS 的 DeviceSupport 都能重建,但要花网络和时间,得让用户自己过一眼。第三档不可替代,聊天记录、邮件库、照片图库和进行中的项目状态都在里面,我觉得它们根本不该出现在任何一键列表里。

这三档压成同一份「安全可删」的清单当然省事,代价是把本该用户自己拿的主意替他拿了。清理页的十类项目就是按这个顺序排的,可再生的缓存排在最前面,越往下越需要自己看一眼。

target、build、dist、__pycache__、DerivedData 这些删掉以后重新编译一次就回来了,代价是几分钟 CPU。node_modules、Pods、venv、vendor 看着也是依赖目录,但删了必须重新联网下载,在高铁上或者飞机上想跑一下项目就只能干等。不少清理工具把这两类混在一起算作垃圾,Mole CLI 早期也是这样,后来专门把所有下载类的目录从 Mac 版的清理列表里摘了出去。模型是这里面最重的一类,几十 G 重下一遍是灾难。所以 ~/.ollama/models~/.lmstudio/models~/.cache/huggingface 这几个路径在代码里是写死的保护名单,扫描阶段根本不会出现,只在磁盘分析那边显示占用大小。

而且模型这一类,通用清理工具就算想帮你删也删不对。Ollama 把模型存成按 sha256 命名的内容寻址 blob,再用一个很小的 manifest 把模型名和标签关联到它需要的那些 blob,多个模型可以共享同一个 blob,ollama rm 会先移除 manifest,只有确认没有别的引用了才释放 blob。你从文件系统上直接删一个看着很大的 blob,很可能把另一个还在用它的模型弄坏。Hugging Face 那边按修订保存不可变快照并对重复内容去重,也是同一个道理。这种引用关系只有工具自己知道,所以我把模型交回给 Ollama、LM Studio、Hugging Face 各自管,Mole 最多告诉你它有多大。

还有一类东西比模型更不能动,是 AI 的会话记录。~/.codex/sessions~/.claude/projects~/.grok/sessions 里存的是你和 AI 几个月甚至一年的完整对话,里面有当时的思路、被否掉的方案、每一处为什么这么改的原因,删掉就真的没了,某种程度上比代码本身还珍贵。所以这几个路径在 Mole 里是任何年龄都不可清理的,不管多久没被访问过,同样受保护的还有 memories、plans、skills 和生成的图片。

最后说一个踩过的坑,~/Library/Caches/com.apple.e5rt.e5bundlecache 这个路径带着 Caches,位置也在缓存目录下,从任何角度看都像缓存,实际上它是苹果神经引擎编译好的模型存放处。CLI 早期真把它当缓存清了,结果用户反馈所有用到识别类功能的 App 全部报 E5RT Code 13,一直到重启才恢复。现在这个路径在两层保护名单里都写死了,还配了两个测试专门盯着,防止哪天被误改回去。

这件事之后我自己养成一个习惯,看到名字里带 cache 的目录,先在心里过三个问题,谁写的,重启之后谁会去读它,万一删错了怎么找回来。有一个答不上来我就不动它。剪贴板历史可能就住在某个厂商的 Caches 树下,叫 tmp 的目录里放的也可能是聊天检查点或者没保存的草稿。

删之前得先知道哪些不能删

我感觉这类工具差别最大的地方不是能清多少,是删之前让不让你看清楚。

Mole 的清理是先扫描,逐项列出来,每一项显示具体是什么、在哪、占多少,拿不准的默认不勾选,确认完再删,删的时候优先进废纸篓,后悔了还能找回来。扫描和清理全程在本机完成,文件和结果都不会上传。代价是慢,多了一步确认,喜欢一键完成的人多半不会喜欢,但我还是想让它宁可漏删也不误删。

卸载走的是同一套逻辑,选中一个 App,Mole 会把它散在系统各处的东西一起翻出来,逐项标上路径和大小,上面这张图里 Claude 本体只有 781MB,~/Library/Application Support/claude 却有 7.67 GB,真正占空间的从来不是应用包本身。登录项和后台服务也放在同一页,不用再去系统设置里一个个找。

举个例子,macOS 系统更新下载下来的安装包,也就是 /macOS Install Data 那个目录,经常十几个 G,看着是完美的清理目标。上个月有用户报过,装 macOS 27 测试版的时候这个目录被清掉了,重启直接黑屏。现在它在 Mole 里是默认不勾选的审阅项,前面叠了三道门,系统里存在待安装的更新就整行隐藏,安装包最近 14 天内被写过就隐藏,安装相关进程还在运行也隐藏,任何一个信号读不出来都按有风险处理不显示。

真到执行删除那一刻,root 权限的脚本还会把这几项检查重新跑一遍,不通过就非零退出,绝不会出现「报告说清了 12G 其实一个字节没动」这种事。界面上看清楚只是一半,另一半在看不见的地方,发现阶段不能删除,确认阶段只生成范围明确的计划,执行阶段再验一次身份和保护路径。

类似的地方还有不少,Gradle 守护进程在运行就不清它的缓存,Xcode 的测试模拟器克隆只在确认测试工具完全没在运行的时候才出现,探测进程失败或者超时一律按正在使用处理。

我自己判断一款清理工具好不好,有个很土的办法。装同一个厂商的两款产品,只卸掉其中一款,看它会不会把两款共用的 Application Support 父目录或者 group 容器也列进去。列进去了,说明它是按名字匹配的,不是按归属判断。归属都说不清的工具,我不太敢让它批量删东西。

想让它安静,得定一堆很硬的规矩

Mole 从第一版 shell 脚本开始,要求就是安静、可靠、不打扰你,这个词听着很虚。落到界面上,其实是一串很硬的规矩。

一个区域要么完整显示要么隐藏,不允许出现半成品的按钮和空卡片。扫描结束之后界面才进入结果状态,绝不进一个扫到一半的页面。很短的等待不显示任何提示,超过阈值才出现一种工作状态,所以短扫描根本不会闪一下加载动画。完成页也提前预留好空间,结果到达的时候窗口不会突然跳一下。

底下的活儿本来就不好预测,这时候加动画只是让混乱动起来,真正的平静还是来自异步流程本身足够可靠。我不希望一个维护工具需要人一直盯着,发起任务,等它完成,再拿回屏幕就够了,它更该像一件做工好的家电,而不是不断闪烁、要求你查看的应用。

克制也包括无障碍,朗读顺序、键盘操作和稳定的焦点跟视觉上的安静是同一份承诺。系统开启「减少动态效果」之后,行星会停止装饰性旋转,状态变化也减少空间移动,任何操作都不依赖用户看懂动画。如果安静只对一部分人有效,那还不算真的安静。

把工具做到 70 岁的老爷爷也能用

以前我做东西基本只考虑身边这些人用得顺不顺手。这次从 CLI 做到桌面端才发现,要让一个 70 岁的老爷爷也用得上,中间要过的事情多得多,也有意思得多。下面几封信是从这三个月的用户邮件里摘出来的,我最大的收获几乎都在这里。

有位快 70 岁的英国用户,说他犯了一个老年时刻,把 Mole 又买了一遍,「第二笔钱就当做送你,谢谢这个出色的工具,帮我省下了比 CleanMyMac 多得多的英镑」。我建议他退款或者把多出来的授权送人,他去问了一圈,第二天回我「我邻居没人用 Mac,我 Bluesky 上的关注者也没有,这一轮算我请你」。收到这样的信,我会觉得必须把产品做得更好,才对得起这份信任。

一位美国用户纠正了我一个关于地区习惯的错误想法。我一直以为美国人看温度就得用华氏,所以美区默认给了华氏,他说:「美国人在所有技术相关的场景都用摄氏度,只有天气和体温例外。我装上 Mole 看到 110,吓了一跳。Apple 给美国人看的规格也是摄氏度,fastfetch、neofetch 在美式系统上默认也是摄氏度。建议保留华氏切换,但所有地区默认摄氏度。」后来就改成了默认摄氏可切华氏。他还追了一封聊定价,说我给的那个数字读起来不像刻意定的价,像是从别的货币换算过来的,又补了一句「我说外来不是指反华,而是人们希望感觉到作者理解他们」。说实话那个价格就是我拍脑袋定的,做产品之前从没认真想过定价这件事,被一个素不相识的用户当面点出来,挺不好意思的。这封信也让我第一次意识到,一个价格数字本身也在传递信息。

一位视力轻度障碍的用户说:「看起来是个很不错的 App,可惜我用不了,它似乎把深色模式写死了。我系统设成浅色,也只用浅色模式的 App。」Mole 只做深色其实是个刻意的决定,菜单栏面板像 HUD 一样浮在壁纸上,深色玻璃眩光更少,也不用多一个主题开关。但这个理由对他不成立,我一直觉得自己把无障碍当成了完整的承诺,却完全没想到浅色模式本身也是一种无障碍需求。这封信收到有一阵了,Mole 到现在还是只有深色,浅色一直排在列表上没做完。一个说自己在意无障碍的产品,把一位明确说了用不了的用户晾到现在,这件事我一直有点过意不去。

还有一位德国拜罗伊特大学的讲师来申请教育授权,说这「不仅是对我个人的支持,也是一种有意义的教育层面的支持」。原来还有国外的老师在课堂环境里用我的产品,这是我没预料到的用法。一位匈牙利的医生则给了最真实的差评,「说实话,这个价格对一个免费应用也能做到的事情来说有点高了」。这条我一点都不觉得刺耳,不同国家购买力差别很大,他不是在抱怨,是在帮我定位问题。

Mole 里我自己最喜欢的几个功能,起源其实都不是我想到的。AirPods 快没电时会收到一条提醒,是做电池健康那阵子加的,我一直没遇到这个场景,直到某天下午真的收到了,很贴心又不打扰。屏幕常亮做了三种不同的行为,也是用户提醒之后才补的,周末突然出门,AI Coding 那边可以继续跑,帮我省下不少异步的时间。状态里能看到 iPhone 的电量,这一块之前不太好实现,后来也找到了办法。这些都是用户告诉我要加的,加完之后对我自己帮助最大。

用户的邮件我一直自己回

这些邮件我一直是自己回的,答疑、退款、重置激活码这些事加起来不到用户量的 1%,花半小时写个脚本就能全自动,但我没写。只有自己一封封处理过,才能感觉到用户到底要什么、为什么退款、哪里让他不舒服,而那经常不是他第一句话问的东西。我给自动化定的门槛不是工单数量,是三个条件同时成立,问题反复出现,答案保持稳定,例外已经理解。在那之前,对话本身就是研究。目前这样还有效,我没花钱做营销,增长基本来自口碑,退款率低于 0.8%。

发布之前我也没有搭工单系统、客服平台和知识库。工程师喜欢先把支撑机器建起来,因为那是熟悉的工作,AI 又把它压缩到半天,更容易让人过早动手,可是半天搭建是真的,长期维护一个暂时用不到的系统也是真的。等哪天收件箱开始丢请求、看不清响应时间,或者同一个问题得到了不同回答,那才是真正需要新系统的时候。AI 让这个产品的很多部分成为可能,但它没有取代和使用者交谈,也不该取代。效率越来越容易拿到,开发者和用户之间的信任还是要一场对话一场对话地建立。代码可以生成,关系不能。

做产品这段时间,我自己感觉有用的几件事

做产品这件事,我感觉代码能力大概只占三成。更花心思的是怎么把自己的痛点和大部分用户的痛点接上,产出一个方便易用的解决方案,还有怎么把它更好地推荐出去,让人觉得多亏有这个东西解决了一个大问题。这几件事加起来约等于用研、产品、工程师、运营、数据和商业混在一个人身上。

不做什么远比做什么重要。大一刚入门的时候很幸运看了不少讲工程师修炼的书,如无必要勿增实体、至繁归于至简这两句慢慢渗进了我的生活、工作和代码里,做产品之后感受更深。好产品和一般产品的区别,很大程度上在于它更会决策哪些东西不做,哪些功能即使很好但不属于这条主线所以不放进来,否则很容易变成功能堆砌,也不好维护。

另一个感受是脑袋里得有半年的脉络,清楚知道每一个版本该加什么、哪些是伪需求、哪个功能该放在用户顺手的地方。对普通用户来说,不用看说明书就能上手的那个才算好。Mole 的定位是 Mac 系统维护的安静守护者,有不少朋友建议过挺好的功能,我都婉拒了。我的目标也很简单,每一百位 Mac 用户里有一位愿意留下 Mole,它就已经足够有用。

现在一个功能进路线图之前要过三道门,用户没进入这个功能的时候不增加常驻的定时器、监听器和采样开销,不为一点小便利去扩大特权助手,也不新增系统权限,有合理默认值的时候不增加设置项。这不是所有软件的通用原则,是 Mole 自己的预算。常驻工作、特权和配置都是用户需要长期信任的表面积。

我基本没攒过大招,尽量做到每周都发一版。及时解决用户的问题,和用户形成人与人之间真实的互动,每一次发布、更新、宣发其实都是一次很好的沟通机会,也让之前没看到消息的人有机会知道你在做什么。

Mole 从第一天就是全球化的,英文内容也发得比中文多。这段时间最大的感受是世界很大,用户很广,而且他们从一开始就愿意信任你,力所能及帮助过的人,很大概率会成为未来的用户,因为有过真实的交情。我也没花钱做过推广,X 上的脉冲很高但时效一般,反而有些东西发到 YouTube 之后衰减非常慢,只要东西够好,有人推荐,能在上面活很久。

AI 时代代码壁垒越来越小,更需要把控的是怎么把 Token 刚好花在解决用户问题上。多花我不太介意,但要花在实处,需求分析的讨论、数据下钻挖问题、内容的友好性和易读性,这些地方值得花。Token 在我看来属于投资,投资也得讲收益。

数据这块我花的时间比想象中多,销量分维度分时间去看,再结合流量数据、用户评论、和用户交流过的所有内容、用户的退款原因,开源产品还有全部的 issue,这些都是很宝贵的资源,能帮我发现特别多自己不知道的问题,也能看清销售的漏斗到底断在哪一环。

最后一条更像是我自己的做法,我把账号当成一个长期的东西在养,但没抱太强的功利心,抱了就会焦虑。思考、想法、产品更新、见解、评论都是在给它积累信任值,在如今这个宣称得很响、点进去又很一般的环境里,信任特别值钱。很多好产品得不到关注不是因为不好,是因为用户的预期已经被拉得太低了。这件事可以做得非常长期,你在互联网上待多久它就活多久,大概是我生命周期最长的产品。

写在最后

Mole 桌面版目前是清理、卸载、优化、磁盘分析、硬件状态五块,界面上每一块对应一颗行星,清理是地球,卸载是火星,优化是水星,分析是木星,状态是太阳。这和我小时候喜欢看各种行星运行有关系,加上十年前学会前端之后第一个特别想学的就是 WebGL,正好凑到了一起。各颗行星的贴图我换了不下 10 次,从 NASA 官网下载挑了很多才定下来,自转的方向、转速、完成后的飞行效果也都参考了真实的天体运行情况。

这部分完全可以不做,做个菜单栏点一下清一下的小工具也能用。但 AI 产生的赛博垃圾已经够多了,与其把 Token 花在再生成一个能跑就行的界面,我还是想做个舒服一点的东西出来,不浪费我的 Token,也不污染你的时间线。

我做事情喜欢水到渠成,不喜欢短时间急切追求结果。前段时间想到一句话,世界上最好的工作,大概是持续学习的人在自由市场里,用自己的判断力、能力和审美持续创造价值,变成他人愿意买单的东西。

CLI 在 GitHub 上开源免费,桌面版可以先试用再决定,官网是 https://mole.fit。这是我的第一款付费产品,里面一些判断可能是错的,你要是在这条路上走得比我久,看见我正在做傻事,很欢迎告诉我。比起买不买,我更想听的是你用下来觉得哪里别扭、哪个功能是真的需要但现在没有。上面这些改动没有一条是我自己想出来的,全部来自某位用户的一封邮件或者一个 issue,这三个月最划算的一件事,可能就是没放弃跟用户聊天。

Read More

你不知道的具身智能:从小机器狗到 Optimus

【2026-06-07】4 月份的时候,我用 STM32、ASRPRO、ESP32-C3、舵机和 3D 打印件手搓了一台能听懂话、能走路、能接云端 AI 的小机器狗。跑通之后再看具身智能,很多判断都落到了很具体的地方:串口、PWM、空间、动作、控制频率、执行器、失败样本和量产约束。