TinyPilot:第 42 个月
原文由 Michael Lynch 于 发布,订阅该博客
一句话总结
如何才能更多地放权?
亮点
- 思考如何更好地把产品决策和文档工作委托出去。
- 对比学习 Nix 和学习 Zig 的体验。
目标完成情况
每月初,我都会定下当月想完成的目标。以下是本月目标的完成情况:
完成 TinyPilot 许可证校验的设计工作
- 结果:设计文档已完成并通过评审。
- 评分:A
我们现在已经有了一套方案,用于在用户更新到最新版本前校验其 TinyPilot 许可证是否仍然有效。接下来还需要选定第三方许可证管理方案(目前倾向于 Keygen)后补充一些细节,但主要环节已经确定。
建立新设备每批次生产的抽检流程
- 结果:没做。
- 评分:F
部分原因是时间不够。本月不得不临时处理供应商的几个问题,占去了不少时间。
另一个原因是这项任务本身让人不太想做,所以我一直在拖延。这件事很重要,因为我们希望尽早发现生产环节的差错,但它需要向我们的第三方物流(3PL)提出特别请求,而对方以往配合度并不高。
处理 TinyPilot 年终税务工作
- 结果:已向所有供应商收齐了 W-9 表格。
- 评分:A-
这项工作现已完成,我也更清楚哪些供应商需要向我们提供 W-9 表格。以后可以避免拖到最后一刻才去做。
TinyPilot 数据一览
| 指标 | 2023年11月 | 2023年12月 | 变化 |
|---|---|---|---|
| 独立访客 | 6,400 | 6,700 | +300 (+5%) |
| 销售收入 | $84,055.05 | $75,198.00 | -$8,857.05 (-11%) |
| 企业订阅 | $290.70 | $290.70 | 0 |
| 版税 | $2,824.46 | $1,792.51 | -$1,031.95 (-37%) |
| 总收入 | $87,170.21 | $77,281.21 | -$9,889.00 (-11%) |
| 利润 | -$5,407.96 | -$59,117.41 | -$53,709.45 (-inf%) |
收入较 11 月略有下滑,但这是每年都会出现的季节性波动。我们的月收入正常区间大约在 7.5 万至 9 万美元之间,本月处于区间下沿,但还不值得担忧。
利润看起来很吓人,是因为我仍在按收付实现制记账,而由于转向第三方代工厂,我们前期在生产制造上的投入大幅增加。第四季度,TinyPilot 在物料和生产上花费了 15 万美元,创下单季度最高纪录。按销售成本(COGS)口径计算,TinyPilot 12 月的利润实际上是 9000 美元(是的,正的 9000 美元)。
不过,最近我把精力都放在管理向外部生产和履约供应商的转型上,营销方面有所疏忽。好在过去几个月即便没有怎么投入营销,TinyPilot 依然实现了增长,但不能一直指望这样,所以我 1 月的目标之一就是探索一些新的营销渠道。
我能把艰难的产品决策交出去吗?
回顾最近时间的去向,我发现很大一部分都花在了我所说的“艰难的产品决策”上。也就是思考 TinyPilot 需要哪些功能、该投入多少资源,以及遇到意外时如何重新分配优先级。
我尝试过把这些艰难的产品决策交给团队,但进展不大。
要是能画一张图,横轴是功能成本、纵轴是用户满意度,然后告诉团队只要保持在那条线之上就行,那就太好了。

我多希望只需定义一条用户满意度与开发成本的关系曲线,然后告诉团队保持在曲线之上就行。
但决定对新功能投入多少,需要考虑的因素远不止这些,包括:
- 这个功能会不会让不需要它的用户感到困惑或觉得界面臃肿?
- 长期维护这个功能的负担会有多大?
- 这个功能会对客服团队带来什么影响?
即便我能做出这样一张多维度图表,对各个变量做出有意义的估算也很难。一个人可能认为 5% 的用户会从某个功能中受益,另一个同样合理的同事可能估计是 15%。仅这一个变量,功能的价值估算就会相差 3 倍。把所有变量综合起来,两个人得出的投资回报率估算甚至可能相差 100 倍。
这么说可能有点自命不凡,但最终做决定的人必须具备“产品远见”。他需要同时与客户、开发团队和客服团队保持紧密联系。而在 TinyPilot,唯一处于这个位置的人就是我。
一个可能的方案是聘请一位产品经理,由他来把高层战略转化为具体计划,并与团队一起执行。但这不太现实,因为这意味着要多管理一个人,还要让他融入团队的沟通协作中。我目前管理着六个人,这已经接近我能有效管理的上限。
另一种可能是让现有团队成员兼任产品经理的职责,但这同样不太现实。这可不是像早上顺手收个邮件那样顺带能做的杂事——他需要参与几乎所有的客户和团队互动,每周要额外投入 10 到 20 小时。即便这么做了,我也不确定能否把人培养到能够做出可靠产品决策的程度。
我目前的计划是继续向开发团队提供高层战略方向,并为修 bug 和做新功能给出大致的工时预算。这一做法目前行之有效,但我仍在寻找能让他们更自主地做决定的方法。
我能更好地把文档工作交出去吗?
我对文档要求很挑剔。如果发现有可以改进的地方,我就不想在改到最好之前发布。
TinyPilot 所有的博客文章、FAQ 和教程仍由我来审核,而我经常成为发布的瓶颈。我感觉创始人时间里有很大一块都花在了文档审校上。
倒不是说我在文档上花了多少纯粹的时间,而是审校文档占用了我大量的“深度思考”额度。我每天大概只能进行一小时的写作。而审阅别人的文字比自己写更耗神。因为我不仅要思考如何表达一个想法,还要思考为什么要这样表达。
我以前在代码评审中也曾纠结于完美主义,后来学会了放过一些小问题。代码是否写得极致优美并不影响用户体验。但文档是人人都能看到的,A 级的文字和 B 级的文字之间有着实实在在的差距。
那么,如何在保持高写作标准的同时,又不让自己成为流程中的依赖瓶颈呢?
我考虑过请一位自由职业的技术写手,但这会让我们的写作流程变得更复杂。我也担心专门的写手会削弱大家提升写作能力的动力。他们可能会想:“我随便写写就行,反正有技术写手来改。”
我在审校文稿时遇到的一个难题是,我脑海中有一个典型 TinyPilot 用户的画像,却不知道如何准确地把它传达给其他人。即便别人理解了这个画像,也很难写出符合 TinyPilot 用户模型的文字。

摘自 TinyPilot 内部风格指南中关于技术术语使用尺度的说明
改进这个问题的一个办法或许是回顾过去的审校记录,寻找其中的规律。如果能发现一些模式,就可以告诉大家:“在提交审校前,先检查一下是否有需要配截图的地方,检查是否在使用新术语前先做了解释,等等。”
我们团队订阅了 Grammarly,但它不太契合我们的工作流程。大家可能在写初稿时会用一下,但没人愿意每次修改后都把整篇文章复制粘贴到 Grammarly 里再检查一遍。我研究过 Vale,它更面向开发者,但相比 Grammarly 显得比较简陋。也许可以给 Vale 配置一些低噪音的检查规则,所以我打算试试看。
学习 Nix 与学习 Zig 的对比
将 TinyPilot 的生产制造和履约外包给第三方供应商带来的一个结果是,我有了更多时间和精力去学习新技术。过去两年我一直关注的 Nix 和 Zig,终于在 2023 年底有机会上手尝试了。
在两门技术都学到入门水平后,对比学习 Nix 和学习 Zig 的体验很有意思。
学 Zig 靠推理,学 Nix 靠复制粘贴
关于 Zig 的一个抱怨是文档质量差。我觉得它的文档确实比较简略,而且更多是从编译器设计者的视角而非开发者视角来写的,但我仍然可以通过查阅讨论和动手实验,逐步建立起对 Zig 准确的心智模型。
使用 Nix 六个月后,我对 Nix 的心智模型依然很糟糕。我看过多份解释,但概念始终没有真正清晰起来。写 Nix 文件时,我只能靠复制现有示例再改成自己想要的样子。文件里大部分都是样板代码,而我并不明白它们为什么要那样写。
在 Zig 中遇到报错时,我通常能顺着逻辑推导出编译器到底在说什么。而在 Nix 中遇到报错时,我则完全束手无策。
我想一个主要原因是,我在类 C 语言方面有丰富的开发经验,而在纯函数式语言方面则毫无经验。Zig 面向 C 和 C++ 开发者,所以作为一个有十年相关语言经验的人,我觉得它的概念很好理解。
Nix 则深受 Haskell 等函数式语言的影响,而我从未学过这些语言。对 Haskell 开发者来说,Nix 可能更直观,而他们可能会对 Zig 中对指针和内存分配器的强调感到困惑,因为这些在函数式语言中并不那么突出。
Zig 的开发者体验窄而深,Nix 则广而浅
Zig 还没有包管理和代码覆盖率方面的工具。让我有些失望的是,Zig 对微控制器的支持似乎大多还处于缺失状态。

除了树莓派 Pico 之外,Zig 对所有主流微控制器的支持都不成熟或根本不存在。
但 Zig 声称能做到的事,它都做得很好。我曾怀疑它所说的可以无缝替代 gcc 是夸大其词,但每次我把 gcc 换成 zig,都能一切正常。Zig 说你可以直接在 Zig 文件中导入 .c 文件,也确实可以。
而我对 Nix 的体验是,Nix 试图做的事情要广泛得多,从构建 Node.js 项目这类简单任务,到构建和管理整个操作系统这类宏大的事情。
当我的项目与 Nix 工具链的预期完全一致时,一切都很顺利。但当我的配置与预期稍有不同时,我就会撞上堵墙。例如,我至今还没搞明白如何在 Nix 下运行任意的 Python 项目。
Nix 中最令人惊讶的缺口之一是,竟然没有官方方法来指定你想安装的软件包版本。这个问题已经讨论了八年,却似乎既没有解决方案,也没有官方表态说明到底会不会修复。
Nix 的领导权分散,Zig 则有 BDFL
Andrew Kelly 是 Zig 的最初创建者。后来有几位成员加入了项目,但 Andrew 实际上仍是终身仁慈独裁者(BDFL)。当我搜索 Zig 的文档或求助信息时,经常会看到 Andrew 或项目官方人员在 GitHub issue 或论坛讨论中亲自答疑。
当我第一次听说 Nix 时,我以为 Eelco Dolstra 会是 Nix 的 BDFL。至少从公开层面看,他似乎并不是。
Nix 是 Eelco 的心血结晶,源自他 2006 年的博士论文。Eelco 是 Nix 基金会的主席,但他同时也在 Determinate Systems 工作,这是一家推广 Nix 的第三方咨询公司。而 Determinate Systems 显然是第三方,并非 Nix 核心。他们发布的一些东西有时会与 Nix 内部团队的工作产生争议性冲突甚至引发分歧。
Zig 给人的感觉是中央统筹的,而 Nix 则感觉群龙无首。当我遇到问题搜寻答案时,经常只看到 GitHub 或 Nix Discourse 论坛上漫无边际的讨论。大家的讨论听起来就像是在谈论一项我们偶然发现的外星科技。而我从未见过 Nix 核心团队的人出面表态,甚至不确定是否存在这样一个核心团队。
在 Nix 和 Zig 中,旧的解决方案往往不再适用
Zig 尚未发布稳定的 1.0 版本,因此编译器更新带来破坏性变更是很正常的。在 Zig 0.8.0 中合法的代码,到 Zig 0.11.0 中可能就不再合法了。依我的经验,Zig 的工具链在自动修复代码方面做得还不错,但并非 100% 准确。
在 Nix 中,我也同样遇到过旧示例失效的问题。Nix 正处在一场围绕 flakes 的、有争议的变革之中,flakes 是一个相当新且仍未正式定型的功能。但最近的所有指南都在用 flakes,而所有旧讨论用的都是非 flakes 方案,所以我很难把基于旧 flakes 之前的解决方案应用到现在基于 flakes 的环境中。
Zig 需要团队全员投入,Nix 则便于部分采用
Nix 的一个优点在于它是自包含的。我可以在某个项目中放一个 flake.nix 来自动管理依赖,而无需改变其他任何东西,也无需要求队友做任何事。
即使我是团队中唯一使用 Nix 的人,flake.nix 依然能为我带来很大价值,同时不会给其他人带来任何成本,也不需要他们使用新工具。这就像在项目中添加一个 .vscode 目录:对使用 VS Code 的人有帮助,对其他人则几乎没有打扰。
而 Zig 则不同,它需要投入和团队全员的支持。如果你有一个 C 或 C++ 项目,想切换到 Zig,就不能只是自己享受更好的工具链、等着队友慢慢加入。一旦你在项目中引入 Zig 代码,每个人都必须改用 Zig 编译器而非 C/C++ 编译器来构建。
这不是 Zig 的错,但这意味着我只有在造访 Zig 世界——捣鼓代码或查看 Zig 项目时——才会接触到 Zig,而如今无论走到哪里,我都会把 Nix 带在身边。
总结
完成了什么?
- 完成了 TinyPilot 许可证校验的设计工作。
- 发布了三篇新的博客笔记。
- 完成了年终税务工作。
经验教训
- 对文档审校进行定期的元复盘可能会有帮助。
- 我们目前只在单篇文章层面讨论改进,但通过复盘多篇文章中反复出现的问题,或许更能提升团队的写作能力。
- Vale 或许能在文档审校前捕捉一些小问题。
下月目标
- 发布年度回顾。
- 联系五位博主探讨 TinyPilot 合作。
- 整理好 2023 年报税所需资料。
求助
- 如果你曾与服务于小批量订单(每月 100-200 单)的优质第三方物流(3PL)合作过,欢迎告诉我。我正在寻找一家靠谱的 3PL。
随机一篇博客
评论
登录后参与讨论