上一篇我把“任务完成”拆成了五类证据:行为、数据、修改范围、自动检查和页面体验。
一旦真的按这些证据验收,多文件一次性修改的问题就会变得很明显。
Codex 也许几分钟就能同时修改页面、子组件、接口、类型、状态和测试。站在代码生成阶段看,这当然很快。
但我接下来要面对的是一整块差异:
哪个文件先发生了行为变化?
接口和页面的约定是否同时改变?
状态错误是从页面引入的,还是从公共组件传下来的?
某个测试失败对应哪一步判断?
页面正常,是因为每一层都正确,还是几个错误刚好抵消?
改动越集中,写代码的等待时间越短;改动越混合,理解和验收的成本越高。
所以我现在衡量 AI 修改速度,不只看“多久输出代码”,还看“多久能拿到可信的完成证据”。
一次性修改的问题,不在文件数量本身
标题里写“8 个文件”,只是为了说明一个常见场景。
真正决定风险的不是数字,而是这些文件是否同时改变了不同性质的行为。
例如下面两种修改都涉及 8 个文件:
情况 A:机械性改名
一个类型名称修改。
8 个引用文件同步更新。
行为不变。
类型检查可以直接验证遗漏。
情况 B:新增列表编辑功能
页面增加入口。
弹窗增加表单。
接口增加保存方法。
类型增加字段。
状态增加 Loading。
权限增加判断。
列表增加刷新逻辑。
测试增加新路径。
两者文件数相同,风险完全不同。
情况 A 的改动规则单一、验证方式统一,批量完成通常合理。
情况 B 同时改变用户入口、表单状态、接口契约、异步流程、权限和刷新行为。只要其中一个判断错了,错误就可能跨文件传播。
所以我判断要不要小步修改,主要看三件事:
是否只有一种行为变化。
是否能用同一组证据验证。
某一部分失败时,能否快速定位和回退。
只要答案不够明确,我就不会因为文件少而强行一次改完。
一次性生成,省下的是输出等待,不一定是交付时间
AI 编程最容易制造一种速度错觉:
代码已经全部出现,所以任务已经接近完成。
其实从输出到交付,中间还有很长一段:
阅读差异 → 运行检查 → 定位问题 → 修正 → 页面验证 → 回归
如果一次生成的差异同时包含多个状态和多个行为,后半段的成本可能迅速增加。
我会区分两种时间。
生成时间
从下达任务到代码被修改的时间。
可信交付时间
从任务开始到所有关键行为有证据、剩余风险被说明的时间。
一次性修改通常能压缩前者,却不一定能压缩后者。
小步修改看起来多了几次停顿,但每次停顿都在提前消除错误假设。它减少的不是打字时间,而是问题在多文件中扩散后的排查时间。
第一种成本:错误假设会沿依赖链扩散
假设要给订单列表增加编辑功能,需求没有明确“详情数据来自当前行还是单独请求”。
如果 Codex 选择直接使用当前行数据,并一次完成所有文件:
弹窗 Props 按列表行类型设计。
表单初始值从行数据复制。
接口类型只包含列表字段。
测试也基于列表行构造数据。
保存逻辑默认列表数据完整。
后来才发现,有两个可编辑字段只在详情接口返回。
这时要改的已经不只是一个取数方法:
弹窗初始化方式要变。
Loading 边界要变。
类型要变。
测试数据要变。
打开和关闭时的异步状态要重新处理。
最早只错了一个业务假设,最后却形成一组互相配合的错误实现。
如果先完成“确认弹窗数据来源和初始化流程”,这个问题会在真正写表单前暴露。
小步修改最直接的价值,就是让高风险假设在依赖它的代码出现之前得到验证。
第二种成本:大差异会失去因果关系
代码审查不是逐行看语法,而是判断:
这处变化为什么必要,它与哪一个需求结果对应?
当一批差异同时包含:
新增字段。
重构方法。
调整命名。
替换组件。
修改样式。
增加异常处理。
更新测试。
每一行代码和需求之间的对应关系就会变弱。
有些无关修改可能被“藏”在正确功能旁边;有些真正必要的变化,又可能被误认为顺手重构。
我会把这种情况称为“差异噪声”。
差异噪声越高,审查者越难回答:
哪一处是目标行为。
哪一处是为了兼容。
哪一处只是格式化。
哪一处改变了公共行为。
哪一处可以撤掉。
小步修改并不会自动让代码更好,但它能让每一批差异有一个更清楚的解释。
第三种成本:检查放到最后,问题发现得太晚
一次性修改经常采用这种顺序:
全部代码写完 → 类型检查 → 测试 → 构建 → 页面验证
如果最终类型检查失败,我们要在所有改动中定位类型边界;如果页面验证失败,还要继续判断是状态、接口、组件还是样式问题。
我更倾向于把检查放进过程:
调整类型或接口契约后,先运行相关静态检查。
建立状态和参数转换后,先验证数据流。
接入页面交互后,再验证用户路径。
最后做联合回归和完整差异审查。
同一个检查,执行得越早,定位范围越小。
OpenAI 当前的 Codex 迭代用例也强调:复杂任务应先定义评估方式,每次只做一个聚焦改动,在有意义的修改后重新执行检查,并记录变化和结果。
这个方法不只适合需要多轮优化的大任务。前端多文件修改同样需要“改一层、证一层”,而不是把所有证据压到最后。
第四种成本:失败时很难判断应该修哪里
一次性生成后出现问题,常见处理是继续让 AI 修:
页面现在报错,请检查并修复。
如果前一批改动很大,Codex 会再次面对多个可能根因。它也许修复表面错误,却继续在原来的错误假设上补丁。
例如编辑弹窗打开后字段为空,根因可能是:
列表行没有该字段。
详情请求没有执行。
响应转换漏了字段。
表单初始化早于请求返回。
关闭后旧请求覆盖了新状态。
字段名与接口类型不一致。
当每一层都在同一批变化中,排查需要重新建立因果链。
如果每一步都已经验证,失败范围会小很多:
数据契约已验证。
详情请求参数已验证。
响应转换已验证。
当前只剩弹窗回填阶段。
修复成本的差异,不是 AI 能不能找出问题,而是它需要在多大的搜索空间里找。
第五种成本:纠偏可能变成二次重写
大批修改的另一个问题,是错误方向内部可能已经高度一致。
类型、状态、组件和测试都围绕同一个错误设计配合得很好。此时局部修改反而很难,正确纠偏可能需要重新组织整条链路。
这也是为什么“测试通过”不能单独证明方向正确。
如果测试本身和实现基于同一个错误假设,它们可以一起通过。
人的验收必须回到需求和用户行为:
数据来源是否符合真实业务。
公共责任是否放在正确层。
失败恢复是否符合产品决定。
原有行为是否保持。
小步修改把这些判断分散在过程中,避免最后才发现整套实现建立在错误基础上。
小步修改不等于一个文件一个任务
我不赞成机械地按文件停顿。
前端中的一个行为经常天然跨多个文件:
接口类型。
请求方法。
页面状态。
组件展示。
测试。
如果它们共同完成一个不可分割的结果,并且可以用同一组证据验证,就可以放在一批。
例如“状态筛选能够正确进入列表请求”可能同时修改:
查询条件类型。
页面筛选状态。
参数转换。
相关测试。
虽然涉及多个文件,但只有一个行为目标:
页面选择的状态与发送的请求参数一致。
这一批可以用明确证据验收:
页面状态正确。
请求参数正确。
类型检查通过。
相关测试通过。
相比之下,“新增筛选,同时重构公共请求层”即使只改两个文件,也应该拆开,因为它包含两个不同风险和两套验证方式。
所以小步的单位不是文件,而是“可验证的行为增量”。
我用四个问题决定一批改多大
1. 这一批能否用一句话描述结果
例如:
编辑弹窗能够从详情接口取得完整数据,并在请求期间显示局部 Loading。
如果一句话里出现两个独立结果,就考虑继续拆。
2. 这一批是否只有一个主要未知
当前最需要验证的是数据来源、状态归属、组件契约,还是页面交互?
一批改动同时赌多个未知,失败后就很难归因。
3. 这一批是否有就地证据
完成后能不能立刻运行检查、看请求、走页面路径或审查差异?
必须等所有功能都完成才能验证的批次,通常还不够独立。
4. 方向错了是否容易撤回
如果错误会迫使后续所有步骤重写,应该把它提到更早单独验证。
例如公共组件 API、数据模型、状态唯一来源,通常比局部样式更值得先确认。
用一个多文件前端任务对比两种执行方式
下面是演示场景,不代表真实项目:
在用户列表中增加编辑弹窗,从详情接口回填数据,保存成功后刷新当前列表,失败后保留用户输入。
一次性执行
同时修改: - 用户列表页面 - 编辑弹窗 - 用户接口 - 用户类型 - 表单校验 - Loading 状态 - 列表刷新逻辑 - 相关测试 最后统一运行检查和页面验证。
小步执行
步骤 1:确认详情数据契约 - 只建立详情接口、类型和转换 - 验证参数、响应结构和类型检查 步骤 2:建立弹窗初始化 - 打开时请求详情并回填 - 验证 Loading、关闭和重新打开 步骤 3:建立提交闭环 - 校验、提交、防重复和失败恢复 - 验证成功与失败路径 步骤 4:接入列表刷新 - 保存成功后刷新当前列表 - 验证搜索条件和页码是否保留 步骤 5:联合回归 - 审查完整差异 - 运行项目检查 - 走新增、编辑、失败和连续操作路径
两种方式最终可能修改同样多的文件。
差别在于第二种方式把关键假设、状态和证据分开了。问题在每一步都有机会暴露,不需要等到最后一起排查。
哪些情况可以放心合并
小步修改不是越碎越好。下面几种情况可以适当批量:
规则完全机械,例如确定范围内的统一改名。
有可靠的类型检查或测试覆盖所有引用。
不改变运行行为,只更新同步的类型或文档。
多个文件共同构成一个不可分割的单一行为。
失败时可以通过自动检查快速定位。
即使批量,也要先确认目标范围,完成后审查差异,防止替换到不该改的位置。
哪些信号说明必须停下来
出现这些情况时,我不会让 Codex 继续沿计划一路改完:
发现需求与现有行为冲突。
必须改变公共组件或公共 API。
找到新的主要调用方。
参考页面之间的模式不一致。
项目关键检查无法运行。
前一步的证据没有通过。
修改范围明显超过原计划。
停下来不是任务失败,而是计划中的风险控制点。
如果前一步尚未证明正确,继续往后写只是在增加建立在未知上的代码。
真正快的不是一次改完,而是每次都知道自己改对了什么
AI 把代码生成速度提高以后,开发流程中最稀缺的东西变了。
过去可能是实现时间;现在更容易成为判断、审查和验证时间。
一次性修改把实现压缩到很短,却把大量判断留到最后。小步修改则把验证插进过程,让错误在影响范围还小时暴露。
我看重的不是每一步都“慢慢来”,而是每一批改动都具备:
单一目标。
清楚边界。
可执行检查。
可解释差异。
可控的纠偏成本。
下一篇我会继续解决执行层的问题:一个多文件前端任务,计划到底应该怎样写,才能真正约束 Codex 的修改顺序。我会给出 6 个检查点,以及计划发生变化时必须停下来更新的条件。
本系列持续更新。Day 6 的第二篇会把“小步修改”落实成一份可直接复用的多文件执行计划。
参考资料
OpenAI Codex 用例:一次做一个聚焦改动,并在每轮重新评估
OpenAI Codex 用例:修改前理解依赖、状态变化和风险位置