老系统技术栈升级可能是整个软件工程里最不受待见的项目类型。它不像新项目那样有从零到一的兴奋感也不像热门框架那样能在简历上写一行用了某某最新技术但它又是每个有点年头的团队躲不开的课题。我最近就陪着朋友处理了一个跑了八年的 Java Web 老系统Spring 3 Struts2 自定义 JS 全家桶数据库是 Oracle 11g代码量二十万行左右还在坚持服役。业务方一边抱怨页面卡、扩展难一边又不敢真的停掉它。好不容易凑出一个月时间窗口准备做一次局部技术栈升级——先把 Spring MVC 部分换到 Spring Boot再把部分页面用新框架重写存量功能必须行为不变。这时候问题就来了时间紧人少老代码没人愿意碰靠人肉去看这二十万行既不现实也不放心。于是我们开始认真思考AI 能帮上什么忙。这不是一句焦虑营销式的口号而是实在的问题:在这类工程改造里,AI 到底能在哪个环节替人省时间?哪些事交给 AI 做是靠谱的?哪些事看似可以,实际上会埋雷?这篇内容,我会把这几个月里实际用 AI 参与老系统技术栈升级的经验,按工作流的顺序拆开来讲,包括代码梳理、方案选型、替换重构、测试回归、文档补齐这几块,也聊聊 AI 的边界和团队怎么配合。1. 先看清现实老系统升级失败死因往往不在技术上1.1 技术栈升级的本质是行为不变结构变一说技术栈升级很多人第一反应是换框架、换语言、换数据库。但真正做过的人都知道技术栈只是一个壳壳底下真正难搞的是业务逻辑。老系统跑了多少年里面就沉淀了多少年累积的隐性规则某个字段为什么这么算某个按钮为什么点了两次才算某张表为什么留下了冗余列——这些谁都不清楚但没人敢删。所以我在动手前先给团队定了一条铁律技术栈升级不是重写业务而是在保持对外行为不变的前提下替换技术实现。这条铁律决定了后面的一切方法。这条铁律也决定了 AI 的角色AI 不是用来设计新业务的而是用来理解旧行为和搬运旧行为的。工具能不能用对首先取决于你把这颗弦绷得紧不紧。1.2 常见死因排序不是技术选型翻车而是理解断层我见过不少升级项目最后失控梳理下来就两类原因。第一类是范围蔓延升级过程中看到老代码不顺眼顺手就优化优化结果改了不该改的逻辑上线就出问题。第二类是知识断层写老代码的人离职了文档又缺失接手的人看不懂不敢动只能东拼西凑。这两种死因AI 其实都能帮上忙。范围蔓延可以通过AI 只做翻译、不做创作的工作纪律来约束知识断层则可以通过 AI 的代码解析和信息抽取来缓解。当然这是理想状态。想让 AI 干活你得先知道你手里有什么料。大部分老系统的料就是代码本身少数运气好的还有接口文档和数据库设计说明书但无论哪一种都需要我们主动整理好、喂给 AI而不是期待它自己会去翻。1.3 把升级流程拆开看 AI 的插入点老系统技术栈升级通常可以拆成四个阶段:摸家底、定方案、动手改、验证上线。这四个阶段里AI 的参与深度不同摸家底AI 做代码理解、依赖分析、模块梳理这是目前最成熟的用法。定方案AI 做技术选型对比、迁移计划草案可以当顾问但不能当决策者。动手改AI 做代码翻译、重构建议、脚手架搭建这是效率提升最明显但也最容易埋雷的环节。验证上线AI 生成测试用例、执行回归、分析日志这是最值得投入的环节。后面几节我会按这个顺序展开。先讲第一步读懂老系统。2. 代码考古AI 帮我三天读懂跑了十年的老代码2.1 老代码不是不能读而是读不过来二十万行 Java 代码加上数不清的 JSP、JS、XML 配置文件靠人肉通读是不现实的。传统做法是找核心模块按链路去追但每个人对核心的理解不一样容易遗漏那些藏得很深的公共逻辑。我们这次换了思路不追求从头到尾通读而是先用 AI 做一层代码考古把系统结构、模块边界、核心链路、数据流向这些地图画出来再由人沿着地图去验证和深挖。注意这里说的画地图不是让 AI 给你画架构图而是让 AI 从代码里抽取出关系网哪个 Service 被哪些 Action 调用哪个 Mapper 对应哪张表哪个公共同步方法影响了哪几个业务模块。有了这张关系网你在读代码的时候就不是盲人摸象了。2.2 怎么给 AI 喂代码效果最好很多人用 AI 看代码上来就丢一整个仓库问帮我看下这个项目——结果不是上下文超长就是回答泛泛而谈。我的经验是让 AI 干活前先把喂食环节设计好。实操步骤大概这样先给 AI 一个项目级问题清单按层次分批提问。比如项目分几个模块核心实体有哪几张表状态机怎么流转每个问题对应一个聚焦范围不要把看懂整个系统当成一个 prompt 丢出去。对单个文件或单个函数把那一段代码贴在 prompt 里附加上下文比如它调用了哪里、被谁调用让 AI 用自然语言描述它在业务流程里的位置。对跨文件调用链让 AI 先列文件清单和关键方法签名再逐步追问。相当于让 AI 先梳理地图上的节点再填节点之间的关系。这里完全可以借助主流 AI 编程助手的仓库级问答能力比如支持整个代码库检索的工具它能把符号索引语义搜索大模型生成结合起来。实测下来配合先问结构、再问链路、最后问细节的提问顺序比随手把文件塞给通用大模型要精准得多。2.3 一个真实的代码考古案例报价单模块有个核心模块叫报价单被 Action、定时任务、消息队列三处调用逻辑散落在五六个类、三个存储过程里真正的业务规则只有老员工脑子里有。我们用 AI 做了这么几步第一步让 AI 找到所有与报价单相关的类和方法输出调用关系清单。这一步传统 IDE 的 Find Usages 也能做但 AI 能顺带告诉我们哪些调用是主链路、哪些是历史遗留的零散调用。第二步把核心报价方法切分成若干小段逐段让 AI 用业务语言解释这段在算什么、会影响什么。AI 的解释不完美但足够当向导后续由人复核。第三步把所有 AI 解释汇总让 AI 生成一份报价单模块行为说明标注出它不确定、需要人工确认的部分。这份说明后来直接成了改造方案的需求底稿。说实话AI 的解释里也会出错比如对某个异常分支理解偏了或者漏掉了某个隐藏的副作用。但在人肉读需要两周、AI 梳理加人复核需要三天的对比下效率提升是实打实的。2.4 提示词是考古铲要舍得磨这里分享几个我实测好用的提示词模板按顺序微调就行你是熟悉 [语言/框架] 的资深架构师。请根据以下代码用业务语言描述它实现了什么功能包含哪些输入、输出、状态变更和异常分支 [代码片段]现在要改造这个模块请列出所有外部依赖数据库表、接口、缓存、消息队列以及在代码中的具体位置。这段代码存在哪些隐藏的耗时点或风险点请结合上下文说明。注意再好的提示词也替代不了你对业务的判断。AI 负责把发生了什么讲清楚负责为什么要发生的永远是人。3. 选型与迁移方案让 AI 把拍脑袋拉成决策矩阵3.1 先别急着问新不新先问匹配不匹配老系统技术栈升级最难的不是编码而是选型。团队内部经常吵成一锅粥:有人想换微服务有人想用看似更快的 NoSQL有人盯着刚出的框架版本跃跃欲试。这个时候AI 能当很好的破局工具。我的做法是把要不要换、换成什么这个问题变成一张可对比的决策矩阵。3.2 用 AI 生成技术选型决策矩阵把老系统的现状整理成一段描述丢给 AI让 AI 按以下几个维度输出对比表团队熟悉度、迁移成本、运行时兼容性、社区活跃度、长期维护成本、对存量数据的影响、灰度难度。举一个实际例子我们当时在继续用单体Spring Boot和拆微服务之间犹豫。AI 给出的矩阵很直白:维度单体 Spring Boot微服务拆分团队熟悉度高现有 Java 成员直接上手低需要学习注册中心、网关、配置中心等迁移成本低主要改启动方式与依赖高模块边界、通信协议、数据拆分都要重做运行时兼容性高原有调用链基本不变低涉及网络调用、序列化、分布式事务社区活跃度高高长期维护成本中单体膨胀后仍需治理高运维组件多对团队规模有要求对存量数据影响小大数据库拆分风险高灰度难度低高链路追踪和灰度策略复杂团队规模五个人业务模块十几条微服务的收益独立部署、独立扩展根本用不上成本运维复杂度、分布式事务、链路追踪却要全量承担——结论自然就出来了。同样的方式数据库要不要从 Oracle 迁到 MySQL、缓存要不要引入 Redis都可以拉矩阵对比。有了这张表技术选型就不再是谁声音大听谁的而是谁说得清成本收益听谁的。很多团队以为 AI 只是会聊天其实这种把模糊诉求结构化的能力才是它在方案阶段最值钱的地方。3.3 让 AI 出迁移计划草稿但要自己改三遍AI 是可以直接给迁移计划建议的比如分几期、每期做哪些模块、回流方案怎么定。对这种建议我的态度是拿来做初稿但必须自己再改三遍。第一遍删掉所有听起来很对、但本系统里不存在的内容。AI 容易从通用经验出发列出不符合项目实际的步骤。第二遍根据历史踩坑经验往里加约束比如数据库变更必须先在预发跑一遍核心模块改动要双人复核灰度周期至少一周。这些约束来自团队纪律AI 不知道但它生成的骨架能帮你把这些约束排进计划里。第三遍给每期目标加退出条件。升级方案不是用来做 PPT 的它是用来对进度的。没有退出条件方案很容易变成永远差的最后十分之一。3.4 影响面分析AI 帮你避免改一个函数炸一条链路迁移方案里最怕的就是只想改 A结果动了 BCDE。我们让 AI 做了两次影响面分析第一次在开工前针对要替换的模块列出所有上下游依赖第二次在改造中每次提交前,让 AI 对比 diff提醒这个变更会影响到哪些调用方。第二次这个用法特别推荐等于给代码 review 加了一个 AI 哨兵。你甚至可以把它固化到提交规范里每次 PR 描述必须写清楚影响面自评再由 AI 辅助审查。4. 动手改造AI 写码、翻译、重构但人必须审4.1 三种常见的改造类型AI 参与度不一样老系统技术栈升级落到动手改这个环节通常会遇到三种类型。第一种纯语言版本升级。比如 Java 8 升到 Java 17或者 Python 2 升 Python 3。这类工作里有很多机械性的更新过时的 API、旧语法、不兼容的库。AI 相当擅长处理因为它的训练语料里这类迁移案例极多。但要注意它不是全能一旦编译通过就不管运行行为这是我们要补的功课。第二种框架替换。比如 Struts2 换 Spring BootjQuery 换 Vue。这类工作一半是翻译一半是重新设计。AI 能把旧的请求处理方式翻译成新的注解风格但页面组件的拆分、状态管理设计、前后端接口约定这些更需要人来定。第三种架构级重构。比如把单体拆成服务或者把存储过程迁移到应用层。这种 AI 帮不上什么大忙最多是辅助生成代码骨架和梳理边界。真正的架构决策还是要靠人。我们这次主要是第一二种混合。针对性最强的是一个Spring 3 Struts2 存量页面用 Vue 重写的任务AI 帮了大忙但也让我看清了它的上限。4.2 实操Java 8 到 Java 17 的迁移AI 怎么用先说纯语言升级。我给 AI 贴了一段老代码让它给迁移建议。AI 直接列出几个关键修改点把已废弃的 API 换成新的替代品、用var做局部类型推断、用 pattern matching 做 instanceof 检查、移除过时的 GC 参数建议等。我没有直接全盘接受 AI 修改后的代码而是先要求 AI 生成修改理由清单列清楚改了哪里、为什么改、有什么风险。这么做的原因是老系统里很多旧写法不是写错了而是当时为了兼容某个环境故意写的。如果不知道修改理由删掉后可能埋下运行时炸弹。代码迁移这里给一个实用建议把 IDE 自带的迁移辅助工具先跑一遍再把 diff 丢给 AI 做逐条解释。你会发现 AI 对 diff 的解释质量远高于让它自己从头写一遍迁移代码。因为 diff 已经框定了变化范围AI 只需要做解读而不是创作出错的概率会低很多。4.3 老页面改造成 VueAI 写页面人写边界另一个典型场景是页面层迁移。老系统页面大多是 JSP 里嵌 HTML 加 jQuery新页面要用 Vue 3 加组件化。迁移工作分三步第一步AI 把旧页面翻译成新页面。把旧 JSP 的 HTML 结构和后端渲染逻辑贴给 AI让它输出 Vue 组件同时标注出哪些是动态渲染部分、哪些需要从后端接口取数。第二步我给 AI 提供接口定义和字段映射表让它把取数逻辑换成 axios 调用。这一步 AI 经常出错比如把字段名搞混、漏掉异常处理。必须逐行校对。第三步统一交给人做交互走查凡是涉及复杂状态流转、权限控制、异步竞态的部分一律人工造数据验证。用下来AI翻译单个静态页面效率很高一页大概能省四十分钟。但一旦涉及动态交互人工成本还是在的。别指望全程无人值守。4.4 编译过不等于可以上线运行时行为差异要自己兜底这是这次升级里最深刻的教训。我们有一个导入导出功能AI 翻译代码后编译、单测全过结果在预发测试时发现历史数据里的日期格式没按预期转换——因为旧代码依赖了服务器的默认时区而新框架换了个时区。这种运行时行为差异不靠 diff 是看不出来的只能靠新旧系统的对比测试来兜底。所以我们在项目里定了一条死规矩任何模块改造完成都要跑一遍行为对比测试把新旧系统的输入输出拉出来对拍差异不一致就不允许上线。5. 测试与回归AI 让上线靠胆量变成验收靠基线5.1 老系统最缺的是有据可查的基线很多老系统没有自动化测试测试方式就是改完点一点感觉没问题就上线。技术栈升级最怕这种状态因为你连改动前后的基线都没有出了问题都不知道是谁改出来的。我们有段时间花了不少功夫补测试后来发现 AI 能帮上大忙。具体做法是让 AI 根据旧代码和接口定义生成测试用例先测旧系统把输出结果作为基线保存下来。新系统完成后再跑同样用例输出和基线对齐的就算通过不对齐的进人工评审。5.2 AI 测试用例生成的关键技巧真实数据比边界值更重要AI 生成测试用例最常见的毛病是太标准了——单元测试喜欢造干净的数据边界值一个不少但真实业务场景里那些乱数据反而很少覆盖到。我的做法是把老系统的真实请求日志喂给 AI让它根据真实输入生成测试数据。比如日志里有一个订单金额 -9999 的异常记录AI 看到后会专门为它生成一个用例去验证新系统对这个异常输入的处理是否和旧系统一致。这种基于真实数据的用例比拍脑袋造的数据靠谱得多。5.3 跑 Diff 测试新旧系统的行为对拍Diff 测试是这次升级里性价比最高的一个环节。做法并不复杂准备一批覆盖各种场景的请求数据分别打到新老两套系统上把响应结果做结构化对比输出差异列表。AI 在这里有两个用途第一个分析差异列表把合理差异比如换了框架导致的时间格式变化、字段命名变化和可疑差异比如同样输入返回了不同结果、状态码不一致自动分类。第二个对可疑差异做代码定位指出问题可能出在哪个函数。这个环节做好之后整个升级团队的信心提升是肉眼可见的。原来大家想的是希望能上线求别炸后来变成了只要对拍通过上线就不慌。5.4 测试结果不过让 AI 当日志分析员如果对拍测试跑出了差异先别急着打开 IDE 翻代码。把两份日志交给 AI让它先抽丝剥茧请求参数是什么、哪个环节开始分叉、异常堆栈指向哪里、旧代码里的处理逻辑是怎样的。大多数情况下AI 能在几分钟内给出一个可疑函数列表比人肉翻日志快很多。我们在一个存储过程迁移到 Java 的任务里就靠这个技巧把排查时间从一天缩短到了半天。6. 文档和知识转移AI 把一个人脑子里的东西变成团队的资产6.1 老系统普遍只写代码不写文档现在可以补老系统的文档往往停留在装了个 Tomcat连接了数据库这种级别真正的业务和技术细节都在代码里。想靠文档了解系统是不可能的但升级改造又必须要文档——不然改完知识又变成一个人的。我们这次的做法是代码即真相路线以现有代码为唯一事实来源用 AI 从代码里面生成设计文档、接口文档、数据库字典。生成的文档不一定完美但至少以后新同学接手不用再靠嘴对嘴传知识。6.2 AI 生成文档的实操清单接口文档让 AI 根据 Controller 和 Service 方法生成参数、返回值、异常说明。对于老系统没有 OpenAPI 注解的情况这招特别管用。数据库字典让 AI 根据建表 SQL 或实体类生成字段说明补充注释。结合数据字典和代码中的字段映射能还原出一张业务翻译表。部署手册让 AI 根据 Dockerfile、启动脚本和配置中心内容生成步骤说明把散落在各处的环境变量和启动参数整理成文档。每份文档生成完都找熟悉模块的老同事过一遍把AI 漏掉的历史背景补进去。这项工作看起来不起眼但它决定了升级之后的系统是可接手的系统还是下一个老系统。6.3 升级过程本身就是一次知识梳理AI 当速记员升级改造过程中团队会产生大量决策和踩坑记录。过去这些知识都散落在聊天记录、会议纪要和个人笔记里项目结束后就丢了。我们立了个规矩每次改造讨论或者代码评审让 AI 做详细记录员输出统一格式的《技术决策记录》——今天决定了什么、为什么这么选、影响范围是什么、谁负责跟进。这个记录最后变成了一份有价值的项目资产比任何年终总结都实在。这里也可以引入一点AI Agent的思路把代码审查、文档生成、测试执行拆成几个独立的小任务让 AI 按固定流程跑关键节点由人来确认。不一定要做得多复杂哪怕只是把AI 整理会议结论自动同步到文档这个动作跑顺团队协作的体感就会完全不一样。7. AI 的边界与团队协作别把 AI 当成自动升级按钮7.1 哪些环节 AI 确实帮不上尽管 AI 在这次升级里贡献很大但有几个环节我是不会交给它的。第一业务规则的最终解释权。老系统里那些说不清为什么这么写的代码AI 只能猜不能拍板。真正决定要不要保留这个行为的是对业务熟悉的人。第二架构决策。AI 可以把方案选项摆出来但拆不拆、怎么拆、优先级是什么这些权衡需要结合团队能力、业务节奏、资源情况来做不是一个模型能替代的。第三跨系统的组织协调。升级往往要拉上运维、DBA、业务方一起排期。这个环节的沟通和项目管理AI 目前还做不了。7.2 团队怎么配合让 AI 当新员工人当老专家我的建议是把 AI 当团队里一个学习能力极强、但经验不足的新员工来用。它可以在你指导下快速完成大量任务但方向和验收必须由人把控。落地到团队分工上大概是这样的资深开发负责切片、定级、验收、拍板。业务知识最核心的部分一定在他们手里。初中级开发负责执行 AI 生成后的复核和细节修正相当于代码校对员。AI负责初稿生成、文档整理、测试执行、差异分析等偏体力化的环节。每个人跟 AI 的接口就是一份任务卡片——输入材料、期望产出、验收标准。7.3 最后给准备升级的团队几个建议不要把 AI 的使用局限在写代码上升级项目里真正花时间的往往是理解代码、对齐行为、守住边界这才是 AI 最大的价值地带。所有 AI 生成的内容都要标记AI 生成待人工确认尤其是涉及业务规则的部分。可以建立一个共享的确认清单逐条勾销避免遗漏。升级不是一个月的短跑是一场有节奏的改造。AI 能帮你提速但节奏和质量的门还是人来守。回头看这次老系统技术栈升级AI 最大的贡献不是帮我多写了多少代码而是把那些原本要靠人力硬扛的理解成本、迁移成本、验证成本压了下来。代码还是那些代码业务规则还是那些规则但 AI 让团队第一次有底气说这二十万行老代码我们读得懂、改得动、验得完。对我来说,这才是它在这场升级里真正的价值。