在很长一段时间里,我们都把系统迁移当成一种“必要但痛苦的事情”。
不是不会做,而是不想做。
一、为什么我们又一次走上了迁移这条路#
事情的起点很普通:
老系统运行多年,依赖版本逐渐老化
新成员上手成本越来越高,涉及多语言、多框架
每一次改动,都要反复确认“会不会影响旧逻辑”,维护成本高
最典型的状态是:系统还能跑,但没人敢大改。
继续堆功能,技术债只会越来越重;推倒重来,又意味着一次不可控的工程风险。
最终我们达成共识:
迁移不是为了追新技术,而是为了让系统重新“可维护”。
二、迁移真正消耗人的地方,从来不是技术难度#
真正开始拆解任务后,我们发现一个很现实的问题:迁移里 80% 的工作,几乎没有技术含量。
包括但不限于:
接口层的批量改写
DTO / Model 的结构调整
错误处理、日志规范的统一
配置文件、命名风格的机械性修改
这些事情的特点非常一致:
规则明确
重复度极高
极其消耗专注力
非常容易出低级错误
而真正需要工程师思考的部分——架构边界、业务语义、数据一致性,反而只占很小一部分。
问题在于:人被大量“脏活累活”拖住了。
三、传统迁移方式,为什么总是效率低#
在使用新的工具之前,我们几乎把能试的方法都试过了:
手写迁移脚本
正则 + 搜索替换
临时小工具拼规则
它们并非没用,但局限非常明显:
只能处理“格式”,很难处理“语义”
一旦规则复杂,维护成本直线上升
跨语言、跨框架时几乎全部失效
迁移做到后期,经常出现一种状态:人不是在写代码,而是在对付代码。
四、我们是如何把 Codex 引入迁移流程的#
我们并不是抱着“让 AI 自动完成迁移”的期待去用 Codex 的。
目标非常明确:让它接管那些规则明确、重复度高、不值得人反复消耗精力的工作。
在实际使用前,我们先做了清晰的边界划分。
适合交给 Codex 的事情#
接口层 / DTO 的批量迁移
代码结构、命名风格的统一
框架层面的固定模式改写
明确规则下的重构工作
接口业务逻辑梳理
坚决不交给 Codex 的事情#
架构设计与拆分决策
性能、安全关键路径
任何“改错一次代价很大”的代码
一句话总结:让它做执行者,而不是决策者。
五、Codex 在迁移中是如何发挥作用的#
典型流程大致是:
提供旧代码
明确目标框架或规范
清晰描述迁移规则
明确哪些部分“禁止改动”
在这种前提下,接口层迁移、结构性重构、重复代码替换,大约有 70%–80% 的结果可以直接使用。
剩下的工作变成了:人工 Review、小范围调整、补充测试。
迁移的工作性质发生了明显变化:从“连续高强度编码”,变成了“规则制定 + 校验”。
六、迁移实战演示(节选)#
老项目和新项目放置同一目录,这样做可以方便 Codex 读取项目代码:
tree -L 1 -d
.
├── each-oms-main:老项目
├── each_hwd:新项目
├── eachfans-main:老项目
└── starsback-manager-master:老项目
撰写一份 README,用于介绍项目、划分 Codex 边界、定义规则,然后与 Codex 进行多轮对话迭代,直至某个功能迁移完成。
七、效率变化,比想象中更明显#
我们没有做特别夸张的数据统计,但体感非常一致:
编码时间显著下降
Review 更聚焦在“逻辑正确性”而不是格式
人的疲劳感明显降低
最重要的一点是:迁移不再让人抗拒。
八、Codex 能做的,其实远不止迁移#
在迁移之外,它同样适合:
代码规范与风格的长期对齐
批量重构与技术债清理
新老系统之间的临时适配层
把工程经验固化成可重复执行的流程
从这个角度看,它更像是工程团队经验的放大器,而不是替代者。
九、当迁移不再痛苦,技术演进才真正开始#
回头看这次迁移,最大的变化并不是“快了多少”,而是心理负担明显降低了。
当迁移不再意味着长期加班、大规模返工、不可控风险,技术团队才真正有勇气去持续演进系统。
最后,用一句很工程师的话来总结:
迁移本身不是问题,让人长期做低价值重复劳动,才是问题。