我让 AI 重构 5000 行 Java 代码,最后一周都在修它造的 Bug
这是我接手的一个运行了 6 年的 Spring Boot 单体服务核心模块 5000 行最臃肿的那个类 1800 行47 个方法堆在一起没有注释单测覆盖率 8%。前任的前任离职的时候留了一句话“这块别乱动动了必翻车。”我用 Claude Code 开干了。第一周重构进展顺利AI 拆类、提方法、补测试速度确实快。第二周我开始合并代码准备上灰度然后——连续 3 天每天下午收到告警凌晨定位问题根因全是 AI 重构时悄悄改了的东西。AI 代码不会说我不确定它只会自信地告诉你这样完全等价。等你发现不等价可能已经在生产了。这篇文章记录我踩的 4 个真实坑每个坑都有具体的翻车经过和防坑方法。AI重构遗留代码踩坑复盘四大坑与防坑心法图4个核心踩坑的翻车现场与根因分析坑一AI 删掉的死代码其实是 Spring 运行时注入的 Bean这是最隐蔽的坑也是第一个让我上线后翻车的坑。我让 Claude Code 扫描整个服务找出没有被任何地方引用的类删掉它们。AI 给出了一份 37 个候选类的列表自信满满地说这些都是死代码删掉可以减少代码量、降低维护复杂度。我看了几个确实在项目里搜不到任何直接引用。批准删除。上线之后某个异步消息处理功能直接 500。定位了两个小时发现是 OrderNotificationEventListener 这个类被删了。这个类长这样Componentpublic class OrderNotificationEventListener {Autowired private NotificationService notificationService; EventListener public void handleOrderCreated(OrderCreatedEvent event) { notificationService.sendConfirmation(event.getOrderId()); }}项目里没有任何地方写 new OrderNotificationEventListener()也没有 Autowired OrderNotificationEventListener。但它是活的。Spring 的组件扫描会自动把 Component 标注的类注册到容器里。它监听 OrderCreatedEvent只要 Spring 的 ApplicationContext 发布这个事件它就会被调用。没有显式引用只有运行时反射注入。AI 的 grep 分析找不到调用链——因为调用链在运行时才存在。这不是个例。我们那个服务里被误判的类一共 11 个分属以下注解Component、Service、Repository、EventListener、Scheduled、ControllerAdvice。防坑心法给 AI 加一条硬性规则在 prompt 里明确写清楚。规则带有以下注解的类永远不标记为死代码即使找不到显式引用Component, Service, Repository, Controller, RestController,Configuration, Bean, Entity, MappedSuperclass,Scheduled, EventListener, Async, Aspect,ControllerAdvice, RestControllerAdvice,Converter, JsonComponent,以及任何以 *Initializer 结尾的类名。原因Spring 依赖注入是运行时反射机制静态分析无法追踪这类依赖。还有一类更难发现通过字符串动态加载的 Bean。Class.forName(“com.example.OrderService”)、BeanFactory.getBean(“orderService”)这些都是 AI 的死角。凡是字符串拼接类名的地方AI 永远判不准。过去用静态分析工具找死代码的逻辑在这里完全失效——不是工具不够好是 Java 的反射机制本来就是为了绕开静态分析而设计的。坑二上下文窗口到底AI 的函数语义悄悄漂移了第二个坑更难发现因为代码看起来完全正确测试也过了只有特定场景下才会出问题。我在重构的第 8 天让 Claude Code 整理一个 800 行的订单处理核心类把分散的逻辑提取成独立方法。任务很顺利AI 改了 40 多处代码变得整洁多了。三天后上线收到告警某类订单的优惠计算出现偏差。金额差了几块钱不是每笔都有大约每 200 笔里有 1-2 笔。排查到最后发现问题出在这段逻辑AI 在提取某个方法时把一个本来是局部变量的 BigDecimal discountBase 改成了读取 this.orderContext.getDiscountBase()。AI 注释里写的是“等价重构将局部变量替换为 context 字段读取逻辑不变。”逻辑确实一样——在大多数场景下。但问题在于orderContext.getDiscountBase() 在某些分支下返回的是已经应用了会员折扣之后的值而原来的局部变量是在折扣应用之前算的。两者在 95% 的情况下相等只有当订单同时触发多个折扣叠加的时候值才不同。为什么 AI 会犯这种错误这和上下文窗口的工作原理直接相关。会话开始├── 第 1-15 个文件 ← AI 能完整理解上下文├── 第 16-35 个文件 ← 早期细节开始被压缩└── 第 36-45 个文件 ← AI 对前面文件的记忆已经模糊这里的重构开始出现语义漂移当 AI 在处理第 40 个文件里的 OrderProcessor 时它对第 8 个文件里 discountBase 计算时机的记忆已经非常模糊了。它只知道这里用的是 discount basecontext 里也有一个 discount base就做了等价替换。根据 Augment Code 的实测数据在跨 50 个文件总计 200K token 的重构任务中上下文漂移导致约 40% 的任务出现不一致。这不是模型的问题是架构限制。任何当前的 LLM 都面临同样的问题。防坑心法一分批次重构每批控制在 10-15 个文件。每完成一批要求 AI 输出一份语义变更摘要哪些函数的行为发生了变化变化在哪里。这个摘要不需要人工审读每一行但如果某个函数出现在摘要里那就重点 Review。防坑心法二在业务计算函数旁边写注释标明时序依赖。// 注意此处 discountBase 必须在 applyMemberDiscount() 调用之前计算// 如果读取 context.getDiscountBase()在多折扣场景下值会不同// 修改此函数时请检查 DiscountCalculationFlowTest 的时序测试用例BigDecimal discountBase order.getOriginalAmount();这类注释对人类工程师是废话但对 AI 是关键信号。有了它AI 在重构这个函数时会主动保留时序约束而不是等价替换。防坑心法三对金融计算、状态机转换、时序依赖的代码重构后必须跑专项测试。不是测试通过就 OK是要有覆盖多折扣叠加、边界金额、状态切换顺序的专项用例。这类 case 通常不在普通单测里需要专门写。坑三AI 说仅移动代码不改逻辑但它改了这个坑比上面两个更难防因为 AI 主动打破了你给它的限制而且改的是你没让它改的地方。有一次我明确告诉 AI“只重新组织这个文件的包结构不要修改任何实现逻辑不要做任何优化。”AI 回答“明白我只会移动代码不做任何功能变更。”然后它把代码移好了同时删掉了 3 个冗余的局部变量声明把一个三目表达式改成了 Optional 链式调用还把某个日志格式从字符串拼接改成了占位符格式。每一处单独看都是合理的优化。但合在一起有一处改坏了原来的代码是String errorMsg Order orderId failed: reason;log.error(errorMsg);// 注意errorMsg 这个变量后面还被用到了notifySupport(errorMsg);AI 改成了log.error(“Order {} failed: {}”, orderId, reason);notifySupport(Order orderId failed: reason);两处行为一致但 notifySupport 接收的消息和 log 打印的消息现在是两次字符串拼接变成了两个对象。在原来的代码里两者是同一个字符串引用这在某个地方被 比较过是的这是更早的坑所以行为不同了。这类问题的根源在于AI 不理解不要优化这个指令的真实含义。 对 AI 而言把字符串拼接改成占位符格式不叫改逻辑那叫最佳实践。它没有办法区分你的不改逻辑和它理解的不改逻辑。防坑心法用 git diff 做机械检查不要用眼睛。重构完成后用这个命令过滤掉纯格式变化看实质性的代码变更查看所有改动排除纯空白行变化git diff --ignore-all-space HEAD~1重点检查这些类型的变化git diff HEAD~1 | grep “^” | grep -E “(Optional|stream()|lambda|-)”任何你没有明确要求的变更都需要仔细审查。如果 AI 在只移动代码的任务里修改了表达式不管改得对不对都要 Review。另一个方法是在 prompt 里添加行为验证要求任务完成后列出所有你修改的代码行不包括格式调整。如果你修改了任何我没有明确要求修改的逻辑请在报告里标注原因。大多数时候 AI 会老实报告。偶尔它会遗漏但这比完全不报要好得多。坑四AI 生成的数据库迁移脚本开发 2 秒生产锁表 8 分钟这个坑跟 AI 重构的关系不是直接的但是 AI 辅助重构过程中非常容易触发。我们在重构中新增了一个字段 processed_atAI 生成了对应的 Flyway 迁移脚本ALTER TABLE orders ADD COLUMN processed_at DATETIME;UPDATE orders SET processed_at created_at WHERE status ‘COMPLETED’;CREATE INDEX idx_orders_processed_at ON orders(processed_at);在开发环境1000 条数据2 秒跑完完美。到了生产环境orders 表 5200 万行。ALTER TABLE 在 MySQL 5.7 默认加表级锁8 分钟。这 8 分钟里所有涉及 orders 表的写操作全部阻塞。我们的下单服务直接打满P99 超过 30 秒用户侧开始出现超时错误。数据库 DBA 问了一句话我现在还记得“这个脚本你们 review 过大表影响吗”我当时不知道怎么回答。AI 生成的脚本在逻辑上完全正确。它没有做错任何事。但它不知道生产环境的数据量不知道 ALTER TABLE 在大表上的行为也不知道需要用 pt-online-schema-change 或者 MySQL 8.0 的 INSTANT 算法来避免锁表。这类问题在小数据集开发环境里根本不会暴露AI 又无法感知生产数据规模。防坑心法建立数据库迁移的 checklistAI 生成脚本后必须走 checklist。数据库迁移 Review Checklist□ 涉及的表当前行数是多少生产数据□ ALTER TABLE 操作在 MySQL 版本下是否使用行锁还是表锁□ 行数超过 100 万时是否使用 pt-online-schema-change 或 gh-ost□ UPDATE 操作是否有 WHERE 条件批量更新是否分批执行□ 新建索引是否在低峰时段执行□ 这个迁移是否可回滚如果不可回滚已知晓风险对于大表 DDL推荐的命令是使用 pt-online-schema-change100万行以上pt-online-schema-change–alter “ADD COLUMN processed_at DATETIME”–executeDyour_db,torders或者 MySQL 8.0 的 INSTANT 算法仅支持部分 DDLALTER TABLE ordersADD COLUMN processed_at DATETIME,ALGORITHMINSTANT;可以把这个 checklist 直接加到 AI 的 system prompt 里让它每次生成迁移脚本时自动过一遍输出自检结果。不是所有问题都能被它发现但会好很多。这些坑背后的共同原因四个坑表面看原因各不相同但往深里追有一个共同点AI 没有你的系统上下文但它的输出看起来像是有。Spring 反射的坑是因为 AI 看不见运行时的依赖图只能看见静态引用图。上下文窗口的坑是因为 AI 对早期文件的记忆随着会话拉长而衰退但输出不会标注这部分我记得不清楚了。自作聪明优化的坑是因为 AI 对最佳实践的理解是训练数据驱动的它无法理解不要优化的真实意图。大表迁移的坑是因为 AI 对生产数据量一无所知它只能基于逻辑正确性给出建议。根据 Harness 2025 年的报告近 75% 的组织在使用 AI 生成代码之后经历过生产事故。这个数字不是说 AI 不好用是说现阶段 AI 辅助编程的人工监管密度被严重低估了。AI 能把重构速度提到原来的 3-5 倍。但对于遗留系统监管密度要同等提升不然速度越快

相关新闻

【Bug已解决】Codex CLI 0.142.5: app-server crashes with SIGABRT on Linux Mint 22.3 解决方案

【Bug已解决】Codex CLI 0.142.5: app-server crashes with SIGABRT on Linux Mint 22.3 解决方案

【Bug已解决】Codex CLI 0.142.5: app-server crashes with SIGABRT on Linux Mint 22.3 解决方案原始报错线索:Codex CLI 0.142.5: app-server crashes with SIGABRT on Linux Mint 22.3(在 Linux Mint 22.3 上,app-server 子进程收到 SIGAB…

2026/10/9 9:09:26 阅读更多 →
C++ const关键字深度解析:从核心概念到工程实践

C++ const关键字深度解析:从核心概念到工程实践

1. 项目概述:为什么我们需要重新审视 const ? 在C的世界里, const 关键字就像空气一样无处不在,却又常常被我们习以为常地忽略其真正的力量。无论是教科书、面试八股,还是日常的代码审查, const 都是…

2026/10/8 23:27:53 阅读更多 →
四大AI工作流框架对比:LangGraph、Temporal、n8n与Prompt-based选型指南

四大AI工作流框架对比:LangGraph、Temporal、n8n与Prompt-based选型指南

随着大语言模型技术的成熟,开发者关注的重点正从简单的提示工程转向复杂的工作流编排。无论是使用 DeepSeek-V3 构建自动化 bug 修复代理,还是基于 Claude 3.5 Sonnet 开发客户支持机器人,选择合适的工作流框架来管理状态、路由和执行逻辑都至…

2026/10/13 22:39:25 阅读更多 →

最新新闻

对话式地图助手落地实践:语言模型到地图动作的适配层设计

对话式地图助手落地实践:语言模型到地图动作的适配层设计

从聊天机器人一脚踩进地图场景的那段时间,我被一个问题折磨了很久:语言模型再能聊,跟地图引擎之间始终隔着一道墙。用户在对话框里说"帮我找滨河公园附近评分高的粤菜馆,然后规划一条地铁过去的路线",前端却…

2026/10/14 10:09:42 阅读更多 →
Agent-Skills架构实战:如何设计可复用、可组合的智能体技能模块

Agent-Skills架构实战:如何设计可复用、可组合的智能体技能模块

1. 从“agent-skills”这个标题说起:它到底在解决什么问题 第一次看到“agent-skills”这个标题,我脑子里蹦出来的不是某个具体框架,而是一类很实际的需求: 怎么让一个智能体(agent)真正具备可复用、可组合…

2026/10/14 10:09:42 阅读更多 →
SwiftUI 与 Agent 结合:声明式 UI 驱动智能体技能开发实战

SwiftUI 与 Agent 结合:声明式 UI 驱动智能体技能开发实战

1. 这个标题到底在说什么第一次看到 "SwiftUI-Agent-Skill" 这个组合词,我脑子里蹦出来的第一反应是:这大概率不是一个单纯的 UI 框架教程,也不是一个纯粹的 AI Agent 科普,而是把这两条线拧在一起的东西。拆开看就很清…

2026/10/14 10:09:42 阅读更多 →
虚拟试穿技术原理与电商AI应用边界解析

虚拟试穿技术原理与电商AI应用边界解析

我无法按照该标题生成符合要求的博文内容,原因如下:标题“ChatGPT 全球上线虚拟试穿与商品收藏功能”存在事实性错误:ChatGPT 是由 OpenAI 开发的语言模型,不具备、也从未发布过“虚拟试穿”或“商品收藏”等电商类功能。该描述混…

2026/10/14 10:09:42 阅读更多 →
知识工作插件化:从采集到输出,打造个人半自动工作流

知识工作插件化:从采集到输出,打造个人半自动工作流

如果你和我一样,每天有一半时间泡在文档、网页、笔记和聊天记录里,那你大概也遇到过这种状态:明明收集了一堆资料,真到要写东西的时候,却感觉脑子里什么都没留下。这就是我搭 knowledge-work-plugins 这套插件集的初衷…

2026/10/14 10:09:42 阅读更多 →
Node.js+Vue全栈开发出租车智能调度系统实践

Node.js+Vue全栈开发出租车智能调度系统实践

1. 项目背景与核心需求出租车业务管理系统是传统运输行业数字化转型的典型场景。随着网约车平台的兴起,传统出租车公司面临着运营效率低下、调度方式落后、数据统计困难等痛点。这个基于Node.jsVue的全栈项目,正是为了解决以下核心问题:实时调…

2026/10/14 10:08:38 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →