乐于分享
好东西不私藏

AI改代码越快,我越要先看边界

AI改代码越快,我越要先看边界

周四下午4点半,同事在群里@我:

"你刚才合并的代码把我的数据同步接口搞挂了,线上已经开始报错。"

我立刻打开Git历史。合并记录显示:我的feature分支合并进了release,但提交列表里不只有我的改动,还混入了另外两个同事正在开发中、没测完的功能代码

这些代码随着release分支自动部署,触发了线上数据异常。

紧急回滚、数据清理、开复盘会……那一刻我意识到一个问题:

AI改代码的速度越来越快,但我检查代码的速度没有跟上。

更可怕的是,我甚至没意识到应该检查什么。


AI改了什么,我真的知道吗?

事故发生前10分钟,我是这么操作的:

我让Claude Code帮我合并feature分支到release,处理一些冲突。

帮我合并XX分支,解决这些冲突

AI很快搞定了,给我看了一下改动。我扫了一眼,没发现明显问题,觉得没什么大不了的,就推送了。

但我没有做这件事:

# 看看到底要合并哪些提交git log --oneline release..feature/recommend-api

如果我当时跑了这个命令,会看到提交列表里有其他人的commit。那一刻我就应该停下来。

后来复盘才发现,真正的问题不是Git乱合并,也不是AI神奇地改坏了分支,而是我没有让AI做"合并范围校验"

分支里到底有哪些commit、哪些文件会进release,我没有先确认。

AI会处理操作,但不会替你判断边界。


第二次事故:AI的"好心"

两周后,类似的问题又发生了。这次是AI"顺手帮我清理了无用代码"。

我让AI写一个新接口,替换旧的数据查询逻辑。AI写完后,看到旧接口不再使用,就把UserMapper.xml文件删了。

编译通过,本地测试通过(我只测了新接口)。第二天上线后,同事发现他负责的数据同步功能失效了——他的接口也在用这个Mapper.xml,被我删了。

Maven编译不会检查Mapper.xml是否被其他地方引用,因为这是运行时加载的。AI不知道这个文件被多个接口共享。


我发现真正危险的不是写错,而是改动边界失控

两次事故后,我开始意识到问题不在于AI写的代码对不对,而在于:

AI不知道它可以改什么,不可以改什么。

更准确说:

  • AI不知道合并分支时应该只包含我的提交

  • AI不知道Mapper.xml可能被其他接口共享

  • AI不知道什么文件可以删,什么文件不能碰

  • AI不知道什么操作风险高,需要人工确认

我之前的用法是:丢给AI一个需求,让它去做。做完了我看一眼,没发现明显问题就提交。

这种用法的前提是:AI知道边界在哪里。

但它不知道。


我后来只加了三道闸

现在回头看,我需要的不是更强的AI,而是更清楚的边界。

我给AI编码加了三道闸:

第一道闸:明确哪些操作AI不能直接执行

我在项目根目录放了一个CLAUDE.md文件,写清楚AI不能做什么:

# 严禁AI执行的操作git push到release/mastergit merge到release/master删除文件(除非我明确要求)改动我没有要求的文件"顺便优化"或"清理无用代码"

CLAUDE.md不是保险箱,它只是让AI每次进入项目时先看到规则。真正起作用的,还是我后面有没有按规则检查diff、提交范围和风险点。

现在任何Git操作,我都让AI给出命令建议,但不让它直接执行。AI可以帮我分析冲突、给方案,但最终操作必须我自己做。

更重要的是,合并前我一定会先跑这两个命令:

git log --oneline release..feature/recommend-apigitdiff--stat release...feature/recommend-api

这里的关键不是背命令,而是确认:即将进入release的提交,是否全部属于本次需求。

如果提交列表里有我不认识的commit,或者文件改动超出预期范围,就停下来排查,而不是直接推送。

第二道闸:diff必须看删除操作

第二次事故后,我改变了看diff的方式。

以前我主要看AI加了什么代码,现在我重点看AI删了什么:

gitdiff--stat# 先看文件列表,重点关注deleted filegitdiff# 再看具体改动

如果diff里有deleted file,我必须确认:

  • 这个删除是我明确要求的吗?

  • 这个文件是否被其他地方引用?

对于Mapper.xml这种共享文件,我不会只看文件名,而是会搜namespace、Mapper接口、SQL id,确认没有其他接口还在调用:

grep-r"namespace=\".*UserMapper" .grep-r"selectUserById" .grep-r"UserMapper" src/main/java

现在我让AI改代码时,会明确告诉它:

写一个新接口实现XX功能注意:- 只写新接口,不要动旧接口- 不要删除任何文件- 不要"顺便优化"其他代码

把边界说清楚,比事后检查省力得多。

第三道闸:改动前先让AI列出影响范围

对于复杂改动,我现在不会直接让AI执行,而是先让它给个Plan:

Research一下XX功能涉及哪些模块Plan一下如何实现,列出:1. 需要改哪些文件2. 可能的风险(缓存/配置/定时任务)3. 测试点Plan确认后再Execute

看到Plan后,我会追问AI容易漏的点:

Plan里没看到缓存处理,这个改动会影响缓存吗?Plan里没提定时任务,定时任务需要改吗?配置文件需要同步吗?

这些问题不能指望AI每次都主动想到。你不把它写进Plan要求里,它就可能漏。


我按风险给AI的操作分了三档

现在我会根据风险决定AI能做什么:

禁止AI直接执行(必须人工操作):

  • release/master分支操作

  • 删除文件

  • 数据库迁移脚本

AI可以做,但必须先Plan并人工确认:

  • 跨3个以上文件的改动

  • 涉及缓存、定时任务

  • 涉及公共Mapper.xml、工具类

AI可以直接做,但我必须看diff:

  • 注释、日志

  • 单文件小修改

这个分级不是为了限制AI,而是为了让我清楚什么时候应该停下来检查。


这套边界在工程里叫什么?

2026年前后,Mitchell Hashimoto、Martin Fowler等人都在讨论类似的Harness Engineering:不是只换更强的模型,而是给Agent设计更可靠的工作环境。

这个概念我不是想展开讲。对我来说,Harness Engineering最有用的一点就是:不要只盯模型强不强,而要设计一套让AI不容易越界的工作环境。

我的理解是:不求模型更"聪明",而是通过工程手段防止同样错误再次发生。

每次AI出错,我都会问自己:

  1. 这个错误是什么

  2. 为什么会犯这个错

  3. 如何避免下次再犯

然后把规则补充到CLAUDE.md里,或者改进我的Prompt。

比如误删Mapper.xml后,我在CLAUDE.md里加了一条:

# 特别注意- Mapper.xml可能被多个接口共享,删除前必须全局搜索引用

Git事故后,我把"禁止AI操作release分支"写进了规则。

不只是改这一次,而是改规则,让AI以后不再犯。


你现在可以做的三件事

如果你也在用AI写代码,这三件事可以立刻做:

1. 创建一个CLAUDE.md,写下禁止事项

至少包含:

  • AI不能直接操作的分支(release/master)

  • AI不能做的操作(删除文件、顺便优化)

  • 项目的特殊约束(共享Mapper、缓存逻辑)

2. 下次合并前先跑git log

git log --oneline release..feature/xxx

看看到底要合并哪些提交,确认都在预期范围内。

3. 记录下一次AI出错

问三个问题:

  • 错误是什么

  • 为什么会犯

  • 如何避免下次再犯

把答案写进你的CLAUDE.md


写在最后

AI改代码的速度确实快,但如果不给它画边界,出问题也很快。

这篇文章记录的是我踩过的两个坑,以及我后来补上的三道闸。我不敢说这套方法完美,但至少让我知道什么时候应该停下来检查。

AI不是银弹。关键是知道它能做什么,不能做什么。

后面我会把这套检查清单整理成一份更完整的版本,尤其是Git、Mapper、缓存、配置、定时任务这几类高风险点。不是为了做资料,而是为了以后少踩同一种坑。


关于作者

我是Leon,Java后端开发,专注推荐系统和搜索业务。这3个月最大的收获不是AI帮我写了多少代码,而是我开始学会给AI改代码画边界。

如果你也用AI改过真实项目,我更想看你踩过的坑。尤其是:

  • AI有没有动过你没让它动的文件?

  • 你是怎么防止AI"顺便优化"的?

欢迎在评论区聊聊。