官方代码现代化案例中文拆解:为什么不能一条 prompt 全量重写
结合 Exec Plans 与 Code modernization Cookbook,学习先建立系统证据,再分阶段迁移并保持可运行。
先知道终点
- 做完你会得到
- 为一个练习代码库编写能被下一位 agent 接手的 ExecPlan
- 开始前只需要
- 完成 Plan/Goal、权限、AGENTS.md 与 Review 章节;准备一个只读分析的旧项目或虚构练习仓库
- 最后留下这些证据
- 系统概览、约束与验证基线;分阶段里程碑、决策日志与回退;另一位读者可以只靠 ExecPlan 继续工作
内容校准于 2026-07-31 · 第 17 / 38 节已发布课程
跟着材料做,不只阅读
本节练习资料
全量重写最迷人的时刻,是第一分钟
老系统终于要现代化了。一条 prompt 发出去,几千行代码迅速变动。进度看起来惊人,直到第一个旧接口调用失败,团队才发现没有人记录原来的行为。
大改动带来的速度感,很容易掩盖验证债务。
现代化真正的加速器,是每一步都保持系统可运行。 这节课不崇拜改动规模。我们沿着官方案例建立基线、切迁移片段、做行为对照,并为每个阶段保留退路。
官方案例的核心不是“Codex 能改很多代码”
OpenAI Cookbook 的 Code modernization 案例把现代化描述为一项研究、设计、实施与验证相连的工程,而不是把“升级技术栈”交给一个长 prompt。ExecPlan 是持续更新的工作文件:它保存目标、系统现状、约束、里程碑、决策、验证和恢复,让任务跨会话仍能继续。
这类文章属于方法案例,不保证你的仓库会得到同样速度或结果。可迁移的是工作结构,不是示例数字、模型名或特定技术版本。
为什么全量重写容易失败
“把项目从旧框架升级到最新版本”隐藏了大量决策:
- 现有系统的真实入口和用户行为是什么;
- 哪些依赖、API 和数据必须兼容;
- 当前测试是否足以定义“保持不变”;
- 能否分阶段上线;
- 新旧版本如何共存;
- 哪一步不可逆;
- 谁批准公开接口和数据变化。
如果没有这些答案,agent只能用常见模式补空白。代码可能编译,但真实行为、运营流程或回退能力已经丢失。
ExecPlan 的七个部分
1. Purpose 与用户结果
说明为什么做、谁受影响、最终能观察到什么。不要只写“降低技术债”。
2. Current system map
列出入口、模块、数据流、外部依赖、部署与测试。每条结论引用真实文件或命令,不凭目录名猜架构。
3. Constraints 与不变量
公共 API、数据格式、兼容环境、性能或视觉行为,以及禁止的外部动作。
4. Baseline
迁移前运行并记录测试、构建、关键行为、性能或数据基线。已有失败必须单列,不能把旧红灯算作新回归,也不能假装全绿。
5. Milestones
每个里程碑留下可运行、可验证状态。例如先建立适配层,再迁移一个垂直切片,然后扩大覆盖;不要按“改完所有文件”划阶段。
6. Decision log
记录做了什么选择、依据、备选与影响。长任务的价值不只在代码,关键决策必须可恢复。
7. Verification 与 rollback
每阶段的机械检查、人工行为验证、回退入口、数据兼容和停止条件。
一个可执行里程碑示例
Milestone 2:迁移只读查询路径
Outcome
- 新实现处理 /api/catalog 查询,响应 schema 不变。
- 写入路径仍走旧实现。
Changes
- 新增 adapter 与类型;
- 只切换 catalog route;
- 不删除旧模块。
Verification
- 旧 fixture 与新响应逐字段一致;
- 单元、集成和构建通过;
- 生产样本只读回放无差异。
Rollback
- 恢复 route binding 即可;
- 无数据 migration;
- 旧模块仍可运行。
Stop if
- 发现未文档化字段被外部消费者使用;
- fixture 与真实样本口径冲突。
它比“完成第二阶段迁移”更长,但下一位 agent 能据此继续或停止。
先补观测,再改实现
旧项目常见问题是测试不足。现代化第一阶段可能不是升级依赖,而是:
- 建立可启动开发环境;
- 捕获代表性输入输出 fixture;
- 为关键路径添加 characterization tests;
- 记录当前已知失败;
- 补一张系统与数据流地图。
这些工作看似没有“新功能”,却把隐性行为变成迁移合同。没有合同,验证只能依赖“页面大致能开”。
用 Codex 维护而不是代替 ExecPlan
每个里程碑后让 Codex更新:
- 实际完成与原计划差异;
- 新发现的系统事实;
- 运行过的检查与结果;
- 决策及理由;
- 下一步与阻塞;
- 当前 Git/worktree 状态。
然后人工审查计划是否与代码一致。ExecPlan 不能变成自动生成但无人阅读的日志。
练习
选择一个练习项目,只做只读研究和计划,不进行真实大迁移。使用模板完成:
- 通过文件和命令建立系统地图;
- 找出三个最大未知;
- 定义一个可独立交付的垂直切片;
- 为它写 baseline、verification、rollback;
- 让另一位读者指出仍需决定的事项。
评分重点不是篇幅,而是证据、可执行性和恢复能力。
完整案例:现代化旧认证模块,而不是一次重写
旧系统把 token 解析、session 查询、权限判断和 HTTP 响应混在一个模块。目标不是“换成现代写法”,而是让职责可测试、公共行为稳定、迁移可回退。
先建立行为清单
在改结构前记录:
- 有效、过期和格式错误 token 的返回;
- 用户被禁用或权限不足时的状态码;
- session 缓存和数据库失败时的行为;
- 公共函数、错误类型和日志字段;
- 当前测试没覆盖的高风险路径。
现代化成功的第一证据是“旧行为被说清楚”,不是新目录出现。
用里程碑替代文件批次
里程碑 1:补 characterization tests,冻结当前外部行为
里程碑 2:提取纯 token parser,不改变调用方
里程碑 3:提取 session loader,保留旧 facade
里程碑 4:把权限判断迁到 policy 层
里程碑 5:切换调用方,保留可回退开关
里程碑 6:删除旧实现并更新文档
每个里程碑都能独立测试和回退。“先搬所有文件,最后统一修测试”会让失败范围失控。
Decision log 应记录什么
记录有多个合理选项、会影响后续里程碑的选择:
决定:保留旧 AuthError 公共类型直到调用方全部迁移
原因:三个服务依赖其 code 字段
替代方案:立即引入新错误层级
未选原因:会把结构迁移扩大成跨服务 API 变更
验证:契约测试比较旧 facade 与新实现
回看条件:全部调用方迁移后
不需要记录每次变量改名。Decision log 服务恢复和评审。
先补观测,再比较新旧
若系统缺少错误分类和关键指标,重构后即使测试通过,也难判断生产行为是否改变。先增加不改变业务的观测:错误 code、路径计数、兼容 fallback 命中。上线时比较基线,再决定是否扩大流量。
ExecPlan 要随着证据更新
计划不是开工前写完就冻结。每个里程碑结束后更新进展、意外发现、决定和下一步验证。例如 characterization test 发现旧系统本身在缓存失败时返回 500,就要明确这是要保留的兼容行为,还是本次获批修复的缺陷。没有记录的“顺手修复”会让现代化边界失去意义。
最终移除旧路径前,再从一台或一个干净环境执行安装、启动、关键业务路径和回退演练。只在开发者已有缓存的机器上成功,不能证明现代化结果可交接。
故障诊所
| 现象 | 根因 | 恢复 |
|---|---|---|
| 新旧测试都绿,但调用方失败 | 只测内部实现 | 增加公共契约和端到端路径 |
| 迁移进行一半无法继续 | 没有 facade 或回退边界 | 恢复兼容层,把下一步缩小 |
| 每个里程碑都改同一批文件 | 拆分按文件而非能力 | 按可观察行为重新切里程碑 |
| 长任务忘记早期决定 | 决策只在聊天 | 更新 ExecPlan 和 decision log |
知识检查
如果新框架能减少一半代码,是否足以支持全量重写?不足。还要证明外部行为、迁移顺序、验证、观测和回退;代码量只是一个局部指标。
切出第一块能独立证明的迁移
不要从「重写整个系统」开始。选一个边界清楚、已有行为证据、失败可回退的模块,写下迁移前后必须一致的观察结果。
第一块稳定以后再切下一块。系统始终能跑,现代化才不是一场只能前进的豪赌。
完成检查
- 计划以用户结果而非“升级”开头
- 系统地图来自真实文件与命令
- 基线区分旧失败和新回归
- 每个里程碑留下可运行状态
- 决策、验证与回退持续更新
- 案例方法没有被写成通用性能承诺
参考与校准来源
本文是官方资料的中文转译与教学重组,不是逐字翻译;产品能力、命令、默认值与安全边界以下列官方原文为准。