AI 改代码便宜但静默行为变更风险高,建议先量化 diff 预算并为遗留代码编写表征测试(characterization tests)锁定当前行为,再做小而可验证的改动。
AI 的重构建议很廉价。静默的行为变更很贵。diff 预算就是连接二者的桥梁。每一次 AI 重构都是一场赌注。赌注只有在行为存活时才兑现。diff 预算让赌注小到可以核查。
本周 DEV 问了这样一个问题:谁来测试 AI 审阅者?诚实的答案是:你。行为测试是裁判。它们决定一个补丁是否保留了行为。
AI 工具让每位开发者都变成了审阅者。但没有人测试审阅者。这个鸿沟在遗留仓库中伤害最大。
一个免费模型提出了一个大胆的重构。补丁看起来很干净。行为却静默地偏移了。更小的补丁可以修复这个问题。经验证的补丁可以更好地修复它。
大 diff 隐藏了回归。审阅者略过中间部分。合并冲突成倍增加。一个混乱的仓库没有测试也没有契约。解决方案不是更好的模型,而是更小的、经验证的变更。
选择调用者最少的那个最混乱的模块。先测量扇入和扇出。有三个调用者的模块比有三十个调用者的模块更安全。从小开始。小范围让后面的每一步都可以衡量。
编写记录当前输出的测试。它们断言的是稳定性,而不是正确性。它们冻结今天的行为。MonkeyCode 是一个开源项目,它的免费模型访问可以快速起草这些测试。在信任之前,验证每个测试对照真实代码。模型写的测试仍然是你的测试。
从模块的公共函数开始。覆盖快乐路径和错误路径。每个函数一开始有三个测试就够了。目标是织一张网,而不是一幅杰作。
披露:本文是 MonkeyCode 产品推广的一部分。
选一个硬数字。每次提交二十行变更是合理的起点。每次提交一个公共签名变更。把预算写下来。用脚本强制执行它。预算迫使模型将其计划分割成可审查的块。
这个数字匹配人类审查能力。审阅者可以仔细检查二十行。他们无法检查两百行。
向模型提供模块和预算。要求一个计划,而不是一堆补丁。每个计划步骤必须适合预算范围内。每个步骤必须保持行为测试绿灯。如果模型拒绝,重构就太大了。
门禁是一个小脚本。它检查 diff 大小。然后运行测试套件。以下是完整的产物:
#!/usr/bin/env python3
'''refactor_gate.py - approve or reject a refactor patch.'''
import subprocess
import sys
DIFF_BUDGET = 20
TEST_CMD = ['pytest', '-q']
def diff_stats(base):
out = subprocess.run(
['git', 'diff', '--numstat', base],
capture_output=True, text=True, check=True,
).stdout
added = removed = 0
for line in out.splitlines():
a, r, _ = line.split('\t')
if a != '-':
added += int(a)
if r != '-':
removed += int(r)
return added, removed
def tests_pass():
return subprocess.run(TEST_CMD, capture_output=True).returncode == 0
def main():
base = sys.argv[1] if len(sys.argv) > 1 else 'main'
added, removed = diff_stats(base)
total = added + removed
print(f'diff: +{added} -{removed} / budget {DIFF_BUDGET}')
if total > DIFF_BUDGET:
print('REJECT: over budget. Split the refactor.')
sys.exit(1)
if not tests_pass():
print('REJECT: characterization tests failed.')
sys.exit(1)
print('APPROVE: within budget, tests green.')
if __name__ == '__main__':
main()
在每个模型生成的提交后运行它。python refactor_gate.py main。退出码零意味着批准。退出码一意味着拒绝。把它接入 CI 或 pre-commit 钩子。
门禁在几秒内运行。每个补丁上它几乎不花任何成本。这个脚本是模型无关的。它同样约束人类补丁。
记录什么变了以及为什么。记下模型的计划和测试结果。记下 diff 数量。未来的读者会感谢你。被拒绝的补丁是一个决策,不是失败。
它将生成与验证分离。模型提出建议。测试做裁决。预算保持建议小。小建议大声失败。大建议静默失败。这个不对称就是全部诀窍。
在一次性环境中运行门禁。没有本地依赖腐化。笔记本上没有共享密钥。MonkeyCode 的免费服务器选项提供了那个环境。循环从第一天起就保持可重现。行为测试加上干净的运行器胜过任何提示。
你也可以在笔记本上运行这个。免费服务器只是去除了设置摩擦。它还把模型调用和测试放在一个地方。
行为测试锁定当前行为。它们不证明它是正确的。Diff 预算让大型重构慢下来。每次提交二十行意味着一个大型模块需要二十次提交。
门禁只测量行数。它不测量语义风险。对哈希函数的一行修改可能比二十行重命名破坏更多。
免费层级会变化。截至 2026 年 8 月,一千万 token 免费层级是当前的。在围绕它做计划之前,在项目页面上验证配额。
预算是你选择的一个数字。根据你的审查能力调整它。独立开发者可能更喜欢十行。大型团队可以处理五十行。
有完整覆盖的新生项目不需要它。需要形式正确性的团队需要证明,而不是测试。任何接触认证或支付代码的人都需要人工审阅者。
没有 CI 的团队应该先解决这个问题。门禁假设有 git 和测试运行器。它是一个地板,而不是天花板。
选择你仓库里最丑的叶子模块。用行为测试锁定它。设置二十行的预算。向免费模型要求最小的安全变更。运行门禁。衡量结果。
在你的 PR 描述中分享 diff 数量。与上次重构比较。数据打败感觉。你仓库的行为是真正的基准。