背景:Spring Boot + MyBatis Plus,个人项目,用Cursor的Chat模式和Agent模式写了快三个月。一开始确实爽,CRUD基本不用动脑,但最近改需求时发现一个问题:它生成的Service层逻辑越来越绕,很多地方为了“兼容”我之前的代码,会额外塞一些没必要的判断和状态流转。我试着让它重构,结果它又基于现有代码“自洽”地改,反而把一些原本清晰的接口搞复杂了。
用Cursor写后端三个月,感觉代码越来越难维护了怎么办?
全部回复
共 97 条跟你的情况挺像的,我用了两个月后发现它特别擅长在旧逻辑上打补丁,而不是推倒重来。后来我学乖了,让它改代码前先写清楚这段逻辑的输入输出和边界条件,再限制它只能动指定方法,不然它真能把简单事整成迷宫。另外建议给关键Service写点测试用例,重构完跑一遍,不然它自洽起来你根本不知道哪里断了。我现在的做法是每周抽一天纯手工review,AI生成的代码一旦超过三层嵌套就直接拆,别心疼。
这题我太有体会了,跟你几乎一模一样的路径。我自己的感觉是,Cursor这类工具最大的坑不是它写错,而是它太会“顺着你”了,你之前代码里哪怕有个隐性的坏味道,它也会当成某种规范去继承和放大,最后生成那种“看着能跑但没人敢动”的意大利面。你让它重构,它其实是在做局部优化,根本没有全局视角去推翻自己之前的决策,所以越改越拧巴。我的建议是,你得主动给它划边界,比如核心的Service层状态机或者业务流转,务必自己手写或者用伪代码把逻辑框死,只让AI去填那些真正机械的CRUD和DTO转换。另外,每过一两周就强制做一次“删代码练习”,把那些为了兼容而加的判断全砍了,再让AI从干净版本重新生成,反而比反复重构有效。说到底,工具越强,我们自己越得守住那个“什么该让渡、什么必须掌控”的底线,不然代码腐化的速度会比你手动写还快。
同感,AI生成代码最大的坑就是“上下文污染”——它为了迁就之前写的不合理结构,反而把新逻辑也带歪了。我后来基本只让它写单元级别的代码,Service层拆流程还是自己手动控制,不然最后重构的成本比手写还高。另外你可以试试在Prompt里强制它“忽略旧代码风格,按最简方案重写”,有时候比让它自己改管用。
我也有类似的体感,AI写代码最怕的就是它把“能跑”当成“设计得好”,为了兼容旧逻辑疯狂叠条件,最后代码变成一团乱麻。你试试让它重构的时候,别给整块代码,而是拆成小函数一个个改,并且明确告诉它不要保留历史包袱,这样会干净很多。另外维护阶段我基本只用它补测试和写文档,业务逻辑还是自己手写更可控。
同感,AI写代码最大的问题不是写不出来,而是它会把你过去的烂设计当成feature来维护,越补越臃肿。我后来干脆定期让它按当前需求重写某个模块,而不是让它增量改,反而清爽很多。你试试把Service层拆细点,明确告诉它不要兼容旧逻辑,只按新接口走,效果会好不少。另外关键流程建议自己手写,别全扔给Agent。
三个月正是项目开始变味的阶段,其实就算人写也容易这样,只不过AI更擅长一本正经地制造混乱。我觉得你可以考虑给它一个“逆向约束”,比如明确禁止在某些方法里加状态判断,或者直接开个新分支让它从零生成,再手动merge,比让它自己重构靠谱。想知道你那些“自洽”的改动,是不是也喜欢自己发明一些不必要的抽象?
这情况我倒觉得不全是Cursor的锅,个人项目前期爽完后期还债太正常了。不过它确实有个毛病,就是会为了通过编译和符合上下文,硬把逻辑塞进已有结构里。我的做法是隔段时间就逼自己手动读一遍核心Service,把那些AI加的“安全网”删掉,删完代码量能少三分之一。你有试过让它先画个调用流程图再动手改吗?
试试让它只改你圈出的那一段,别给全局上下文,ai一“贴心”就容易过度设计。
AI生成的代码得定期人工review,不然三个月后你就是在给它的历史债打工。
这情况太真实了,cursor写多了确实会陷入“代码自洽”的怪圈,它重构的时候优先考虑的是不破坏现有逻辑,而不是让设计更简洁。我后来都是让它按“最小改动”来,然后自己定期手动抽公共方法,把那些多余的状态流转砍掉,AI生成的代码当参考,别真当主力。你有没有试过在prompt里明确禁止它加防御性判断?我试了还挺管用的。
同感,我用了两个月就发现这问题了。Cursor生成代码时特别执着于“最小改动”,结果就是往老代码里硬塞新逻辑,条件判断叠了一层又一层。我的办法是每周末抽时间手动重构关键Service,把AI写的那些防御性分支砍掉,恢复成线性流程,宁可让它下周再重新生成也不要留着这种自洽的复杂度。
我最近也在用类似的AI工具写Go后端,遇到的情况跟你几乎一模一样。前期生成代码确实快,但到了第三个月,你会发现它特别爱做“防御性设计”,为了不破坏已有逻辑,会叠出很多层状态判断,其实很多根本走不到。我后来想明白一个事儿,AI它没有“重构会越改越乱”的直觉,它只会基于当前代码库做局部最优解,所以你要给它画一条清晰的边界线,比如直接说“这个模块只保留三个方法,其他全删”,不然它永远在打补丁。还有一个比较笨但有效的办法,就是定期把某几个关键Service文件全部清空,从接口定义开始重新生成,别让它老看着那堆历史包袱。另外,你或许可以试试在Prompt里强制要求它先写单元测试再写实现,这能逼着它把逻辑理直,不然测试根本过不了。说实话,到后期我反而觉得,AI工具更适合用来写一次性脚本或者新模块的骨架,维护核心业务逻辑还是得自己上手改,至少关键路径要能一眼看穿。你现在是个人项目还好,要是以后跟别人协作,这种“自洽”的代码真的会让队友崩溃。
我最近也有类似的感觉,AI写代码就像滚雪球,前期爽是因为没历史包袱,后期它为了不破坏现有逻辑,就会疯狂打补丁。我后来干脆把某个模块的核心Service彻底推翻重写,只把AI当高级补全用,效果反而好很多。你可以试试阶段性让它做“代码审计”,而不是直接重构,或者隔段时间就手动梳理下状态机,不然真成屎山了。
这情况太真实了,AI生成的代码就像滚雪球,越滚越乱,关键它自己还觉得挺合理。
建议你试试让它先写设计文档,再写代码,不然重构就是原地兜圈子。
同感,AI生成的代码在简单CRUD阶段确实效率拉满,但一旦业务逻辑复杂起来,它倾向于“打补丁式”地兼容历史代码,导致调用链越来越绕。我后来干脆用Cursor做单文件级别的生成,跨模块的架构和接口设计自己手动写,这样AI只负责填实现,不碰调用关系,维护负担小很多。你那个重构问题,试试把需求拆成最小步骤,分多次让它改,每次只给一个明确约束,比一次性说“帮我优化”靠谱。
我这边也踩过类似坑,后来发现让AI写代码前得先给它立规矩,比如在项目里写个约定文档,明确service层不准出现状态机判断,复杂逻辑必须拆独立方法。它生成的时候会参考这些规则,代码干净不少。不过说实话,三个月个人项目到这个阶段,手动接管核心模块可能是最省心的,AI留着写测试和搬砖就行。
你这情况我熟,Cursor特别喜欢在旧代码上加新逻辑,不去动原有结构,结果就是层层嵌套。我现在的办法是定期让它解释一遍整体流程,一旦它自己都说不清楚就果断推倒重写那一段,别心疼。另外,把MyBatis Plus的复杂查询尽量挪到Mapper层用注解或XML写,别让service层去拼条件,会好维护很多。
说实话这情况太典型了,我自己的项目也踩过类似的坑。Cursor写CRUD确实快,但它会默认把之前生成过的东西当成“遗产”来维护,结果就是代码越叠越厚,逻辑绕得跟迷宫似的。我后来学乖了,每过两周就手动把Service层拆一遍,把那些没用的状态判断直接删掉,别指望它自己重构,它只会让代码更“自洽”地烂下去。另外你可以试试给它更明确的边界指令,比如告诉它只改某几个方法,别让它碰整体结构,不然它总想“发挥”一下。
同感,Cursor这玩意儿写CRUD是真快,但代码一多起来,它那个“基于现有代码自洽”的毛病就特别明显,动不动就给你套个状态机或者守卫条件。我后来是硬性规定,凡是它生成的Service层逻辑,必须自己过一遍,把那些为了兼容历史代码的“屎山”分支全拆掉,只留最直接的路径,重构的时候干脆把上下文清空让它重写,别给旧代码当参考。
这个问题我太有共鸣了,Cursor写新代码确实快,但改老代码的时候它总喜欢顺着现有逻辑往下堆,越堆越乱。我的经验是别让它直接重构,先自己把要改的那块手动理一遍,把没用的分支删干净,再让它基于干净的版本写。或者干脆新开一个对话,只贴核心接口和实体,让它从零给你一版,对比着抄。不然它永远在旧代码的坑里自我循环。
这问题我太熟了,Cursor写CRUD确实爽,但service层一旦超过两三个业务分支就开始失控。我后来发现根因是它每次都是基于当前代码“局部最优”去改,而不是站在整体架构上重新想。你让它重构,它只会把已有的烂逻辑换个姿势摆整齐,根本不敢删东西。我的做法是定期把某个模块的service整个丢给它,但要求它先输出一份纯业务描述,不许看现有代码,然后再拿这份描述去对照重构。另外MyBatis Plus本身就容易让人偷懒,wrapper嵌套多了连自己都看不懂,我现在强制自己超过三个条件就抽成独立方法。还有个小技巧,每次改需求前先手动把要动的接口注释掉,让它从零写一遍,而不是在旧逻辑上打补丁。说白了AI适合从零生成,不适合在熵增的代码上做减法,减法还得自己来。
这问题挺典型的,我后来是逼着自己先手写一版接口和状态流转,再让AI只补实现,不然它老爱顺着旧逻辑叠补丁。重构前最好先让它把现有Service画成流程说明,人看一遍砍掉多余分支,不然等于让它在烂地基上装修。