我的Vibecoding落地之路(老项目) 老项目 × AI从濒死到手术台我做对了什么接手一个十年老单体项目打开代码四千行的OrderService、不敢升的 JDK 1.8、被魔改的底层包、写在存储过程里的定时逻辑——那一刻我明白这不是技术债务这是技术遗产。而我要做的是带着 AI 这把新式工具把它从“濒死”拉回“体面地活下去”。写在前面这不是一篇爽文如果你也接过这样的项目——打开 IDE 要等半分钟点进一个类看到滚动条细得像根针问同事“这段干嘛的”只会收到一句“别动就行”——那我相信你看到标题时的心情和我当时一样复杂。一边是摇摇欲坠的老古董一边是号称“解放生产力”的 AI 全家桶Vibecoding、Agent、Copilot。我天真地以为把脏活累活扔给 AI我只要躺平做决策就好。结果呢AI 确实很勤快但它勤快得像个刚毕业的实习生——敢删代码、敢升依赖、敢拆结构就是不敢问“为什么”。三周血泪四次炸服七个被驳回的 PR 之后我终于摸到了一条让老项目和 AI 和平共处的路。这篇文章不吹概念只讲实操——我踩过的坑、定下的规矩、以及最后如何让那个四千行的OrderService体面地活了下来。Define一个让所有架构师头皮发麻的场景故事的开头很标准——Leader 丢给我一个任务去救火稳住一个十年老单体项目。我打开代码映入眼帘的是一个叫OrderService的类四千多行最长的那个方法翻三屏找不到结尾。依赖版本停留在 Spring 4.xJDK 还是 1.8没人敢升因为升一次崩一次。pom.xml里躺着一个被魔改过的底层包注释写着“某业务特殊需求改源码”——至于改了哪里没人说得清。数据库字段status2文档写“已审核”但线上有个定时任务每天凌晨三点会把它刷成“已删除”——而这套逻辑写在存储过程里没人敢动。我问同事“这段逻辑为什么这么写”同事答“我也不知道以前就这样别动就行。”那一刻我懂了这不是一个技术问题这是一个考古问题。而我手上最先进的工具只有一台电脑和一个刚上线不久的 AI 助手。Design我以为的“AI 解放方案”当时的想法很直接项目太复杂人看不过来那就让 AI 帮我读、帮我写、帮我改。工具链齐全理论上一周就能出效果。我设计了一套理想工作流把OrderService.calcPrice()那个几百行的方法贴给 AI让它解释业务逻辑。让它生成对应的单元测试把这个方法的行为固化下来。再让它帮我重构——把散落的校验逻辑抽成私有方法把重复的折扣计算统一收口。最后基于改动生成 Mermaid 调用关系图告诉我哪些地方会受影响。听起来很完美对吧AI 负责干脏活累活我负责做决策和 Review。但实际跑起来之后我才发现——AI 在它看得懂的地方有多聪明在它看不全的地方就有多鲁莽。DilemmaAgent 进老项目等于往雷区扔扫地机器人AI 确实勤快。但它只看到了我贴给它的那几百行代码完全看不到全局。于是灾难接二连三第一个坑擅自“优化”依赖线上炸了半小时Agent 看到redis.clients:jedis版本号是 2.9.0贴心地给我升到 4.3.0理由是“修复了已知漏洞”。但它不知道我们生产环境的 Redis 版本是 4.0更不知道项目里有十几处用到了JedisPoolConfig的旧 API。一部署NoSuchMethodError铺满日志线上直接不可用。第二个坑自作聪明删“无用代码”价格算错calcPrice()里有一段看起来毫无意义的Thread.sleep(50)Agent 判定为“性能垃圾”当场删除。但那行代码是三年前为了等主从同步而加的操作——虽然写法不规范但十年来没人敢动。删除之后主库刚写入的订单数据在从库查不到价格全算错财务第二天追着我骂。第三个坑疯狂重复造轮子代码量膨胀 10%上午我让 AI 写了个手机号脱敏工具类PhoneMaskUtil。下午让它改另一个模块的用户信息展示它又写了个UserInfoMaskHelper功能几乎一模一样。短短一周项目里多了二十多个工具类代码量膨胀了近 10%。第四个坑修一个 Bug生出三个新 Bug我让 AI 修一个空指针异常它加了个判空返回空列表。本地测试通过上线后下游计算平均值直接除以零又炸了。AI 只管“当下这个方法的返回值不空”压根不会去扫调用方怎么消费这个返回值。最崩溃的是第五个坑修复死循环变成死循环我反馈 → AI 改 → 引入新问题 → 我再反馈 → 它再改。同一个类的同一个方法来来回回提了七个 PR全是 AI 写的。我每天的工作变成了点“驳回”和“重试”像个高级测试员而不是架构师。那一刻我彻底清醒让 AI 在老项目里自由奔跑它不是手术刀是挖掘机。Deliver血泪里总结的四条铁律被折腾了三周后我终于摸索出一套能打的方案。核心思想就一句话让 AI 当实习生干局部脏活所有架构决策必须捏在人类手里。第一条先画红绿灯再让 AI 进门我在项目根目录建了一个.ai-rules.md每次对话开场第一句就是“先读这个文件”。里面三块内容红灯禁区升级依赖、删方法删字段、删配置文件、改核心公共类、动数据库。AI 敢碰一次直接驳回。黄灯确认区新增工具类、改 Controller 入参出参、改事务行为。AI 可以提方案但必须我点确认才能合入。绿灯自由区方法内部算法优化、if-else 简化、加日志、写注释、生成单元测试。规则定死之后AI 的犯错率直线下降至少它不敢再碰pom.xml了。第二条测试先行没有安全网不准动手术老项目最大的痛点是“没有测试”。所以我强制要求改任何代码之前先用 AI 生成特征测试——让 AI 根据当前方法的行为逆向生成单元测试跑通之后这些测试就变成“护城河”。改造完成后跑一遍测试全绿才能提 PR。这一步把“改崩了都不知道”的恐慌彻底掐死在本地。所有测试都用 Mockito 隔离外部依赖套件能在 30 秒内跑完开发中随时可以快速验证。第三条拆分任务一次只改 20 行绝不允许对 AI 说“重构整个订单模块”。只能指定具体的方法和行号范围例如“把OrderServiceImpl.createOrder()第 50 到 70 行的参数校验逻辑抽成一个私有方法保持原有功能不变。”每次改完立即跑测试立即提交。一个模块拆成四五十个小任务累是累了点但安全。第四条人类 PR 必过三关AI 提交的 PR必须经过三道检查才能合入依赖检查pom.xml或build.gradle有变化直接驳回理由就一句“你没权限碰这个。”删除检查原有代码一行不许删仅允许删除 AI 新增的调试代码。AI 觉得“没用”的代码我宁可留着也不让它删。日志检查有没有把System.out.println带进生产代码AI 经常干这事见一个打回一个。额外收获让 AI 反向考古AI 不适合改老代码但特别适合读老代码。我把那段神秘的Thread.sleep(50)丢给 AI让它分析上下文它还真猜出来了——“疑似等待主从同步”。虽然不敢 100% 确认但至少给后续排查提供了方向。我还让它给整个订单模块生成了调用关系图清楚看到calcPrice()被哪些上游依赖彻底解决了“改一处不知炸哪里”的恐慌。结尾AI 是手术刀还是挖掘机取决于你怎么用老项目不是一个可以“一步到位”重构的东西。它是十年里无数个“先上线再说”的妥协累积出来的产物里面每一行看似愚蠢的代码背后可能都藏着一段血泪教训。Vibecoding 和 Agent 给了我们强大的生成能力但生成能力越强越需要有边界。我的经验总结成一句话就是人指路AI 干活测试保底人把关。按照这个流程我那个四千行的OrderService用了一个月拆成了七个类每个类五百行以内单元测试覆盖率从 0 提升到了 67%。过程中 AI 辅助生成了初稿但核心逻辑部分人工重写了约 40%——没有任何一行代码未经 Review 就直接上线。你问我现在还敢不敢让 AI 改老项目敢但戴好手套、穿好防护服。老项目还能再活十年。只不过这一次是带着 AI 这把手术刀体面地活下去。而那个曾经问“这段逻辑为什么这么写”的我如今会笑着回答自己“我不知道没关系但我知道怎么让 AI 帮我去查、去试、去验证同时不炸掉整个系统。”这才是架构师该干的事。