§ Essay

如何避免 AI 越改越乱?

和 AI 一起写代码,最大的风险不是写不出来,而是越改越乱。用 TDD 用例当唯一 Spec、拷问式提问拉齐认知、Issue 式整体分析修 Bug、重构节奏防止测试腐化,这四条规则对抗 AI 协作时代的项目腐烂。

Katrina · · 8 min read ·

和 AI 一起写代码,最大的风险不是写不出来,而是越改越乱。下面这四条规则,是从实践中沉淀下来的对策。


1. 用 TDD 用例代替文档,作为唯一的 Spec

可执行的测试比静态文档可靠 —— 也就是常说的活文档(Living Documentation)

文档为什么会失效?

原因说明
描述不准确自然语言天生有歧义,写的时候可能就没想清楚
描述过时代码改了,文档忘了同步,变成”僵尸文档”
AI 上下文问题长文档被上下文压缩后,AI 会”忘掉”关键细节,甚至产生注意力幻觉

为什么 TDD 用例是更好的 Spec?

维度文档TDD 用例
可执行静态描述,跑不起来自动运行验证
同步性易过时失败即过时,骗不了人
歧义自然语言模糊代码精确无歧义
AI 友好上下文压缩可能丢信息用例 = 标准 harness,幻觉率极低

例子:

  • 文档写法:用户登录功能支持邮箱登录。
  • 测试写法:输入邮箱 + 正确密码,期望返回登录成功;输入错误密码,期望返回 401

AI 不小心把登录逻辑改成手机号时,测试会直接报错,它就能立刻自我纠错。

一个容易踩的坑:测试只描述”What”,不描述”How”

测试关心的是”做了什么”,不是”怎么做”。换句话说:区分事实(业务行为)实现(内部细节),只绑定前者。

打个比方:验证”快递送到了吗”,应该看包裹在不在门口、完不完整;而不是跟踪快递员走了哪条路、用了什么交通工具、中途停了几次。快递员换电动车、改路线,快递还是那个快递。但如果测试在追踪路线,换路就会导致全部测试失败,逼着你去”修测试”。

这对 AI 协作意味着:

后果说明
重构即崩塌AI 改个内部函数名 / 调用顺序,所有测试瞬间失败
AI 陷入”修测试”泥潭AI 误以为测试是真理,转去迁就测试而不是修逻辑
幻觉率飙升AI 编造”补丁代码”让旧 mock 重新匹配,反而引入新 Bug

记住一句话: 测试是契约(Contract),不是说明书(Instruction) —— 它规定”应该发生什么”,不规定”必须怎么做”。


2. 用”拷问 Skill”做前期认知拉齐

编码前先把问题想透,用结构化提问把需求、设计和边界”拷问”清楚。这是 Matt Pocock(TypeScript 领域专家)提倡的方法,通常封装成一个 AI Skill(提示词模板):写代码前,用一系列尖锐、结构化的提问,把模糊的想法逼成清晰的规范

为什么这比编码本身更重要?

理由说明
方向错误是最大的浪费编码后期才发现理解偏差,返工成本极高
AI 编码快,但思考不能省你自己认知模糊,AI 只会更快地生成一堆漂亮的废品
拷问过程 = 共识对齐强迫产品、开发、AI 用同一套术语和逻辑理解问题

一句话: 用人类的严谨思考,为 AI 的快速执行铺路 —— 把需求从”散文”变成”合同”。


3. 用”Issue 式整体分析”修 Bug,拒绝饮鸩止渴式 Hotfix

把 Bug 当作一个小需求来修:先分析、设计、规划,而不是匆忙打补丁。

Hotfix 的危害:

  • AI 倾向最小改动掩耳盗铃:加 if、吞 try-catch、把简单逻辑改得绕来绕去。
  • 系统腐化:补丁越积越多 → 兼容代码爆棚 → 熵增到不可维护 → 彻底救不回来。

正确的修法,像处理 Issue 一样:

1. 统一管理   所有 Bug 进 Issue 系统,不靠人脑记
2. 整体分析   根因是什么?影响范围?是否暴露设计缺陷?
3. 拉齐认知   原需求没覆盖?还是设计有漏洞?明确"正确行为"
4. 系统化重构 让 Bug"不存在",而非"被掩盖"

修 Bug 不是在贴创可贴,而是在修复滋生 Bug 的源头 —— 与其外科手术式地切除,不如免疫系统式地增强。

测试先行:每个 Bug 修复必须附带缺失的测试用例

修 Bug 不是结束,而是补全 Spec 的开始:

1. Bug 出现   → 说明至少有一个业务场景没被现有 Spec 覆盖
2. 根因分析   → 找到缺失的场景
3. 先补测试   → 写一个"如果以前有这个测试,Bug 就不会发生"的用例
4. 再修代码   → 让新测试通过,同时保证老测试全绿
5. 回顾       → 这个测试该归到哪?要不要重构测试结构?

收益: 同一个坑不会踩两次,测试套件随 Bug 修复越来越健壮 —— 这才是真正的”免疫系统增强”。


4. 用”重构节奏”防止测试自身腐化

TDD 用例不是越多越好,测试套件本身也需要定期维护,否则会从资产变成负债。

测试文件为什么会腐化?

原因说明
场景堆积Bug 修复不断追加用例,文件越来越臃肿
僵尸测试skip / only 的用例长期不清理
命名漂移describe / it 的描述已不能准确反映业务语义
反馈变慢测试运行太久,拖慢 AI 反馈循环,TDD 的核心价值被稀释

卫生检查清单

建议每两周或每个迭代末做一次轻量扫描:

  • 有没有重复的测试场景?
  • 有没有永远不跑、被 skip 的测试?
  • describe / it 描述还能准确反映业务吗?
  • 运行时间会不会拖慢 AI 反馈?

节奏建议: 每两周花 30 分钟,让 AI 扫一遍测试套件 —— 重复、命名不规范、跑太慢的测试,AI 很擅长找出来。


一句话总结

可执行测试当事实来源,前置拷问做认知拉齐,Issue 式分析修 Bug,重构节奏维持测试健康 —— 这四条是 AI 协作时代对抗项目腐烂的根本对策。