用codex重构遗留系统的实战复盘

用codex重构遗留系统的实战复盘

没有银弹,但确实存在一个突破口。我们在一个跑了九年的交易后台系统上做了一次验证,核心结论是:Codex 最大的价值不在“自动写代码”,而在于让团队第一次真正“看懂”了那坨屎山。

那个系统的情况很典型:核心结算模块十二万行 PHP,最早的提交记录可以追溯到 2016 年,中间换过三批开发团队。文档为零,注释是考古现场,有的已经误导了五年。每次上游业务规则调整,开发组都要靠“猜”和“灵媒式推理”来判断改动范围,一次简单的费率变更能排两个 Sprint。

我们之所以启动这次重构尝试,不是因为 AI 火了想蹭热点,而是被一次线上事故彻底逼到了墙角。

一、先看结论:三个月后的真实效果清单

把结果放在前面,因为大部分“经验分享”喜欢先铺垫三千字再来一句“AI 真香”,这没什么意义。我们复盘时把效果分成三档,做到位的、勉强及格的、彻底翻车的。

✅ 做到位的

1. 新成员上手时间从三周压缩到四天。

我们用一个结算模块做样本,喂给 Codex 后生成了第一版“活文档”,包括函数调用链、数据流图、关键类职责说明。虽然不是 100% 准确,但新人可以对着这份文档追踪业务逻辑,而不是像以前那样靠口口相传和翻代 v1.2 的邮件。

2. 故障定位平均时间缩短 62%。

这是用 PagerDuty 数据拉出来的硬数字。过去线上出问题,值班开发要靠 grep + 灵光一闪来定位。现在先丢给 Codex:“这段堆栈信息对应哪个业务流程?这个函数在哪些上游被调用?”,通常 30 秒内能圈定可疑范围。这里的关键不是 Codex 比人聪明,而是它不会漏,人紧张的时候容易跳行,它不会。

3. 拿到了第一张系统模块依赖图。

这是以前至少需要资深开发投入两周人力的工作,现在三个小时完成草稿,再用一天人工校验。

⚠️ 勉强及格的

1. 自动重构输出质量不稳定。

长函数拆分这类任务,Codex 能做,但风格不一致。有时拆得过于激进,一个函数被炸成十一个碎片,反而降低了可读性。

2. 需要持续人工审查。

生成代码的问题不是“会不会有 bug”,而是“bug 的类型变得陌生了”。传统开发容易犯空指针错误,Codex 容易犯业务逻辑错位,看起来合理但实际不是你要的。

❌ 彻底翻车的

1. 最初两周试图直接让它重写整个模块。

我们把一个 A 类核心模块完整喂给它,写了一份两百字的 Prompt,期待它输出重构后的完整代码。结果拿到了一个语法完美但业务逻辑烂穿地心的版本。这相当于让一个没读过你五年迭代史的人,原地重新发明你的业务,不翻车才奇怪。

2. 自定义技能系统过度设计。

这是我们代价最大的错误。受一些社区文章的启发,我们给 Codex 配置了十七个自定义 Skill,覆盖从“检查是否符合公司命名规范”到“检测历史 Bug 模式”的方方面面。结果不仅没有提升准确度,反而让推理时间变长、输出质量下降。最终花了两周才排查到问题根因,“技能肥胖症”。

二、那座“大泥球”到底长什么样

为了让后来的团队少走弯路,我先描述一下我们面对的系统的真实画像。这不是比喻,是实际诊断结论:

  • 上帝类占比 37%: 一个结算单据处理类塞了 8000 多行代码,承担了单据验证、金额计算、日志记录、消息推送、缓存更新等六种职责。
  • 循环依赖深不见底: 试图单独实例化某 Service 类,PHP 的 autoloader 会像多米诺骨牌一样拉进来半个业务层。DI 容器配置了等于白配置。
  • 测试覆盖率 2.1%: 全项目唯一的测试用例是某个离职同事留下的登录接口冒烟测试。
  • SQL 散落各处: 拼接语句藏在 Model、Controller、甚至某一个视图逻辑判断里,DBA 审核流程形同虚设。

这种系统怎么维护?长年的做法就是“补丁式重构”,找到最小改动点,用最安全的方式把功能塞进去。风险最低,但债务累积最快。每次打补丁就像往一锅粥里加水泥,短期凝固了,长期更难搅动。

我们清楚地知道不能再这样下去,但也清醒地知道自己不是“重写派”,你不可能让业务停下六个月等你从头来。折中方案是:用 AI 辅助,在保持系统运行的前提下,逐步理解并改善核心模块的结构。

三、我们差点被自己蠢死的三个坑

先说失败的部分,这是本文最有价值的东西。

坑 1:把 Codex 当许愿池

最初两周,我们对它的态度可以概括为:“你很强大,这是老系统,把它变干净。”

比如给过一个 Prompt:“重构这个结算类,遵循 SOLID 原则,提高可维护性。” 输出的代码确实拆了类,依赖注入也用上了,看起来像教科书。但运行之后,发现它把“满减优惠和抵扣券互斥”这个在代码中用 if 嵌套硬编码的关键业务规则,给“优化”成了一条错误的互斥逻辑。

教训: Codex 没有业务记忆。它不理解你们的商业规则,也不理解那些看起来丑陋的代码背后可能是三次故障之后留下的防御性逻辑。在大幅度重构前,你必须先让它或者你先搞清楚,这段代码能跑,从来不是因为写得好,而是因为 bugfix 堆得够厚。

坑 2:技能肥胖症

我们给 Codex 配置了十七个自定义 Instruction,试图教会它我们的规范、历史错误模式、甚至业务术语表。悲剧的是,这些技能指令之间产生了隐形冲突。比如“命名规范检测”规则要求方法名不能超过 30 字符,但“历史 Bug 模式检测”规则要求方法名必须显式描述其副作用,两者同时生效时,它开始生成一堆又长又不能用的名字,自己还顺着自己的规则反复修改,Token 消耗直接爆了。

最后我们砍到只剩下三个核心规则:理解当前文件所有函数作用对比 git diff 前后的逻辑差异用一句话总结每次修改的原因。出乎意料的是,能力反而更好了。

教训: 给 AI 添加“技能”就像给狼喂食,你以为是投喂,它可能只是变得更懒了,它会开始对着大量技能指令反复印证循环,而不是根据真实代码推理。保持瘦,保持锐利。

坑 3:没有安全网就开始蹦极

我们在最初尝试自动化修复 Bug 时,过于相信 Codex 对“向后兼容”的自觉。有一次它修改了一个核心计算方法,我们跑了一遍单元测试(虽然覆盖率低但至少有一个),通过了,便直接部署上去。结果,凌晨两点半,P0 告警。

直接原因: 修改某个函数的参数默认值,引发了调用链深处一个从来没被测试覆盖过的边界场景。

根本原因: 我们没有一个足够坚实的测试基线,却先上线了 AI 的自动修改。

这是整个项目中我们离被开除最近的一次。从此之后,CI 流程里多了一条铁律:任何 AI 提交的代码,必须触发一次全量回归测试(先不管覆盖率,至少有);且必须由两名开发者审查通过。

四、转折点:让 Codex 做“扫地僧”,而不是“救世主”

在经历最初两周的全面溃败后,团队内部开了一次会(吵了三个小时),做出了核心策略调整:从“让 Codex 写代码”转向“让 Codex 帮我们读懂代码”。

这件事背后有一个产品设计的底层逻辑:遗留系统中,“不理解而修改”造成的破坏,远大于“代码本身就烂”所造成的破坏。 代码不会自己变烂,它变烂是因为 50% 的新需求在不理解旧逻辑的情况下被强行塞进去。

我们是怎么做的?

步骤一:模块采样与喂料。

选定结算模块,把该模块内所有 PHP 文件、关联的 SQL 查询、以及近三年的 Git 提交记录摘要,作为上下文喂给 Codex。不要求它写代码,只问具体问题。

步骤二:生成“考古报告”。

让它逐个分析核心函数,回答下面几个问题:

  • 这函数到底在做什么?(用非技术语言描述)
  • 它的输入来自哪里?输出被谁消费?
  • 近三年被改过多少次?改的时候修了什么 bug?

步骤三:构建可运行的“活文档”。

将上述结果整理成一份在线协作文档,每个模块都有统一的描述模板。这份文档不是完美的,但它是“活的”,每当我们遇到不理解的地方,第一反应是去问 Codex,而不是找那个早就离职的张三。

实际效果:一次三小时搞定的历史疑难杂症

有一个尘封已久的 Bug:当退货单包含特定品类的商品时,结算金额会多算一笔折扣。传统排查方式是几个人对着代码一行行读,至少需要一天。

用了 Codex 后的排查流程是:

  1. 把错误订单号和对应堆栈日志发给 Codex。
  2. 问它:“在结算流程中,哪些环节可能产生这个金额差异?对应代码在哪里?”
  3. 它在一个小众的折扣兼容逻辑函数里,找到了一个三年前为了兼容某渠道特殊活动而写的硬编码判断。那个判断,完全不在现有任何文档里。

从接到 Bug 到定位根因,实际耗时 3 小时 12 分,其中人工验证逻辑合理性占了大半时间。

五、一次成功的“人机协作重构”实盘

在理解系统架构的基础上,我们终于有底气进行第一次小范围重构。

选择目标:一个相对独立的“发票状态机”

这个状态机有 12 种状态转换,但逻辑被分散在三个控制器、两个 Service、以及一堆数据库触发器中。可以把它理解为“高内聚但实现散落”的典型。

协作的具体分工

任务 谁负责 原则
定义重构后的目标接口 架构决策不做外包
编写状态迁移的单元测试 安全网必须人造
抽取散落的状态逻辑 Codex 纯体力活
生成符合 PSR-12 的代码框架 Codex 无价值重复劳动
合并后全量测试 CI + 人 必须双人审查

操作过程

  1. 信息喂入: 把三个控制器、两个 Service 中有状态判断逻辑的方法全部提交给 Codex。同时附带现有的状态转换测试用例草稿( 我们自己写的,覆盖率约 85%)。
  2. 逻辑抽取: 指令是“扫描这些文件,识别所有与发票状态转换有关的 if-else / switch-case 逻辑,将它们汇总到一个新的状态机类中,不改写逻辑本身。”
  3. 代码生成与审查: 获得输出后,我们重点关注“逻辑是否被完整迁移”,一个分支一个分支地对,确认转换条件没有遗漏,然后跑测试。
  4. 部署与监控: 旧代码保留但不调用,新代码上线后,用 feature flag 灰度流量。

效果:状态机代码可测试性从零提升到 85% 覆盖率,后续两个业务需求的开发只花了原先三分之一的时间。

六、什么情况下你应该这样干,什么情况下不该

不是所有遗留系统都值得这样做。下面这张对照表是我们的真实取舍标准。

判断维度 适合引入 Codex 不适合引入
系统体量 3 万行以上,人力已无法在脑内构建完整模型 只改几行代码的小脚本
文档状态 核心模块无文档或文档过时超过两年 文档齐全且持续维护
测试状态 至少能跑通端到端主流程测试(覆盖率无所谓) 完全无法运行 / 无法在本地启动
业务理解 团队对核心流程有基本共识(至少主题专家还在) 完全接手的黑盒系统且无人懂业务
团队能力 有至少两名能鉴别 Codex 输出质量的开发者 全是初级开发,无力审查 AI 代码

一个坦白的原则:如果你的测试无法在本地或 CI 中全部通过,就不要让 AI 动生产代码。 人犯错还能追责代码审查,AI 犯的隐性错误在无测试环境下就是定向爆破。

七、给你的落地行动清单

如果你也在面对遗留系统,这是我基于这次复活(或者说爬坑)过程总结的四条可执行建议。

1. 别上来就重构。先把测试搞到可跑。

没有测试以前,AI 的每一个修改都是一次掷骰子。优先修复环境、补写核心流程测试、保证 git bisect 可用。

2. 用 Codex 打印“理解清单”,而不是“代码清单”。

为每个核心模块生成简要说明:它做什么、被谁调用、依赖什么。这些信息比任何自动生成的代码都更能救命。

3. 保持工具指令的“瘦”。

我们的血泪经验是:规则数据要“少而精”。三条以内是增效,十条以上大概率自噬。只保留最核心的质量准则,其余的全部用人类的审查来保证。

4. 人机边界要硬。

  • AI:负责“看见”,扫描全部代码,找出模式,列出所有线索。
  • 人:负责“决策”,识别哪些是真正的债务,哪些是防御性代码,哪些是陈年的妥协。
  • AI:负责“执行”,把人类的决策用标准语法实现出来。
  • 人:负责“确认”,审查、测试、负责。

过去一年,整个行业对 AI 编程的态度经历了“神化-幻灭-冷静”的过程。我们恰好是在幻灭期入的场,跌的坑足够多也足够深,所以才有资格把话说得具体且难听:

Codex 不是重构的救世主,但它是一个不会被你看不懂的代码吓跑的、不会不耐烦的、不会因为觉得太复杂而敷衍你的队友。别把它当神,把它当那个愿意陪你把一坨屎山翻一遍的完美工具人,然后你来做那个最终拍板的人。

下一步你可以做的:

把你们团队最头疼的那个模块挑出来,只做一件事,用 Codex 分析它,生成一份你能看懂的、关于“这玩意儿到底在干嘛”的文档。如果你发现这步都做不好,那至少说明:之前的混乱不是技术问题,是连唯一线索都没人梳理过。而这,恰恰是你能最先修复的债务。

常见问题解答(FAQ)

1. Codex在重构遗留系统时,最大的价值到底是什么?不是自动生成代码吗?

网上都说Codex能‘几分钟重构老项目’,但我实际试了,它生成的代码根本跑不通,花了两天才把bug修完。后来我发现,最好的用法根本不是让它直接写,而是用来‘读懂’那堆烂代码。你能跟我讲讲,Codex在这个场景里真正的杀手功能是什么吗?

我接手过一个10万行的Java遗留系统,代码没有注释,函数跨越5个类相互调用。一开始我也让Codex直接重写模块,结果它生成了10倍于原代码的新类,还引入了循环依赖。后来我调整策略:只拿Codex当‘代码翻译器’。

我把一条核心数据流(从Controller到数据库的增删改查)喂给它,让它逐层追查并生成带注释的调用链路图。结果它用500个Token就把我们团队之前一周才梳理清楚的模块关系画了出来。这才是Codex的最大价值:不是替代你写代码,而是帮你理解旧代码,它能把一团乱麻变成可读的‘活文档’。

这个能力在重构初期至关重要:没有理解,任何重写都是盲目的。之后每次修改代码前,我都会让Codex先生成对应模块的‘影响范围报告’,然后手动决策改哪、怎么改。重构周期从预估的3个月降到了6周,而其中80%的时间省在了‘理解旧代码’这一步上。

2. 用Codex重构时最容易踩什么坑?为什么我花了27亿Token却毫无进展?

我看到有人分享‘烧了27亿Token才明白Codex技能不能过度设计’,我当时也犯过类似错误,给Codex配置了十几个特别详细的自定义技能,结果每次调用都卡得要命,生成的代码反而更差了。到底哪些坑是新手上路最容易掉进去的?

我踩过的坑有3个,每个都是用真金白银(Token开销)换来的:第一,过度设计自定义技能。我一开始给Codex配了20多个带正则和上下文限制的‘技能’,结果每次交互它要先加载所有技能,响应时间从3秒涨到30秒,生成的代码还频繁混用技能规则,出现自相矛盾。

后来砍到只剩3个基础技能(代码分析、模式提取、单元测试生成),性能立刻恢复正常。第二,提示词太模糊。比如‘重构这个模块’,Codex会跑偏。正确做法是:先给一个具体代码片段(200行以内),然后说‘请把这个if-else链替换为策略模式,保持相同的接口签名’。第三,没有建立反馈闭环。

让Codex修改代码后,我没有让它自动运行测试用例,结果它改完了,测试全崩。后来我们搭建了一个‘CI修复Loop’:Codex先提交修改建议,Jenkins触发测试套件,测试失败则自动回滚并通知人类审核。这个闭环让错误率从70%降到了15%。

如果你想开始,请记住:技能少而精,提示具体到代码级,测试先行且必须自动回滚。

3. 怎么让Codex安全地修改遗留系统代码,而不搞崩生产环境?

我试过直接让Codex给我的老项目改一个bug,它确实改了那个bug,但顺带改了旁边10处我没授权的代码,上线后API响应全乱了。有没有一套流程,能让Codex‘只改我指定的部分’,并且万一改坏了能一键恢复?

我的做法分四步:第一步,建立干净的Git基线。在引入Codex前,确保当前分支的所有未提交更改已stash或commit,并打上标签(如‘baseline-before-refactor’)。这样任何修改都可以通过git diff快速对比,回滚只需reset。第二步,定义修改边界。

我用一个注解(@Modifiable)标记允许Codex修改的函数,其余函数在提示词中明确禁止触碰。例如提示:‘只修改标记了@Modifiable的函数foo(),其余任何代码都不允许改动,包括注释和空白符。’第三步,生成修改前先让Codex生成‘影响分析报告’。

我要求它回答:这个修改会影响到哪些外部调用?会改变哪些API返回值吗?如果影响范围超出预期,就驳回。第四步,强制Codex生成对应的单元测试。修改完代码后,必须给出至少3个测试用例,覆盖正常、边界和异常情况,并在本地或者CI环境通过全部原有测试后才能合入主分支。

这套流程执行一年,我们重构了大约8万行代码,没有一次导致线上故障。唯一的副作用是前期准备时间增加,但相比后期修复bug的成本,完全值得。

4. 用Codex重构遗留系统,实际能提升多少效率?网上说的‘从3-6个月压缩到4周’可信吗?

我经常看到文章标题说‘压缩到4周’,但自己试了一个中小型项目(约5万行PHP),从规划到上线花了2个月,而且还出了几次小故障。那个‘4周’的案例是不是特别理想化?你们真实的效能在什么水平?

说实话,‘4周重构10万行Java项目’这个数据我持保留态度。根据我的经验(重构过一个6万行的内部管理系统),效率提升是真实存在的,但需要分阶段衡量:第一阶段是代码理解,原先团队3人纯手工梳理架构花了2周,现在用Codex配合我们自己的‘模块依赖图生成器’,2天就能生成初版文档,效率提升约85%。

第二阶段是具体编码,这里效率提升有限,Codex生成的代码约30%需要手动调整(比如处理边界条件、集成遗留的安全认证),而且消耗大量Token。第三阶段是测试和部署,Codex生成的单元测试覆盖率能达到70%,但需要人工补充关键路径测试和冒烟测试,整体上测试阶段节省了约40%的时间。

汇总下来,一个6万行项目,原先估算4人月(实际6人月),现在3人2个月完成,而不是网传的‘4周’。后续我们又做了一次2万行模块的重构,因为架构更清晰,确实在4周内完成。但前提是:团队有成熟的测试和CI流程,Codex只负责辅助而非主导。所以那个‘4周神话’可能只适用于简单模块或Demo级项目。

对于真实的遗留系统,建议按1:3备好Buffer,如果你预计Codex帮你省下1个月,就需要多留3个月处理意外。

核心关键词

读者评论

韩知行

看到“技能肥胖症”那段直接破防了。我们团队前两个月也在 Codex 上塞了十几个自定义规则,结果生成质量暴跌,排查半天才发现规则互相打架。确实,给 AI 瘦身之后反而更稳,少即是多这条在 AI 上更残酷。

顾清

最佩服的不是效果清单,而是敢把翻车现场写得这么赤裸。大部分复盘只秀肌肉,这篇把差点丢饭碗的 P0 事故和 17 个技能翻车的代价都摊开了,这种诚实才是读者最需要的。

林晨

先读懂代码,再谈重构”这个思路价值千金。以前都执着于让它生成代码,忽略了 Codex 当考古学家的能力。用非技术语言描述函数那一招,新人上手时间三周变四天,比任何重构都实在。

叶宁

文章里那次三小时定位陈年 bug 的例子太有共鸣了。硬编码的渠道兼容逻辑藏了三年,没有文档,人肉根本不可能快速锁定。AI 不做决策,但能把人带到问题门口,这就是遗留系统里最高效的分工。

文章版权归“万象方舟”www.vientianeark.cn所有。发布者:程, 沐沐,转载请注明出处:https://www.vientianeark.cn/p/596542/

温馨提示:文章由AI大模型生成,如有侵权,联系 mumuerchuan@gmail.com 删除。
(0)
上一篇 1小时前
下一篇 1小时前

相关推荐

  • codex从零到一:自动生成API文档

    你会踩进一个非常经典的坑:当你终于写出一个干净的函数签名,测试用例全绿,代码刚刚合并进主干分支,前端同事却在群里敲了一句,“这接口返回的 data.rule_id 是规则ID还是权限ID?文档里写得不清楚。” 你愣了一下,打开所谓的API文档,发现那行描述是三周前写的,现在早就过期了。文档不是没写,是跟不上代码进化的速度。这就是 API 文档永久性不同步困境的真实切片。 如果此时有人告诉你:“用 …

    1小时前
    300
  • codex的真实搭法:一个Python项目复盘

    大概是在项目进度过半的某个周三,我关掉了自己写了三周的代码库,决定全部推倒,用 Codex 重来一遍。团队觉得我疯了,但我知道,继续在原方案上修修补补,成本只会更高。这不是一拍脑袋的决定,而是那个旧的 Python 报表服务,耦合得太深了,每次加数据源都要改三四个地方,测试跑一次要四十分钟。我需要的不是更多的功能代码,而是一个架构更干净、更容易维护的新版本。 我用 Codex 搭这个项目的过程,更…

    1小时前
    200
  • 我们如何用codex将开发效率翻倍

    去年秋天,我们团队接手了一个电商后台的重构项目,排期六周。技术负责人老张在启动会上说了一句话:这次我们先不改代码,先改协作方式。他说的协作对象不是产品经理,不是测试,而是 Codex。 六周后,项目提前四天上线,bug 数量比预期少了近一半。我后来复盘,发现效率提升最明显的环节,不是写代码变快了,而是我们不再反复修补同一个问题。 这就是今天我想跟你聊的核心结论:用 Codex 把开发效率翻倍,真正…

    1小时前
    100
  • codex避坑:别让它生成测试代码

    你被 Codex 的“温柔”骗了吗? 程序员 A 把键盘往前一推,盯着屏幕上那几百行新生成的代码,脑子嗡嗡作响。他给 Codex 下的指令很明确:“优化支付模块的核心逻辑,解决并发扣减库存的问题。”Codex 辛勤运转了两分钟,吐出一个文件。不是修复后的核心业务代码,而是一份堪称完美的单元测试文件,覆盖率接近 100%,Mock 数据滴水不漏,断言写得像教科书。至于那个让用户半夜打投诉电话的库存超…

    1小时前
    100
  • 一个非程序员用codex写脚本的真实记录

    周一早上九点半,我对着屏幕上47个Excel文件发呆。运营周报里需要把这47个分公司的销售数据汇总到一个母表里,打开、复制、粘贴、关掉,再打开下一个。这套流程我做了三个月,每周雷打不动,耗掉我整整一上午。 那天我破防了。不是因为累,是因为无聊。我坐在工位上,突然冒出一个念头:听说现在AI能写代码了,我能让它帮我干这个吗? 我不会写代码。我大学学的是市场营销,职业生涯里离代码最近的一次,是十年前在网…

    1小时前
    200
站长微信
站长微信
分享本页
返回顶部