借助AI重写项目:别让技术债变成新坑
每位程序员心中,或许都曾闪现过一个“重写”的念头。
特别是面对一个陈旧项目时,这种冲动尤为强烈:代码风格混乱、文档多年无人问津、接口像打补丁一样堆叠。你若问起某项功能的来由,旁人往往沉默片刻后说:
“当初写这功能的人,早就走了。”
这种时候,重写的诱惑真的很难抵挡。
过去大家通常选择忍耐。不是不想推倒重来,而是因为重写成本太高、周期太长,而且容易出错。
但在如今的 AI 时代,情况似乎不同了。
你可以把老代码贴给 AI,让它分析;把需求讲给它听,让它设计新架构;让它写测试、改框架、迁移语言栈。几小时或几天后,一个“看起来更现代”的项目就可能跑起来了。
但问题也正在这里。
AI 并没有让重写变得无成本,而是让你更晚才看到真正的代价。
所以,那个老问题又浮现出来:既然 AI 编程让重写变得更容易,现在是不是重写的最佳时机?
要回答这个问题,我们得回顾软件工程史上的一个经典案例:Netscape。
1990 年代中期,Netscape Navigator 是早期互联网浏览器市场的重要角色。后来,微软 Internet Explorer 快速崛起,浏览器市场的竞争日益激烈。
1998 年前后,Netscape 启动了开放源码的 Mozilla 项目。之后,旧浏览器代码、Mozilla 项目和 Gecko 排版引擎经历了多次演进。等 Netscape 6 在 2000 年发布时,市场格局已大变。
这段历史后来被 Joel Spolsky 在 2000 年的《Things You Should Never Do, Part I》中作为经典反例来讨论。在他的批评框架中,Netscape 放弃旧代码、转向新一代 Mozilla/Gecko,是软件公司可能犯下的严重战略错误之一。
这句话传播力极强,因此后来常被简化为四个字:不要重写。
但只记住这四个字,反而容易把历史读窄。
Netscape 的衰落不是单一原因。微软 IE 的竞争、Windows 捆绑、免费分发、商业策略、标准演进、组织变化,这些事都在同时发生。重写不是唯一原因。
真正值得记住的是另一件更扎心的事:
当团队把核心精力压到下一代系统上时,现实世界不会按下暂停键。
用户还在用旧版本,bug 还在冒,竞争对手还在迭代,市场窗口还在往前滑。新系统没有成熟之前,旧系统又越来越难继续演进。团队很容易掉进一种“双线消耗”:一边救火,一边盖新楼,两边都缺人,两边都着急。
这才是重写最危险的地方。
它不只是一个技术动作,更像一次机会成本巨大的暂停。
Joel 的批评里,最重要的一点是:旧代码看起来很丑,但它不是一堆毫无价值的垃圾。
一段老代码里奇怪的 if,可能对应过某次线上事故。
一个不优雅的兼容分支,可能是为了照顾某个大客户的历史数据。
一个谁都不喜欢的接口格式,可能已经被十几个上下游系统默默依赖。
旧代码最烦人的地方在于,它记录历史的方式很不友好。它不会在旁边写一行注释说:“这段是 2017 年那次支付失败事故之后加的,别乱动。”它只会静静躺在那里,看起来像一块碍眼的补丁。
于是新人接手时,很容易产生一种冲动:
这都什么玩意儿,不如重新写一遍。
从零写出来的新代码,表面确实更干净。目录清爽,命名统一,架构图也好看。
但它还没被真实世界打过。
旧代码里有旧 bug,新代码里也会有新 bug。区别只是:旧 bug 你至少认识了一部分,新 bug 还在路上,甚至还没来得及露面。
所以,Netscape 的故事不是在说“旧代码神圣不可动”。它真正提醒我们的是:不要低估旧系统里那些看不见的经验。
当然,今天和 1998 年确实不一样。
AI 编程工具让“重写”的第一步,在很多场景下变得更容易启动。
它可以快速生成样板代码,把一个旧框架迁到新框架,解释陌生模块,补类型定义,写测试草稿,整理接口文档。需求边界清楚、代码规模可控的时候,一个过去要花几周搭起来的原型,现在可能几天就有雏形。
这不是小变化。
很多小工具、内部后台、低风险模块,确实因为 AI 变得更适合重新实现。尤其是那些边界清楚、依赖简单、失败可回滚的项目,AI 往往能明显降低原型和第一版实现的启动成本。
所以,我们也不能拿老经验简单否定新工具。
过去说“不要重写”,一个原因是重新实现成本太高;更关键的是,旧系统里的隐性知识、兼容关系和市场机会成本很难复制。现在,AI 至少把“写出第一版”这件事变便宜了。
但新的错觉也跟着来了:第一版出现得越快,人越容易以为整个系统已经被解决。
可软件项目最贵的部分,往往不是把代码敲出来。
而是弄清楚它为什么必须那样运行。
AI 让重写更容易启动,却没有自动消灭重写的风险。最后,团队至少还要面对这几笔账。
先是需求账。
老系统真正满足的需求,很多不在需求文档里,而是藏在用户习惯、业务流程和历史妥协里。AI 可以读代码,但它未必知道为什么某个按钮不能删,为什么某个报表必须保留一个看似多余的字段。
再是兼容账。
历史接口、老数据格式、第三方插件、边缘设备、异常订单,这些东西常常才是系统最麻烦的部分。AI 可以生成一个更漂亮的新接口,却不一定知道旧接口被多少地方偷偷调用。
还有测试账。
AI 可以帮你生成测试,但测试有没有覆盖真实业务,要由人判断。很多重写项目出问题,不是因为代码完全跑不起来,而是因为它在大量普通场景下都正常,偏偏在少数关键场景里掉链子。
迁移账也躲不过。
新系统不是写完就结束。数据怎么搬?用户怎么切?失败怎么回滚?新旧系统并行多久?日志、权限、报表、通知、缓存怎么处理?这些问题没解决,重写就只是一个漂亮的半成品。
最后,还有组织账。
重写期间,旧系统还修不修 bug?客户的新需求还接不接?团队是全员扑到新系统上,还是分成两拨人?如果延期,谁来承受业务压力?
这些账,AI 都可以帮忙算一部分,但不能替你承担。
说白了,AI 擅长补“看得见的代码”,不擅长自动恢复“看不见的历史”。
说到这里,还得把几个词分清楚。很多争论吵到最后,其实是大家说的根本不是同一件事。
重构,是不改变系统外部行为,改善内部结构。
用户看到的功能还是一样,但开发者把混乱的函数拆开,把重复逻辑合并,把命名改清楚,把测试补上。它像房子里还住着人,但你重新整理线路、加固墙面、修补水管。
重写,是重新实现一套系统。
它通常希望达到类似的业务目标,但内部实现会大量替换,可能换语言、换框架、换架构。它更像搬出去,把房子推倒重盖。
渐进替换,介于两者之间。
你不一次性推倒整栋房,而是先换厨房,再换卧室,再换客厅。软件工程里常说的 Strangler Fig Application,常译作“绞杀者模式”或“绞杀榕模式”,大致就是这个思路:让新旧系统并行,一块一块接管旧系统的功能。
很多团队以为自己想要重写,其实真正需要的是重构。
也有一些团队确实需要重写,但最好先把它拆成渐进替换,而不是一把梭,赌一整盘。
如果一个项目还在高频服务真实用户,团队又说不清它的边界、数据关系和关键流程,那就不要急着整体重写。
如果没有可靠测试,没有监控,没有回滚方案,也不要因为 AI 能生成代码,就贸然开干。
如果重写的主要理由只是“我看旧代码不顺眼”,那更要小心。看不顺眼可能是真的,但它不等于业务上值得重写。
反过来,有些情况确实可以考虑局部甚至整体重写。
比如系统规模可控,边界清楚,失败可以回滚;旧技术栈已经带来安全、合规或招聘瓶颈;团队有足够测试样本和验收标准;新旧系统可以并行运行,逐步切换流量。
这时候,AI 很适合参与。
它可以帮你读旧代码、画模块关系、生成测试草稿、写迁移脚本、整理接口文档、实现新模块的第一版。它能让“切片重写”变得更便宜。
但关键是:不要把 AI 当成替你拍板的人。
真正的问题不是“AI 能不能写”,而是“风险能不能被切小”。
重写前,不妨先问三个问题:
如果没有 AI,这个重写在业务上仍然必要吗?
这次重写能不能拆成几个可验证的小迁移?
哪些旧系统行为必须被保留,谁来确认?
如果这三个问题答不上来,AI 只会帮你更快地进入混乱。
所以,AI 时代是不是重写项目的最佳时机?
我的答案是:可能是更适合局部重写的时期,但不是盲目推倒重来的借口。
AI 的价值,不在于让我们终于可以忘掉 Netscape 的教训,而在于让我们有机会用更低成本做更小、更快、更可验证的改造。
过去,团队可能因为重构成本太高,一直忍受旧系统。现在,AI 可以帮你把第一步迈出去:补文档,补测试,拆模块,迁移边缘功能,验证新架构。
这是一种很好的变化。
但如果一个团队没有测试、没有监控、没有迁移计划、没有业务验收,只是把旧项目丢给 AI,说“帮我重写一遍”,那它更可能不是在解决技术债,而是在把旧债转化成一份更现代的新债。
Netscape 的故事之所以还值得讲,不是因为 1998 年的答案可以原封不动搬到今天,而是因为它提醒我们:软件不是只由代码组成的。
它还由用户、历史、事故、流程、组织和时间窗口组成。
AI 可以帮我们更快写出一栋新房子。
但它不会自动告诉我们,旧房子里哪面墙其实承重。
真正成熟的重写,不是删除历史,而是先把历史翻译成测试、接口、文档和迁移路径。
如果能做到这一点,AI 时代当然可以更勇敢地改造旧系统。
但勇敢,不等于一键清空。