使用 AI Agent 做开发时,经常会遇到一种很典型的问题:

明明只让它修一个小问题,最后却改了一大片。

比如:

  • 原本只需要修一个接口,结果连公共工具类一起重构了;
  • 只是修一个Bug,却顺手改了命名、格式和目录结构;
  • 一个很小的需求,最后Diff扩展到十几个文件;
  • 功能确实修好了,但Review时却很难判断哪些修改真正有必要;
  • Agent认为自己是在“顺手优化”,开发者却更担心引入新的副作用。

这种情况本质上不是AI不会写代码。

而是:

任务目标虽然明确了,但修改边界没有明确。


一、为什么Agent特别容易“顺手多改一点”?

开发者看到一个Bug时,通常会考虑:

这次只修这个问题,还是顺便重构?

但Agent在分析代码时,可能发现:

  • 命名不统一;
  • 某些函数可以抽象;
  • 重复逻辑可以合并;
  • 旧代码结构不够优雅;
  • 类型定义还能进一步整理。

于是它很容易把:

“解决当前问题”

扩展成:

“把附近代码一起优化掉”。

从局部代码质量看,这些修改未必错。

问题在于,它们可能已经超出了当前任务真正需要的范围。


二、任务目标和修改范围不是一回事

例如任务是:

修复用户资料保存失败的问题。

这是任务目标。

但它没有回答:

  • 可以修改哪些文件?
  • 公共模块能不能动?
  • 能不能升级依赖?
  • 能不能重构接口?
  • 能不能顺便改命名?

所以Agent可能认为:

只要最终解决问题,怎么改都可以。

而开发者真正期望的可能是:

尽量只修改和这个Bug直接相关的代码。

所以Agent任务最好同时定义:

要解决什么 + 允许改到哪里。


三、为什么小问题最后会变成大Diff?

假设真正根因只在一个判断条件。

本来只需要修改:

5行代码。

但Agent继续分析以后,又发现附近函数存在重复,于是抽取方法;抽取以后又发现类型不统一,再顺手修改类型;类型变化后又影响多个调用方。

最终可能变成:

5行修复 → 200行Diff。

这时候真正的问题修好了,但Review成本却急剧上升。

因为开发者需要重新确认:

  • 哪些改动是修Bug必须的;
  • 哪些只是优化;
  • 哪些可能引入新风险。

所以大Diff最大的风险不是“代码多”。

而是:

真正的核心修改被大量附带变化淹没。


四、什么叫“最小修改原则”?

简单理解就是:

能用最小范围解决当前问题,就不要主动扩大修改面。

例如某个Bug只需要:

  • 修改一个条件;
  • 补一个边界判断;
  • 更新一个测试;

那就优先完成这三件事。

不要在同一个任务里顺手:

  • 重构模块;
  • 改目录;
  • 统一所有命名;
  • 更新无关依赖。

这些事情如果真的有价值,可以单独开任务。

这样做的好处是:

每一个Diff都更容易解释。


五、公共模块应该默认视为高风险区域

例如:

  • shared;
  • utils;
  • config;
  • auth;
  • database;
  • common types;
  • 全局中间件。

这类文件往往被很多地方依赖。

Agent一旦修改,影响范围可能远大于当前任务。

所以可以提前规定:

如果必须修改公共模块,先说明原因和影响范围,再继续。

这样Agent就不会因为“这里改一下更优雅”,直接把整个系统一起带进修改范围。


六、让Agent先列预计修改文件,比直接执行更稳

在真正开始改代码之前,可以先让Agent输出:

预计修改文件:

  • user.service.ts
  • user.controller.ts
  • user.service.test.ts

然后再问:

是否还有必要修改公共模块?

如果Agent突然列出:

  • config.ts
  • shared.ts
  • package.json
  • 多个无关模块

就值得提前检查:

任务是不是已经开始扩张了。

这个动作的价值很大,因为它能在Diff真正变大之前发现范围失控。


七、“必要修改”和“可选优化”最好分开

Agent经常会发现一些确实值得优化的东西。

这时候不一定要禁止它发现。

更好的方式是分成两类:

必要修改

当前任务不做就无法解决问题。

可选优化

和当前任务有关,但不是这次必须完成。

例如:

必要:
修复错误的状态判断。

可选:
重构整个状态管理模块。

这样Agent仍然可以指出潜在优化点,但不要直接把它们混进当前提交。


八、修改范围突然扩大时应该暂停

如果Agent一开始预计改2个文件,执行到一半突然变成:

8个文件。

这本身就是一个值得关注的信号。

可能说明:

  • 原来的根因判断不完整;
  • 当前方案影响面比预期更大;
  • Agent开始做额外重构;
  • 任务已经不是原来的“小修复”。

这时候最稳的做法不是继续一路改到底。

而是先重新确认:

为什么范围变大?这些新增修改是否真的必要?

Agent越自主,这种“中途重新确认边界”的能力越重要。


九、为什么“顺手重构”最容易制造Review压力?

如果一个PR同时包含:

  • Bug修复;
  • 文件重命名;
  • 函数抽取;
  • 格式调整;
  • 类型重构;

Reviewer很难快速判断:

哪一行代码真正修复了问题。

而且一旦上线后出现异常,回滚也变得更麻烦。

因为无法简单判断:

是Bug修复出了问题,还是顺手重构导致的?

所以工程上常见的一个原则就是:

修Bug和大范围重构尽量分开。

对于Agent来说更应该如此。


十、可以直接给Agent增加“边界约束”

以后交给Agent任务时,可以这样要求:

先分析问题并列出预计修改文件。优先采用最小修改方案,不要主动重构无关代码、升级依赖或调整公共模块。如果必须扩大修改范围,请先说明原因、影响文件和替代方案。可选优化单独列出,不要自动加入本次修改。

这样Agent获得的不只是:

任务目标。

还有:

执行边界。


十一、任务完成后再检查一次“有没有改过头”

最后可以重新看:

git diff

然后逐个问题检查:

  • 每个修改文件都和当前任务有关吗?
  • 有没有顺手重构?
  • 有没有无关格式变化?
  • 有没有修改公共逻辑?
  • 有没有可以拆到下一个任务的优化?
  • 如果删掉某段改动,当前Bug还能不能被修复?

如果答案是:

去掉这部分也完全不影响问题解决。

那它大概率就不是这次任务必须留下的内容。


最后

AI Agent自动改代码后经常“改过头”,本质上不是因为它能力太强。

而是:

任务只有目标,没有边界。

Agent越自主,就越容易从:

修复一个问题

扩展到:

顺便优化一大片代码。

真正稳定的Agent开发流程应该做到:

先明确目标 → 限定影响范围 → 优先最小修改 → 可选优化单独记录 → Diff扩大时重新确认。

AI Agent真正成熟的标志,不只是:

能不能把问题修好。

还包括:

能不能只改真正需要改的地方。

因为高质量的自动开发,不应该只是“修改更多代码”。

而应该是:

用尽可能小、可解释、可验证的变化解决问题。

持续更新 Codex、Claude Code、AI Agent 与大模型开发工作流实战内容,更多深度内容和稳定订阅渠道欢迎搜索关注「孤狼GPT」。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐