背景:五年经验的Java后端,最近团队引入Copilot和通义灵码,我也算重度用户。但三个月下来,我发现自己写的代码越来越“飘”——比如为了应付CR,让AI生成了一堆看似完整的DTO和工具类,但很多字段根本用不到;重构老模块时,AI直接给了一套全新的设计模式,我照着粘了,结果线上出了两个NPE,回滚了才修好。
用AI编程工具三个月,代码质量反而下降了,是我的姿势不对吗?
全部回复
共 68 条跟你感觉差不多,我用了半年Copilot,最明显的问题是它太会“顺着你写了”。你心里没想清楚,它就给个看似合理的方案,代码量上去了,但逻辑漏洞反而藏得更深。建议把AI当结对编程的实习生,必须让它解释每个设计决策,不然就自己重写关键部分。
AI生成的代码最大的坑就是“表面完整”,它不会告诉你哪些字段是冗余的,也不会考虑你现有的上下文。我现在只让它写测试和重复性CRUD,核心逻辑全手写,代码审查时间反而缩短了。
我觉得问题不在工具,在于你把设计权交出去了。重构老模块这种高风险活,AI给的是“理想化方案”,根本不了解你系统的边界条件。不如让它做候选方案参考,自己先画出调用链和异常路径,再动手改。
我有个土办法,让AI生成代码后,强制自己把所有不认识的API都查一遍文档。如果它用了某个设计模式,就追问它“为什么不用更简单的写法”。这么搞了俩月,代码质量回来了,还顺便逼自己学了不少新东西。
你提到NPE我太有体会了,AI特别喜欢假设输入不为空。我现在给它写提示词都会加一句“请考虑所有空指针和异常场景”,但说实话,关键路径还是自己写try-catch更放心。工具是加速器,不是方向盘。
说实话你这情况我太熟了,我自己用copilot半年,最深的感受就是它像个特别会写八股文的实习生,你问什么它都能给你一套工整但未必合适的答案。你提到CR那点我特别有共鸣,现在组里review代码经常变成看AI有没有把字段命名统一,而不是看这行代码到底为什么要存在。我觉得问题可能出在咱们把“生成代码”和“设计代码”搞混了,AI擅长的是把局部逻辑补完,但让它直接给重构方案,它根本不懂你那个模块的历史包袱和隐式约定。我现在的做法是,先自己把接口、边界条件和异常路径想清楚,再用AI去填充那些重复的getter/setter或者模板方法,这样它产出的东西至少是受控的。另外你提到NPE那个事,我猜是AI用了Optional或者新的流式写法,但你老代码里可能有些地方允许null传递,这种上下文它压根感知不到。说白了,工具没问题,是咱们得把它当高级自动补全,而不是架构师。你有没有试过在prompt里强制它基于你现有的包结构和命名风格来生成?我之前加了这句之后,返工率低了不少。
我觉得问题可能不在AI,在于你把它当成了“代码生成器”而不是“结对编程伙伴”。之前我也这样,后来强迫自己先写清楚接口和关键逻辑,再让AI补实现,CR的时候反而能理直气壮说清楚每行代码的用途。你那个重构案例,大概率是没给AI足够的业务上下文,它只能按“最标准”的套路来,NPE反而说明你该先做测试用例再动手。建议你把AI的产出当“初稿”,强制自己过一遍删掉无效代码,质量应该能回来。
这个坑我也踩过,说白了就是AI给的代码看着都对,但你脑子里没走一遍逻辑,出问题根本不知道从哪查。我后来给自己定了个规矩:AI生成的东西,凡是涉及业务逻辑和边界条件的,必须自己重写一遍,哪怕只是改改变量名。DTO那种纯体力活可以让它来,设计模式这种它给的建议只能当参考,真敢直接粘上线,NPE算轻的。
我跟你情况挺像的,也是用AI生成一堆看着很规范的代码,结果review的时候自己都说不清某些设计为啥这么写。后来我逼自己改了个习惯:AI给的方案先别急着粘,让它解释一遍,能说服我再动手。重构那种老模块尤其要小心,AI不懂你们线上的历史包袱,它给的"最佳实践"可能直接踩坑。现在我把AI当草稿机用,核心逻辑还是自己写,效率没降多少,但心里踏实多了。
我也有类似感觉,但后来发现锅不在工具,在于我让它替我“想”了。AI补全的DTO和工具类看着齐整,其实没经过业务推敲,字段冗余就是信号。重构那块更得小心,它给的设计模式再漂亮,也得自己顺着调用链走一遍,空指针往往藏在它没看到的边界里。我现在只让它干重复劳动,核心逻辑还是自己写,效率没降,质量也稳住了。
AI给的代码我都是先读懂再改,直接粘迟早踩坑,你这还算轻的。
AI给的代码得像review别人的PR一样较真,不然坑都是自己填。