banner
NEWS LETTER

给 AI 设定变更预算:把一次大改拆成可验证的小步

Scroll down

让 AI 修改代码时,真正危险的往往不是它不会写,而是它一次写得太多:顺手整理目录、统一命名、升级依赖,再补上一层“更合理”的抽象。最终 diff 看起来很完整,验证成本却超过了人工重写。

解决办法不是把提示词写得更长,而是给每轮修改设定一个明确的“变更预算”。预算限制本轮可以触碰的文件、行为和验证范围,使 AI 的产出保持在人工能够快速审查、机器能够及时验证的尺度内。

一、变更预算不是行数限制

只要求“修改不超过 50 行”并不可靠。删除一个判断可能只有一行,却会改变整个调用链;批量格式化几百行,反而可能完全不影响行为。

更实用的预算由四部分组成:

  1. 文件预算:允许新增或修改哪些文件,哪些目录禁止触碰。
  2. 行为预算:本轮只改变一个可描述的外部行为。
  3. 依赖预算:是否允许升级版本、引入库或调整构建配置。
  4. 验证预算:改动完成后,必须在多长时间内得到明确结果。

例如,Android 中修复一次空指针,可以这样定义边界:只修改 ViewModel 和对应测试;不改接口模型,不升级依赖;空数据返回时展示空状态;运行目标单元测试必须通过。

这比“修复页面偶发崩溃”更容易执行,也更容易判断任务是否真的结束。

二、先让 AI 交付最小闭环

一次有效的小步修改应包含三个部分:触发问题的输入、针对问题的改动、能够证明结果的验证。缺少其中任何一项,改动都只是一个尚未闭合的猜测。

可以把任务描述成下面的形式:

1
2
3
4
5
目标:修复网络返回空列表时页面一直显示加载中的问题。
范围:只允许修改 UserListViewModel.kt 和对应测试。
约束:不修改公共 API,不增加依赖,不做格式化整理。
验证:先补充一个能复现问题的测试,再实现修复,最后运行该测试。
输出:说明改动文件、验证命令和仍未覆盖的风险。

这里最重要的不是措辞,而是每项约束都能被检查。完成后可以直接用 git diff --stat 看范围,用测试结果看行为,而不必依赖 AI 自己声称“已经解决”。

三、Android 项目按层切分

Android 工程容易出现跨层扩散:界面问题一路改到 ViewModel、Repository、网络模型和 Gradle 配置。面对这类任务,可以先按故障所在的最窄层设置预算。

如果状态转换错误,就先限定在状态持有者及其测试;如果布局在特定尺寸下溢出,就先限定布局资源和截图验证;如果构建失败,再把预算放到对应模块的构建脚本。只有现有证据证明问题跨层,才扩大下一轮范围。

目标测试也应尽量贴近改动模块:

1
2
./gradlew :app:testDebugUnitTest \
--tests '*UserListViewModelTest.empty response shows empty state'

目标测试通过后,再根据风险决定是否运行模块测试或完整构建。这样既保持反馈速度,也不会把“跑了一个大命令”误当成精确验证。

四、Linux 工具修改先固定输入输出

Shell 脚本和系统工具的改动看似局部,却经常依赖环境变量、退出码、权限和文件状态。给 AI 修改前,先把输入输出契约写清楚:

1
2
3
4
5
6
7
8
9
tmp_dir=$(mktemp -d)
trap 'rm -rf "$tmp_dir"' EXIT

printf '%s\n' alpha beta > "$tmp_dir/input.txt"
./bin/process "$tmp_dir/input.txt" > "$tmp_dir/output.txt"
status=$?

test "$status" -eq 0
diff -u tests/expected.txt "$tmp_dir/output.txt"

这段验证不一定要直接用于生产,但它明确了测试数据、退出状态和预期输出。AI 若想顺手改变输出格式,差异会立即暴露,而不是等到下游脚本异常时才发现。

对于会写入系统目录、操作设备或调用网络的脚本,还应默认禁止真实副作用,优先使用临时目录、模拟输入或 dry-run。验证过程本身也属于预算的一部分。

五、每轮结束检查预算是否超支

AI 完成修改后,不要立刻进入下一项需求。先做一次短检查:

1
2
3
git status --short
git diff --stat
git diff --check

然后回答四个问题:

  • 修改是否只发生在允许的文件中?
  • 是否引入了未授权的依赖、配置或公共接口变化?
  • 验证命令是否真的执行,结果是否与目标直接相关?
  • 如果本轮失败,能否只撤销这一步而不影响其他工作?

发现超支时,最稳妥的处理通常不是继续解释,而是缩小任务重新做一轮。一个需要长篇说明才能证明安全的 diff,本身就已经失去了小步修改的价值。

六、什么时候扩大预算

预算不是越小越好。边界过窄也可能迫使代码加入临时补丁,掩盖真正的问题。扩大预算应由证据触发,而不是由“顺便优化”触发。

常见的扩大理由包括:测试证明错误来自下游契约;局部修改会破坏已有公共行为;构建系统无法只验证单个模块。扩大时仍然一次只增加一个维度,例如先增加一个文件,再增加一组测试,而不是同时开放整个仓库。

七、把 AI 从代码生成器变成受控执行者

变更预算的核心,是把一次模糊的“帮我改好”转换成多轮可观察的工程动作。每一轮都有明确边界、可执行验证和独立回滚点,人的审查压力会显著降低,AI 也更少在缺少证据时自行扩展任务。

高效的人机协作并不追求一次生成最多代码,而是追求每一步都能快速回答:改了什么、为什么有效、失败后如何退回。能持续回答这三个问题,小步修改最终反而更快。

其他文章
目录导航 置顶
  1. 1. 一、变更预算不是行数限制
  2. 2. 二、先让 AI 交付最小闭环
  3. 3. 三、Android 项目按层切分
  4. 4. 四、Linux 工具修改先固定输入输出
  5. 5. 五、每轮结束检查预算是否超支
  6. 6. 六、什么时候扩大预算
  7. 7. 七、把 AI 从代码生成器变成受控执行者
请输入关键词进行搜索