Brooks 在1975年写了关于第二系统效应的内容,而我加入的每一个团队从那以后都重新发现了它,通常是在他们的重写撞上第六个月却没有任何可用原型的时候。这个陷阱不是想要一个更好的系统——而是相信旧系统是靠运气撑下来的。这篇文章是我现在强制每一个”我们就重写它吧”对话过滤的那份清单。
第二系统效应到底是什么
Brooks 的说法——被所有人包括我解释过——是一个设计者建造的第二个系统是最过度工程化的。第一个系统是在约束下建造的;它教会了设计者什么重要。到了第二个,设计者感到解放,知道”哪里埋着尸体”,终于可以把它做正确了。他们过冲了。他们加入了之前拒绝过的每个功能。结果是一个更难交付、更难维护、更难替换的臃肿系统——而且交付时间是第一个的三倍。
Brooks 没有强调,但50年的证据已经清楚表明的:第二系统效应几乎总是一次重写,不是一次全新建设。而重写失败几乎总是同样的六个原因。
六个预警信号
当团队里有人说”我们就重写它吧”时,我现在按顺序问这六个问题。如果答案错了,重写会死。不是可能。会。
1. 你能指出确切的生产痛点吗?
不是”代码很难处理”。不是”测试很慢”。不是”框架老了”。我想要一个具体的生产可见行为:一个 latency 尖峰、一个不断重现的 bug 类别、一个因为当前架构使其昂贵而被推迟了三次的功能。
如果答案是开发者体验痛点而不是生产痛点,重写会失败。因为第二系统的开发者不可避免地会有自己的、还没被枚举出来的开发者体验痛点。你在用已知形状的痛换未知形状的痛。
2. 你和最初构建它的人谈过了吗?
原始设计者知道那个看起来奇怪的东西为什么在那里。70%的情况下,答案是一个四年前不在 commit 历史里的生产事故。如果你不问,你会重新实现他们修复过的 bug。我亲眼看着这发生在我自己身上,两次。
如果原始设计者已经离职:找事故事后复盘。 如果那些也不存在:把你的置信度减半。 你即将重写的代码,以你看不见的方式承重。
3. 计划里有没有”walking skeleton”?
一个在头两周内不交付任何端到端可用东西的重写,永远不会交付任何东西。计划应该有一个第14天的里程碑,看起来像”一个真实请求在生产中流经新系统,影子运行旧系统,流量0%“。如果计划以”首先我们建新数据模型,然后新 API 层,然后新 UI 层”开头——恭喜,你在2026年写了一个瀑布计划,没有人注意到。
在 Bytro,我们做的事件驱动现代化成功,是因为我们从第二周就跑了一个实时影子。每个请求同时打了新旧系统。我们每晚对比输出。差异就是规格。
4. 你有一个清晰的”完成”定义吗?
“旧系统消失了”不是一个指标。“99%的请求由新系统服务,p99在基准线10%以内,错误率持平或更低”才是指标。如果你不知道什么时候完成,你就永远不会完成,而团队将在两个系统之间永远振荡。
第二系统效应的毁灭不是新系统很差。而是组织现在维护着两个系统,而重写的”完成”永远在下一个季度。我见过公司以那种状态运行了三年。
5. 新系统在建的时候,谁拥有旧系统?
那个不性感的答案:就是那些要建新系统的同一批人。 如果你的重写计划悄悄依赖于冻结旧系统——“我们就停止给它加功能18个月”——你的重写在交付之前就已经死了。
旧系统在新系统建设期间会积累自己的关键 bug 修复。要么你向前携带那些修复(意味着构建两次),要么你交付一个缺少18个月增量修复的新系统(意味着它实际上不是一个即插即用的替换)。
6. 回滚方案是什么?
一旦你以1%的流量开启新系统,p99上升到2秒时会发生什么?谁注意到?他们怎么做?有 dashboard 吗?有告警吗?回滚是一条命令还是重新配置并重新部署?
没有快速回滚的重写是一次赌注。赌注偶尔会成功,通常是当下注的工程师有职业决定性的理由是正确的时候。在其他所有情况下,它们是一个需要向某人解释停机的简历制造事件。
我真正享受的那次重写
我职业生涯里唯一顺利的重写是 Bytro 的现代化。它成功,因为我们在开始之前回答了那六个问题,而且大多数答案是”是”:
- 生产痛点: 实时游戏后端里的事件排序导致了在匹配加入时玩家可见的失同步。量化了,用户报告了,优先级1。
- 原始设计者: 还在团队里,积极参与重写。埋着的尸体是可见的。
- Walking skeleton: 第二周,一个端点流经了新事件总线。第六周,五个端点。第十二周,关键路径。
- 完成的指标: 99%的匹配通过新路径加入,p99在基准线内。大约花了11个月达到——比计划晚了两个月,这已经异乎寻常地接近了。
- 过渡期间的所有权: 同一个小队拥有两个系统,我们冻结了旧系统的非关键变更。产品同意了,因为我们每周展示新路径的进展。
- 回滚: 一次功能开关拨动。那个开关每周被测试——不只是定义好,是测试了。在一次真实的 on-call 演练里。这在第八个月一个边角案例出现时救了我们。
每一次我见过死掉的重写,都错过了那六个里的3个以上。我不知道一个反例。
2026年的版本
2026年的重写有一个新的诱惑:“AI 会直接重写它。” 我在过去一年里通过这个网站跑了大约3400次 AI 辅助开发的提交,我要说那个安静的部分:AI 不会保护你免受第二系统效应的侵害。 当第一个草稿感觉是免费的时候,重写的诱惑如果有什么变化的话,是更容易放纵了。
AI 辅助开发让你便宜地做的,是快速试验一条迁移路径——用一个端点在48小时内建一个新系统的版本,看看哪里痛,然后扔掉它。这是一个非常未被充分利用的技术。大多数重写在一张幻灯片的基础上提交;一个 AI 辅助的快速试验以一张幻灯片的成本给你一周真实的证据。
如果你从这篇文章带走一件事:不要让重写从一张幻灯片开始。 快速试验它,扔掉试验,然后决定。
我通常会发现自己反思的事
我写了这整篇文章来论证反对重写。同时,我现在在运行 Fulcrum——一个我建了因为没有现有运行时适合我工作方式的 agent 控制面——从迂腐的角度说,这是我本可以建在现有工具之上的某件事的重写。
我用我自己的清单检验了它。生产痛点是真实的(没有现有工具以我想要的方式协调多 agent 运行)。我和设计者谈过(是我;我也写下了历史)。Walking skeleton 在第一周交付。我有一个清晰的完成定义。我同时拥有旧的基于脚本的工作流和新东西。回滚是”关闭 fulcrum CLI,回到 shell 别名”。
六中六。所以我允许了自己这次重写。如果我只达到六中三,我会把它搁置。这就是那个标准。用它,你的重写会交付。忽略它,你会花18个月解释为什么新系统”快好了”。