用 AI 写代码,真正拖慢进度的是这 4 个坑

举报
yd_225040342 发表于 2026/11/01 22:31:35 2026/11/01
【摘要】 用 AI 写代码,真正拖慢进度的是这 4 个坑摘要:AI 编码助手能把"从 0 到 1"的速度拉满,但返工、审查和线上问题的成本只是被转移了。本文复盘一次订单服务改造中踩到的 4 个坑,并给出可落地的约束规则和代码示例。 背景最近给订单服务加一个"批量取消"接口:入参是订单 ID 列表,逐单校验状态、释放库存、写取消记录,要求幂等。需求不复杂,我基本把编码工作交给了 AI 编码助手,人只做...

用 AI 写代码,真正拖慢进度的是这 4 个坑

摘要:AI 编码助手能把"从 0 到 1"的速度拉满,但返工、审查和线上问题的成本只是被转移了。本文复盘一次订单服务改造中踩到的 4 个坑,并给出可落地的约束规则和代码示例。

背景

最近给订单服务加一个"批量取消"接口:入参是订单 ID 列表,逐单校验状态、释放库存、写取消记录,要求幂等。需求不复杂,我基本把编码工作交给了 AI 编码助手,人只做方案确认和代码审查。

结果是:功能按时上线,但中间返工了四轮。这四轮不是模型"不会写",而是四类很典型的问题。记下来,供同样在用 AI 编码的同学参考。

坑一:API 和依赖版本是"编"出来的

AI 第一版直接给了这样一行:

// 编译不通过:OrderRepository 没有定义这个方法
List<Order> orders = orderRepository.findCancelableOrdersByIds(ids, OrderStatus.PAID);

方法名看着很"Spring Data",但 Cancelable 不是实体属性,无法由方法名派生,项目里也没有自定义实现。同一轮里它还建议升级一个并不存在的 starter 版本。

原因:模型不知道你的 pom.xml 里是什么版本,也不清楚仓库里已经有哪些方法,只能按"最常见写法"猜。

做法:

  1. 任务开始先让它读 pom.xml、相关 Repository 接口和已有实现,再动手;
  2. 在规则里明确:不确定的 API 必须先检索仓库和官方文档,不许凭印象生成;
  3. 把"编译通过"设为硬门槛,编译不过的代码不进 review。

上面的需求,正确写法是基于已有方法组合:

List<Order> orders = orderRepository.findAllById(ids).stream()
        .filter(o -> o.getStatus() == OrderStatus.PAID)
        .toList();

坑二:上下文一长,项目约定就丢了

前几轮生成的 DTO 用的是 record,到第五轮新加的类又变回了 Lombok @Data;异常处理也是一半返回 Result<T>,一半直接抛异常。

原因:对话上下文不等于项目上下文。聊到后面,早期说过的约定早被挤出窗口了,模型只能按默认习惯写。

做法:把约定从"对话里说过"变成"仓库里写着"。我们在项目根目录放了一份规则文件,让助手每次任务都先读:

## 编码约定
- DTO 统一使用 record,禁止 Lombok @Data
- Controller 统一返回 Result<T>;业务异常抛 BizException,由全局异常处理器转换
- 日志使用 slf4j 占位符,禁止字符串拼接
- 新增公共方法必须配单测,分支覆盖率不低于 80%
- 不允许跨层调用:Controller 不得直接依赖 Mapper

另外两个习惯很有效:每次任务开头让它复述一遍本次要遵守的约束;大任务拆成"接口定义 → 实现 → 测试"几个小任务,避免一次性生成几百行。

规则文件也有维护成本,别写成一份规范文档。控制在二十行以内,只写"违反了就会返工"的硬约定,比如 DTO 风格、返回结构、异常出口、分层边界。写得太全,模型记不住,人也懒得更新,最后又会退化回对话里的口头约定。

坑三:AI 写的测试"全绿",但边界根本没测

它给批量取消写了一个单测,测的是"PAID 订单可以取消",跑通了。但重复取消、已发货订单、部分 ID 不存在这三种情况一个都没覆盖。更麻烦的是,测试把仓储层全 mock 了,mock 的返回值恰好就是代码期望的值——测试永远通过。

原因:AI 倾向于证明"代码能跑",而不是证明"代码正确"。

做法:

  1. 先写验收条件,再让它按条件生成测试,而不是让它自由发挥;
  2. 明确要求输出"未覆盖分支清单",人来判断哪些必须补;
  3. 关键路径别全 mock,用真实数据库或容器化测试;
  4. 让它自己跑测试,把失败日志贴回来再改。

还要注意,覆盖率数字本身并不可信。AI 很容易写出"执行了但没断言"的测试:方法调了、对象建了、最后没有任何 assert,覆盖率照样上涨。审查测试时先看断言,再看覆盖率。

补完后的参数化测试大致是这样:

@ParameterizedTest
@EnumSource(value = OrderStatus.class, names = {"SHIPPED", "COMPLETED"})
void shouldRejectCancelWhenStatusNotCancelable(OrderStatus status) {
    Order order = OrderFixture.withStatus(status);
    assertThrows(BizException.class, () -> cancelService.cancel(order.getId()));
}

@Test
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。