banner
NEWS LETTER

AI 变更验证流程:从生成代码到可交付结果

Scroll down

AI 工具已经能很快完成代码生成、文档整理、脚本编写和问题排查,但真正影响交付质量的,往往不是“能不能生成”,而是“生成之后怎么验证”。如果缺少验证闭环,AI 写出的内容看起来完整,实际可能改错边界、漏掉失败路径,或者让构建在最后一步才暴露问题。

更稳的做法,是把 AI 产出当成一次普通工程变更处理:先确认改动范围,再建立验证清单,然后用构建、测试、人工审查和回滚预案把结果闭环。这样 AI 负责提高产出速度,人负责控制风险。

一、先把变更范围说清楚

验证的第一步不是运行命令,而是确认这次到底改了什么。范围不清楚时,后面的测试很容易变成“跑了一些命令”,但无法证明关键行为没有被破坏。

一次 AI 辅助变更至少应该回答几个问题:

  • 修改了哪些文件。
  • 影响的是功能逻辑、配置、文档还是构建流程。
  • 是否改变外部接口、数据格式或用户可见行为。
  • 是否涉及异步、缓存、权限、生命周期或资源释放。
  • 哪些部分明确不在本次范围内。

例如让 AI 修复 Android 页面 loading 状态时,范围不应该只写“修复保存问题”,而应该更具体:

1
2
3
范围:SettingsViewModel 的保存状态机,以及对应单元测试。
不改:接口协议、Repository 公共方法签名、页面布局。
预期:成功和失败都会退出 loading,重复点击不会产生并发提交。

范围越清楚,验证越容易对齐真实风险。

二、不要只相信 diff 看起来合理

AI 生成的 diff 常常很顺眼:命名整齐、结构完整、注释也像那么回事。但代码是否合理,不能只看形式。

需要重点检查的是行为变化:

  • 默认值是否改变。
  • 空值和异常路径是否仍然可见。
  • 同步逻辑改成异步后,调用顺序是否变化。
  • 缓存、排序、分页或重试策略是否改变。
  • 日志、埋点、错误码是否仍然满足排查需求。

比如下面这种修改看起来是在简化错误处理:

1
return runCatching { api.save(request) }.getOrNull()

如果调用方原本依赖异常类型来区分超时、未登录和服务端错误,这个改动就不是简单简化,而是隐藏了失败原因。验证时必须回到调用方,看它到底需要什么语义。

三、把验证清单写在修改前

很多问题出在修改完成后才想验证。更好的方式是让验证清单先于代码存在。

可以按四类路径组织:

  • 正常路径:常见输入能得到预期结果。
  • 失败路径:网络失败、磁盘失败、权限失败、解析失败时行为正确。
  • 边界路径:空列表、空字符串、最大值、重复点击、页面销毁等情况稳定。
  • 回归路径:历史问题不会再次出现,已有接口行为不被破坏。

示例:

1
2
3
4
5
6
验证清单:
1. 保存成功后 loading=false,并显示最新配置。
2. 请求超时后 loading=false,并显示错误提示。
3. 连续点击保存只触发一次提交。
4. 页面销毁后返回结果不会更新已释放的 View。
5. 旧的配置读取逻辑保持兼容。

这份清单可以直接交给 AI 生成测试,也可以作为人工验收标准。关键是它把“看起来能跑”变成了“哪些路径必须正确”。

四、构建验证只能证明一部分

构建通过很重要,但它只能证明语法、依赖和静态资源等基础问题没有阻塞。它不能证明业务行为正确,也不能证明边界路径安全。

不同项目常见验证命令可能是:

1
2
3
4
5
npm run build
./gradlew testDebugUnitTest
./gradlew assembleDebug
cmake --build build
pytest

这些命令应该放进任务描述里,而不是最后临时想起来。AI 在知道验证命令后,会更倾向于生成可编译、可测试、符合项目结构的内容。

但也要清楚构建验证的边界:

  • Hexo 构建通过,不代表文章观点准确。
  • Android 编译通过,不代表生命周期处理正确。
  • 单元测试通过,不代表真实设备弱网场景没问题。
  • 后端测试通过,不代表部署配置和线上权限无误。

构建是底线,不是完整验收。

五、让 AI 帮忙补测试,但不要放弃审查测试

AI 很适合根据验证清单生成测试用例,尤其是重复性强的边界输入和状态转换。但测试代码本身也需要审查。

重点看几件事:

  • 测试是否真的覆盖了新行为。
  • 断言是否足够具体。
  • mock 是否把关键风险隐藏掉了。
  • 测试名称是否表达了业务场景。
  • 是否只验证了实现细节,而没有验证外部可见结果。

例如一个保存失败测试,下面这种断言价值有限:

1
assertNotNull(result)

更好的断言应该直接检查用户可见状态:

1
2
assertFalse(viewModel.uiState.value.loading)
assertEquals("保存失败", viewModel.uiState.value.errorMessage)

测试不是为了增加数量,而是为了证明关键路径真的被固定住。

六、人工审查要聚焦风险

AI 生成内容后,人不需要逐字怀疑每一行,但要对高风险点保持敏感。

比较实用的审查顺序是:

  1. 先看文件范围是否越界。
  2. 再看外部接口和数据格式是否变化。
  3. 然后看失败路径和边界路径。
  4. 最后看命名、结构和可维护性。

不要把审查精力优先花在格式偏好上。真正值得拦截的是这些问题:

  • 为了修一个 bug 重写了整个模块。
  • 引入新依赖但没有必要。
  • 吞掉异常或改掉错误语义。
  • 修改了公共方法签名却没有同步调用方。
  • 删除了看似无用但实际用于兼容旧数据的逻辑。

AI 的产出速度越快,人工审查越要抓住风险层级,否则很容易在大量细节里失去重点。

七、保留可回滚路径

可交付的变更不只要能上线,也要能撤回。尤其是 AI 辅助生成的改动,如果 diff 较大,更应该提前考虑回滚。

可以从几个角度控制回滚成本:

  • 单次变更保持小范围。
  • 不把无关重构和功能修改混在一起。
  • 配置变更和代码变更分开提交。
  • 数据迁移要有兼容读取或降级策略。
  • 发布说明里写清楚验证结果和已知风险。

如果一个变更无法简单回滚,那就需要更强的验证和更谨慎的发布节奏。AI 可以帮忙写代码,但不能替代发布风险判断。

八、一个可复用流程

日常使用 AI 完成开发任务时,可以按这个流程走:

1
2
3
4
5
6
7
1. 描述目标、范围和禁止事项。
2. 让 AI 阅读相关代码并总结现有模式。
3. 在修改前列出验证清单。
4. 执行最小必要修改。
5. 运行构建、测试或静态检查。
6. 人工审查行为变化和风险点。
7. 记录验证结果、残留风险和回滚方式。

对应提示可以写成:

1
2
3
4
请完成这个变更,但先不要直接修改。
先阅读相关文件,总结影响范围,并列出验证清单。
修改时只改必要文件。
完成后运行指定验证命令,并说明哪些路径已经验证、哪些风险仍需人工确认。

这段提示的目的,是把 AI 从“生成答案”拉回“交付变更”的流程里。

九、总结

AI 辅助开发真正需要建立的习惯,不是每次都写更复杂的提示词,而是让每次变更都能被验证、审查和回滚。

一个可靠的 AI 变更闭环,通常包含四件事:

  • 范围清楚,知道改了什么,也知道没改什么。
  • 验证前置,先定义成功标准,再写代码。
  • 构建和测试落地,不只依赖肉眼判断。
  • 人工审查聚焦风险,保留回滚路径。

当这套流程稳定下来,AI 工具的价值会更接近工程提效,而不是单纯的代码生成。产出速度变快的同时,交付质量也能保持在可控范围内。

其他文章
目录导航 置顶
  1. 1. 一、先把变更范围说清楚
  2. 2. 二、不要只相信 diff 看起来合理
  3. 3. 三、把验证清单写在修改前
  4. 4. 四、构建验证只能证明一部分
  5. 5. 五、让 AI 帮忙补测试,但不要放弃审查测试
  6. 6. 六、人工审查要聚焦风险
  7. 7. 七、保留可回滚路径
  8. 8. 八、一个可复用流程
  9. 9. 九、总结
请输入关键词进行搜索