
最近开发者社区里一个标题很容易让人停下来多想几秒某位长期实践者在一次视频分享中宣布“Im done coding with AI”也就是不再用 AI 写代码了。这件事在“AI Coding Agent”“Coding Plan”“Vibe Coding”几乎天天上热搜的背景下显得尤其刺眼。一边是大量开发者用 Agent 自动生成整个模块一边是资深实践者公开宣布退出这种反差本身就值得写一篇文章。我的判断是这类“告别”并不是在否定 AI 编程工具的价值而是在提醒所有人——AI coding 的能力边界和工程使用方式远比“能不能生成代码”更值得关注。很多人一开始用 AI 写代码觉得惊艳是因为任务的颗粒度足够小一旦把 AI 放进长期维护的生产项目里问题就会从“能否生成”变成“能否收敛”从“写得多快”变成“改得动吗”。这篇文章不打算站队“该用”或“不该用”。我想把 AI coding 的真实能力边界、最容易导致项目失控的几个环节以及一种更可持续的工程化使用方式拆开讲清楚。文章会包含大量可直接复制的规则文件、质量门禁脚本和权限清单模板不管你用的是 Copilot、Cursor还是各类 Agent Coding 工具思路都能迁移。1. 为什么 AI coding 越火“我不用了”的声音反而越响过去两年AI 编程工具经历了明显的“三级跳”。最早普及的是代码补全典型能力是“你写一个函数名它帮你补完函数体”。这个阶段对开发者干扰最小本质上像更聪明的自动补全。随后聊天式编程助手兴起你可以选中一段代码问“这段逻辑哪里可能有问题”“帮我改成异步实现”工具会基于当前文件或仓库索引给出建议。到了 Agent 阶段工具不再满足于“给建议”而是直接在编辑器或终端里自主修改多个文件、运行测试、修复报错形成一个闭环。再往后出现了一个更工程化的概念Coding Plan / Agent Plan。它不再只处理“帮我写一个函数”这种颗粒度而是让你描述一个较大的任务目标让 Agent 先产出实施计划再按计划执行。很多平台还围绕这种模式推出了更细粒度的收费和资源配额方案。也就是说AI 的“手”越来越长从单文件建议进化到多文件重构、跨模块变更、甚至是长周期任务自动执行。这本来应该是效率的胜利但为什么“我不再用 AI 编程”的声音反而出现了原因在于工具的能力边界变宽之后开发者对它的信任边界却没有同步建立。一个能自动改 10 个文件的 Agent如果对项目约束理解不到位也可能把 10 个文件全部改坏。它改得越快你 review 的压力就越大回滚的成本就越高。早期的代码补全“翻车”最多影响一个函数现在的 Agent“翻车”可能影响整个迭代。所以不是 AI 编程不行了而是旧的“无边界使用”方式开始失效了。2. 先理清概念Vibe Coding、Agent、Coding Plan 到底分别解决什么问题要讨论 AI coding 的边界必须先分清几个容易混淆的概念。很多争论其实就是因为把不同层级的能力混在一起谈。概念交互粒度典型方式适合的任务主要风险代码补全行级输入注释或函数签名生成代码CRUD、样板代码、简单算法方向错误但看起来合理聊天式编程文件/函数级选中代码后提问人工应用修改代码解释、重构建议、Bug 定位修改建议影响面不清楚Agent Coding多文件/模块级Agent 自主查找、修改、运行验证跨文件小需求、测试补齐对项目全局约束理解不足Coding Plan / Agent Plan任务级先做计划再按计划执行长任务较大功能开发、多文件重构计划本身错误导致长链路失败从这张表能看出一个规律任务颗粒度越大初始效率收益越高但对“上下文”的要求也越高。单行补全只需要知道当前函数在写什么多文件 Agent 需要知道整个模块的依赖关系Coding Plan 则需要知道业务规则、技术约束、测试策略、部署方式等大量隐性问题。然后再说 Vibe Coding。这个词经常被翻译成“氛围编程”本质上描述的是开发者只负责描述意图和验收标准把编码实现交给 AI。它很容易让初学者产生一种错觉写程序的瓶颈从“逻辑能力”变成了“表达能力”。这句话有一定道理但对生产项目而言是远远不够的。Vibe Coding 适合的是“能快速验证、负责人可以完整理解每一行代码后果”的场景比如临时脚本、个人工具、Demo、原型。它不适合那种“代码上线后要维护三年”的业务系统。原因很简单Demo 只要求当下可运行生产系统要求未来可修改。后者要求代码里的每一个意外复杂点都有据可查而这恰恰是纯“氛围式”开发最薄弱的环节。3. AI coding 真正擅长的场景不是所有代码都适合交给 AI讨论边界之前先肯定 AI 真正擅长的事。如果因为这些地方好用就误以为“全局都好用”很容易在复杂项目中踩坑如果因为复杂项目踩坑就全盘否定又会错过明显的效率红利。从工程实践看AI coding 在以下几个场景中的可靠性明显较高第一低歧义的样板代码。比如把一个 DTO 转成另一个 DTO、生成 MyBatis 的 XML 映射、写一个标准的 Feign Client。这类代码规则清晰、上下文闭环、不需要跨模块推理AI 生成的质量非常接近熟练工程师。你只需要给它明确的输入输出和字段映射关系。第二单元测试与重复性测试数据补齐。给 AI 一个函数和它的边界条件描述让它生成边界测试用例这通常比人工手写更快。特别是那些“给日期范围过滤订单”“根据状态机流转更新状态”之类的确定性逻辑AI 能把多组 if 分支覆盖得很好。第三常规技术栈的“翻译式”重构。比如把一个工具类从 Java 8 的Date改为LocalDateTime把一段 Python 脚本改成 Java 服务把 XML 配置迁移到 YAML。这类工作本质上是“有对应模板的转换”AI 不太会发挥出奇怪的创造力。第四快速构建原型和技术验证。当你想验证一个中间件能不能用、一套框架的 API 是否满足需要时让 AI 生成一个最小可运行示例能明显缩短进入验证的时间。我建议用一个标准来判断“AI 生成的这部分代码未来被修改时修改原因是否大概率只局限于文件内部”如果答案是肯定的那很适合交给 AI。如果它一旦改变就可能牵扯权限、事务、分布式事务、消息可靠性等问题那它就不适合在没有强约束的情况下全自动生成。4. 真正让开发者想“弃用”的三个核心原因那么AI coding 在实际项目中到底问题出在哪里拆开看核心原因不只是“代码质量不高”这么简单。4.1 上下文控制权从人转移到了模型人工写代码时大脑里会维护一个“影响地图”我改了这个方法谁在调用这个字段被序列化了吗这条 SQL 的数据权限过滤全吗模型没有这个完整地图它只能依赖提示词、仓库索引和它在上下文窗口里看到的内容。当项目规模增大模型生成的修改很容易出现“局部正确全局错误”。比如你让它修复订单校验的 Bug它确实修复了但顺带修改了日志打印方式、重新格式化了一个无关函数、甚至把异常类型从IllegalArgumentException换成了BusinessException。第一次运行没报错但你的调用方可能依赖原来的异常类型做特定处理。来看一个典型的变化过程。假设原始代码是这样的public void saveOrder(Order order) { if (order.getItems() null || order.getItems().isEmpty()) { throw new IllegalArgumentException(订单至少需要一个商品); } orderRepository.save(order); }第一轮 AI 修复 Bug表现很好。但连续几轮之后代码可能变成这样public void saveOrder(Long userId, Order order) { if (!authService.checkPermission(userId, order:create)) { throw new AccessDeniedException(无权限); } if (order.getItems() null || order.getItems().isEmpty()) { throw new IllegalArgumentException(订单至少需要一个商品); } order.setCreateUser(userId); orderRepository.save(order); }单独看加了权限校验、补充了创建人字段都是合理的改进。但如果这个“合理性”没有被评审确认如果saveOrder原本是供内部定时任务调用的定时任务里没有userId的上下文这次修改就直接引入了一个生产事故。AI 并不是坏它缺少的是“这个接口的全部历史约束”。4.2 质量门禁从“写代码之前”挪到了“Review 之后”传统开发中质量门禁分布在很多环节设计评审、编码规范、单测、Code Review、集成测试。AI coding 把大量编码工作压缩了但这些门禁不会自动消失。更麻烦的是它们会被集中推给 Code Review 环节。过去 review 一段 200 行的人工代码你能顺着作者的思路走现在 review 一段 AI 生成的 500 行代码你不知道它为什么选择这个实现、为什么多引入了一个工具类、为什么改变了原有命名。你需要额外花时间去理解“AI 的意图”。如果团队成员没有形成“AI 代码默认需要更严格评审”的共识这些坏味道就会全部流进主干。因此“用 AI 写得越快评审负担越重”并不是一个伪命题。当生成速度超过团队消化速度时效率不升反降。4.3 技术债务被“漂亮代码”掩盖传统认知里技术债务往往是可见的混乱的命名、过长的函数、没有注释的魔法数字。这些代码很丑但至少容易识别。AI 生成的代码常常具有“表面整洁性”——命名标准、格式统一、抽象层次合理但暗藏了许多隐性问题。典型的例子是AI 倾向于在一个修复任务中顺手增加“防御性逻辑”。它可能会在没有任何需求依据的情况下为方法增加对 null 的默认处理而这些默认值掩盖了上游真正的问题。等你排查线上数据异常时会发现不是逻辑算错而是 AI 在某处悄悄加了一个“空值给默认 0”的逻辑把问题静默吞掉了。这种债务不容易被静态检查工具发现因为它语法正确、规范达标问题出在“与业务需求的隐性冲突”上。它也更难在 Code Review 中被发现因为 reviewer 很难从一次 diff 里判断“这行兼容逻辑到底是需求要求还是 AI 自作主张”。5. 不一定要“告别 AI”但要用工程纪律重构 AI coding 工作流理解了问题根源解法就清晰了不是“用不用 AI”而是怎样让 AI 在一个可控的约束空间里工作。完全弃用是极端选择无约束乱用则是另一个极端。现实工程需要的是“带护栏的 AI coding”。我把这套方法归纳为三条原则把任务拆小让 AI 的上下文窗口装得下完整约束用规则文件固定项目的隐性约定不让 AI 每次重新猜测用自动化门禁和人工评审把质量入口前移而不是让 AI 把代码改完再由人“擦屁股”。5.1 创建项目级规则文件很多 AI 编码工具支持在仓库中维护一个规则文件比如AGENTS.md。它的价值在于把团队里约定俗成的约束变成 AI 每次修改代码前都必须阅读的显式指令。下面是一个典型的规则文件示例# 文件路径AGENTS.md # 本文件用于约束 AI 编码助手的行为请在所有代码生成任务开始前阅读 ## 项目背景 - 这是一个基于 Spring Boot 3 的订单中台服务禁止引入重量级规则引擎 - 数据库为 MySQL 8.x所有金额字段使用 BigDecimal禁止使用 double - 生产环境通过 Nacos 配置中心管理开关新增开关时必须同步更新文档 ## 修改约束 - 禁止修改 pom.xml 中的依赖版本除非任务明确要求升级依赖 - 修改公共方法签名前必须先搜索全部调用方并评估影响 - 不要格式化与本次任务无关的代码不要把 XML 配置转为注解式 - 所有对外接口的异常必须使用业务异常码禁止直接抛出 RuntimeException - 涉及数据库变更时必须同时提供正向 SQL 和回滚 SQL ## 代码风格 - Service 层禁止直接操作 HttpServletRequest - 所有时间字段统一使用 LocalDateTime不使用 Date - DTO 与 Entity 必须显式转换禁止使用 BeanUtils.copyProperties 拷贝嵌套对象规则文件不要写得像一份“思想品德手册”它必须能阻断真实的工程问题。每一句话都应该来自过去的某个线上事故或 review 教训。写得越具体AI 越不容易跑偏。5.2 让 AI 在动手前先输出“影响清单”很多时候 AI 改坏代码不是因为它能力不行而是因为它在没有充分探索的情况下就开始“自信输出”。你可以在任务提示中强制加入一个前置步骤让它先产出影响清单等待人工确认后再修改。这套做法在生产项目中非常有效。下面是一个可以放入团队提示模板的示例在修改任何代码之前请按以下步骤执行 1. 列出当前变更涉及的全部文件并说明每个文件修改的原因。 2. 搜索所有调用方列出可能受影响的组件和接口。 3. 如果本次变更会改变方法签名、API 路径、错误码或数据库字段请明确指出。 4. 说明你计划如何保持向后兼容如果不兼容理由是什么。 5. 在人工确认方案前不允许修改代码文件。你不需要每次都把这段话打一遍。可以保存为团队内部的一个提示词模板凡是涉及跨文件重构、接口变更、数据库变更的任务强制使用这个模板。它能有效防止 AI 跳过探索阶段直接进入“生成模式”。5.3 用自动化门禁守住安全边界人工评审很重要但不能完全依赖人工。很多规则可以使用 Git Hooks、静态检查或 CI 检查来落地。下面是一个最小示例在 pre-commit 阶段检查是否存在未纳入索引的代码改动并提示开发者确认测试计划。#!/usr/bin/env bash # 文件路径scripts/quality_gate.sh # 用法在 .git/hooks/pre-commit 中调用此脚本 # 注意团队使用前请根据自身流程调整不要直接作为强制拦截 STAGED_FILES$(git diff --cached --name-only) if [ -z $STAGED_FILES ]; then exit 0 fi # 检查是否有代码文件进入暂存区 if echo $STAGED_FILES | grep -E \.(java|py|ts|js|go)$ /dev/null; then echo echo 检测到本次提交包含代码文件请逐项确认 echo 1. 是否已执行与被修改模块相关的单元测试 echo 2. 是否已搜索过被修改方法的全部调用方 echo 3. 是否检查过本次改动对 API 兼容性的影响 echo 4. 涉及配置项时是否已评估灰度发布方案 echo # 如果团队认为需要强制阻断请取消下面一行的注释 # exit 1 fi这个脚本的思路不是“禁止提交”而是“把提问环节前置”。你可以按团队情况决定是提示还是强制。更成熟的做法是接入 CI在拉取请求上运行风险扫描任务比如检查有没有System.out、有没有硬编码的数据库密码、有没有直接把Exception吞掉的空 catch 块。5.4 把“验收测试”写在使用 AI coding 之前如果你准备让 AI 实现一个较大的功能比较好的顺序是先不急着让它写实现而是先让它帮你补测试或帮助你梳理验收标准。围绕行为写测试的价值在于AI 后续的每一次修改都会受到一组可运行断言的约束而不是只能在对话里凭感觉判断。void shouldRejectOrderWithoutItems() { // 给定一个空白订单 Order order new Order(); // 当保存订单时 // 则抛出 IllegalArgumentException提示至少需要一个商品 assertThatThrownBy(() - orderService.saveOrder(order)) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining(至少需要一个商品); }当这类测试作为修改的“安全网”存在时AI coding 的可靠性会明显提升。它不知道项目的完整业务历史但至少会被一个可运行的行为契约约束住。6. AI coding 在生产环境落地时的实施建议如果你认可上面的方向下面是可以直接落地的实施清单。第一步选择一个合适的试点模块。不要一上来就让 AI Agent 重构核心交易链路。选择内部系统、报表模块、基础 CRUD 接口这类“边界清晰、影响可控”的模块开始积累经验之后再逐步扩大范围。第二步在仓库根目录建立规则文件和任务模板。不管团队用哪个 AI 工具都应该把通用约束沉淀到仓库里。这样无论是个人使用还是团队协作AI 都能读到同样的边界。AGENTS.md 这类文件的价值会随着仓库历史增加而不断变大。第三步统一变更流程。建议团队内部约定纯新增类任务可以让 AI 直接生成修改类任务必须先让 AI 输出影响清单涉及接口签名、数据库、缓存 key 的变更必须经过人工评审涉及资金、权限、消息发送的重度敏感逻辑不建议使用 Agent 自动修改。第四步建立 AI 代码的 Review 专属检查单。传统 Review 关注逻辑正确性AI 代码的 Review 还需要额外关注几个问题这个改动是否引入了与需求无关的修改AI 是否擅自重构了原有代码是否有隐藏的防御逻辑掩盖了上游问题是否新增了不必要的依赖下面这张表可以在团队内部用作 Review 参考。Review 检查点为什么对 AI 代码尤其重要判断方式是否有与需求无关的改动AI 容易顺手“优化”看似不相关的代码查看 diff逐个文件确认修改原因是否新增了隐藏的默认值逻辑默认值可能掩盖上游 Bug搜索 null 判断和空集合返回是否修改了异常类型或错误码调用方等级处理方法可能失效对比修改前后的异常类型是否悄悄升级或增加了依赖依赖变更可能影响构建和运行检查依赖 diff是否引入了重复的工具方法AI 容易在项目已有工具类的情况下另造轮子搜索同功能方法删减的代码是否真的是死代码AI 对“不再被引用”的误判时有发生全局搜索符号引用第五步建立回滚预案。任何 AI Agent 执行的大范围变更提交前都应该确认可以从 Git 历史快速回滚。涉及数据库的变更必须区分“代码回滚”和“数据回滚”不要假设两者同时完成。7. AI coding 失败的常见现象与排查思路结合多个团队使用 AI coding 的实际反馈下面整理了一些典型故障模式的排查思路。注意这里的“排查”不单指代码运行失败更多是指“代码能跑但项目越来越痛苦”这类缓慢失控的症状。现象可能的根因排查方式应对措施AI 生成的代码第一次能跑但过几天无法维护修改时未考虑全部调用方约束查看模块依赖图搜索调用方在规则文件中强制要求“影响清单”同样的问题反复出现每次修复方式不同缺少可运行的行为测试检查是否有针对该逻辑的单元测试先补充验收测试再让 AI 修改AI 修复一个 Bug 引入两个新 Bug上下文窗口无法覆盖完整约束检查最近几次变更范围是否过大把大任务拆成多次小变更分别验证AI 生成的代码格式规范但逻辑错误它对项目的业务规则理解不足人工 Review 中检查需求对应关系增加更具体的业务术语到提示词多个 AI 生成的代码风格互相冲突仓库缺少统一规则文件检查是否已有编码规范文档建立 AGENTS.md 并纳入 Review 标准Code Review 耗时增长了数倍人工评审直接面对 AI 生成代码的“不合理合理”统计每次 PR 的平均评审时长在编码阶段增加方案确认和规则文件约束生产环境出现之前从未有过的数据异常AI 增加了默认值或兼容逻辑检查 diff 中 null 判断和 catch 块禁止 AI 在需求之外添加防御逻辑如果出现以上某种现象不要急着把责任归结为“工具不行”而是回看团队是否让 AI 在一个没有约束的状态下工作。大多数失控发生在约束缺失的时候。8. 一些关于 AI coding 使用边界的个人思路再往深一层说AI coding 给开发团队带来的最大变化不是“写代码效率提升了几倍”而是“工程信息密度的要求被拉高了”。过去人写代码很多隐性知识靠个人经验补齐AI 写代码这些隐性知识必须显式地写下来否则它无法理解。这就是为什么很多资深开发者会感到“心累”他们发现使用 AI 编码后大量的时间不是花在读代码或写代码上而是花在“向 AI 解释代码背后的约束”上。如果约束解释得不够清楚AI 就会做出看似合理、实则偏航的实现。在一两个简单任务里这不是问题但在一整个迭代、一个季度、一个长期项目里这会消耗非常多的精力。为了避免这种消耗我倾向于把 AI 的角色从“替代开发者实现需求”调整为“辅助开发者快速验证想法”。前者要求 AI 理解项目的全部语境后者只要求 AI 在一个人工定义好的、足够小的范围内完成任务。前者适合原型后者适合生产代码。在这个意义上那个宣布“Im done coding with AI”的视频真正的价值不是让你也卸载工具而是它提醒了所有开始依赖 AI coding 的人要重新审视自己的代码中有多少是真正被理解的有多少只是“看起来能运行”。真正可长期维护的代码背后必须有清晰的约束、准确的验收标准和有效的人工评审。这些工作工具不会替你完成但它们才是决定项目能否走下去的关键。9. 总结与下一步实践建议回顾全文我想说的是以下几点。第一AI coding 热潮中出现的“告别”声音不是因为生成代码的能力不够强而是因为“无边界使用 AI”方式生产出来的代码在长期维护中会暴露大量上下文缺失和隐性债务。第二AI coding 的能力边界是有迹可循的。适合它的任务通常具备三个特征上下文闭环、修改影响局部化、有明确的验收标准。反之跨模块重构、核心链路修改、涉及权限和资金的敏感逻辑都需要更严格的人工把控。第三没有必要全盘否定 AI但需要把工程纪律前置在 AI 使用之前。通过 AGENTS.md 固定项目规则通过影响清单确认变更方案通过自动化和人工评审守住质量门禁通过行为测试建立回归安全网。这套流程不依赖特定工具任何团队都可以逐步落地。如果你正在摸索团队内部的 AI coding 规范建议从一件小事开始下一次让 AI 修改跨文件代码之前先要求它输出影响清单和应用方案再允许它动手。同时在仓库里补一个只包含五条硬约束的规则文件。先跑两周再看看代码 Review 的负担和返工次数有没有变化。相关方向还有很多值得延伸的内容比如如何设计更高质量的行为测试让 AI 生成代码可验证如何在架构评审中考虑 AI 生成代码的长期演化以及如何在不增加人工负担的情况下建立更大范围的自动化约束。理解了工具和约束的关系你就不会在“效率神话”和“彻底告别”之间摇摆了。