用 Codex 重构代码:替换旧实现,也要清理旧路径 - AIPlan
让 AI 重构时怎样避免新旧逻辑并存?先写行为约束和调用范围,小步替换重复实现,检查引用、依赖和回归结果。

重构失败最常见的形态不是改坏了,是改出了两套实现。旧函数还在,新函数也能用,调用方一半走旧的一半走新的。判断标准很直接:重构完成后,旧实现应该不存在于仓库里。截至 2026 年 10 月 18 日核对,这套做法在桌面版的审查面板和 CLI 上都能验证。
先写行为约束,再谈结构
重构改的是结构,不是行为。这句话说起来简单,落地要一份可验证的清单。开工前把现有行为列出来:
1. 传入空列表返回空数组,不报错
2. 金额大于 0 时四舍五入到 2 位
3. 优惠券过期返回 409,不是 400
4. 同一订单重复提交幂等,返回同一结果
4 条约束对应 4 个测试。这 4 条测试在重构前后必须都通过,且测试代码不动。测试被改动是重构失控的第一个信号。
如果项目现在没有这些测试,先补测试再重构。补测试的工作量通常是重构本身的 1 到 2 倍,省不掉。
摸清调用方再动手
改一个共享函数之前,先找出所有调用方。Codex 能做这件事,任务描述这样写:
只读任务。找出 formatPrice 函数在整个仓库的所有调用点,
输出文件路径、行号、调用方式,以及每个调用方传入的参数类型。
不要修改任何文件。
在实际项目里,一个看起来只被 3 个地方调用的工具函数,真实调用点常常是 11 个,其中 2 个是通过字符串拼接的间接调用,1 个在测试里用不同的参数签名。
漏掉调用方的代价是运行时报错,而不是编译时报错。Go 这类静态类型语言好一些,编译能拦住一部分;JS 和 Python 就只能靠测试和肉眼。
小步替换,每步可回退
一次改 300 行和分 5 次改 60 行,最终代码可能一样,但出问题时的定位成本差 10 倍。
推荐的节奏:
• 第一步只改函数内部实现,签名不动
• 第二步改签名,所有调用方跟着改
• 第三步删旧函数
• 第四步清理旧函数留下的 import 和类型定义
每一步结束跑一次测试,打一个 Git 检查点。官方快速上手文档就建议在任务前后建检查点,重构场景里这条尤其值得照做。
第 3 步是很多人跳过的一步。旧函数删掉之前,新实现已经在用了,删掉是安全的;不删,三个月后有人看到两个函数,会挑那个“看起来更稳定”的旧版本用。
审查面板能看清动了什么
桌面版里输入 /review,选 Review uncommitted changes,它会按优先级报发现并且不改工作区。切换范围到 Last turn 只看上一轮助手的改动,重构时这个视图最有用。
面板默认显示 Unstaged,也可以切 Staged、Commit、Branch。重构涉及多个文件时,用 Branch 看和基线的整体差异,比逐个文件翻快。
一个必须知道的边界:审查面板反映的是整个 Git 仓库状态,包含你自己手改的部分。重构期间如果还在改别的功能,两批改动会混在一起。干净的做法是重构前 git stash 或者单独开分支。
审查该怎么要求发现格式,可以看 用 Codex 做代码审查:每个发现都要说明怎样触发,那套四行模板在重构场景里同样适用。
死代码怎么判定
删之前先确认三件事:
• 全仓库搜不到引用,包括字符串拼接和配置里的函数名
• 没有外部包依赖它(如果是导出的公共 API)
• 没有被动态加载的路径命中
第三条最容易被漏。一个 plugins/*.py 目录下的模块可能没有任何静态 import,但运行时会被扫描加载。让 Codex 找这类引用,任务里要写明“包括字符串匹配和配置文件”。
删完再搜一次,这次搜的是旧名字。搜不到才算删干净。这个动作花 30 秒,能避免“以为删了其实还有一份”的情况。
依赖和目录也要一起看
重构经常留下这些东西:
• 只被旧实现用的第三方包,还在 package.json 里
• 只为旧实现存在的目录,里面 1 个文件
• 旧的类型定义,没人引用
让 Codex 清理时,任务描述可以点名:“删除旧实现后,检查 package.json 里是否有只被它使用的依赖,列出候选,不要直接删。”列出候选而不是直接删,是因为判断依赖是否可以移除需要看整个项目的运行路径,模型容易误删间接用到的包。
npm install -g @openai/codex 这类全局安装的版本也要跟着更新,Astra 需要 0.153.0 或更新,旧版本上某些模型选项不出现,重构时想对比两个模型的输出就会卡住。
回归检查的 3 个层次
重构后的验证分三层:
层次
检查什么
成本
单元测试
函数级行为是否一致
秒级
集成测试
跨模块调用是否还通
分钟级
手工冒烟
关键流程走一遍
10 分钟
三层都过才算完成。只跑单元测试的风险是:函数行为对了,但调用链上的参数转换错了,单元测试覆盖不到。
手工冒烟清单写 3 到 5 条就够,挑用户最常走的那条路径。比如“登录 → 选商品 → 下单 → 看到订单详情”,4 步走通,主干就没问题。
什么情况不该重构
三种情况建议先放着:
• 这段代码 3 个月内要整个替换掉
• 没有测试覆盖且改动风险高于收益
• 你无法在 1 天内验证改动是否正确
第一条最常见。为一个下季度就废弃的模块做精细重构,投入的时间不会回来。
一次典型的规模和时间
改一个 400 行的工具模块,把 5 个重复函数合并成 1 个,典型的时间分配:
• 补测试:90 分钟
• 找调用方:20 分钟
• 改实现:40 分钟
• 改调用方:30 分钟
• 删旧代码和依赖:15 分钟
• 三层验证:45 分钟
合计 4 小时。其中真正写代码的 70 分钟,其余 170 分钟都在准备和验证。这个比例是正常的,把它当成异常去压缩,压缩掉的通常是测试。
这种规模的重构用量消耗不大,读的文件集中在 1 到 2 个模块。Plus 的 $20 折算约 ¥133.80,一周做 2 到 3 次这种重构够用,¥115.50 的 Plus 月卡 是同样的 Codex 通道。跨 10 个模块的大重构才需要看 Codex 额度不够用时先看任务怎么消耗。
重构完把旧名字再搜一遍,搜不到,这件事才算结束。
参考资料资料核对日期:2026-10-17
• Codex CLI
• Code review
延伸阅读• 用 Codex 做代码审查:每个发现都要说明怎样触发
• 让 Codex 写测试:先问这条测试能发现什么错误
• 给 Codex 下任务怎么写?让目标、边界和验收都可检查