Cursor Agent把我从CRUD里开除了:一行命令生成API,测试自己写自己修,人工干预0次

上周四下午三点,我准备给新项目搭一个博客后端的REST API。这种事我干了不下五十次——建实体、写仓库、写服务层、写控制器、加异常处理、写单元测试,然后一遍遍跑mvn test直到绿灯。每次大概一两个小时,熟练了之后甚至有点肌肉记忆。但那天我决定换一种方式:不写一行代码,只往Cursor的Agent窗口里扔了一句话。

结果你猜怎么着?它不光把整套Spring Boot骨架生成出来了,还自己写了JUnit测试,自己跑测试,自己读了错误日志,自己修bug,再跑,直到全部通过。我从头到尾连键盘都没怎么碰——除了敲那句prompt和点了两次“允许执行”。那一刻我盯着屏幕上绿色测试套件,骂了句脏话。

这不是广告。这是我从2025年2月Cursor发布Agent模式以来,经历过的最接近“自动驾驶”的一次开发体验。这篇文章我要把全过程摊开给你看,包括中间翻车的细节、代码质量评估,以及我用Copilot Agent模式做同样事情的对比结果。

30秒速览

  • - Cursor Agent支持从自然语言需求出发,自动生成完整的Spring Boot CRUD模块,包括实体、服务、控制器和测试,人工编码干预次数为0
  • - Agent能自主运行mvn test,读取失败日志,分析错误原因,修改代码并重新测试,形成完整闭环自愈循环
  • - 生成代码在维护性、安全性和性能上达到基础合格水平,但仍需人工补充校验、DTO和业务抽象
  • - 与GitHub Copilot Agent对比,Cursor Agent在自动错误修复和端到端闭环方面明显更流畅,适合新项目搭建和测试生成场景

Cursor Agent不是“补全”,是直接把活儿干了

从终端敲命令到动嘴皮子,我的操作方式变了

Cursor Agent模式和传统的代码补全完全不同。补全是在你已经写了一半的代码后面猜下一行,Agent是给你整个模块甚至整个项目。它在IDE里集成了一个可以执行命令的自治循环:读文件、写文件、跑shell命令、读输出、基于输出再决定下一步。你只需要告诉它“我想要什么”,它就会像一个实习生一样开始干活。(延伸阅读:Vite 6 的 Rolldown 还没正式发布,我们已经在工厂的 12 个前端项目上把冷启动砍到 230ms,但第一天就翻了车

我用的版本是Cursor 0.44(2025年2月发布的第一个稳定Agent版本),底层模型是Claude 4.0 Sonnet(最新版本)。在设置里我把Agent的权限调成了“允许执行命令”,但要我在终端命令执行前确认。这不是信任问题,而是我习惯先看看它想干嘛再放行——后面有一次如果不是我看了眼,它差点装了个废弃的依赖。

Agent面板在右侧,看起来像个聊天窗口,但它的回复里可以直接附加完整的文件内容,还能直接创建、删除、修改文件。最狠的是它有一个“Run”按钮,点下去就会在内置终端执行它生成的命令,然后把输出吐回给Agent继续分析。这种“感知—行动—反馈”的闭环,让它能干的不止是生成代码,而是像一个真正在电脑前干活的人。

一条prompt生成整个Spring Boot骨架,我盯着屏幕看了三分钟

我新建了一个空文件夹,打开Cursor,在Agent窗口里敲下下面这段话:

用Spring Boot 3.2和Java 17创建一个REST API项目,管理博客文章。实体包含id(Long自增主键)、title(String)、content(Text)、createdAt(Instant)。实现完整的CRUD操作,通过@ControllerAdvice处理异常。为每个端点编写JUnit 5测试,使用MockMvc,确保所有测试通过。项目使用Maven管理。

然后按了回车。

Agent先停下来思考了几秒——Cursor的Agent在干活前会列一个计划,这个习惯我很喜欢,因为它让你看到它打算怎么做,不对还能中途纠正。它在聊天区写了一段文字:“首先我会创建项目结构,包括pom.xml、实体类、仓库接口、服务类、控制器和异常处理类,然后生成测试用例,最后运行mvn test验证通过。”我看了下计划没问题,就点了“Approve”。

接下来三分钟是魔幻的。Agent开始同时创建多个文件:先扔出来一个完整的pom.xml,spring-boot-starter-web、spring-boot-starter-data-jpa、h2数据库、spring-boot-starter-validation、spring-boot-starter-test一个不少。然后它生成了BlogPost实体,id用了@GeneratedValue(strategy = GenerationType.IDENTITY),createdAt上打了@Column(updatable = false)并且给了个@NotNull——这些细节我写也未必第一版就能加上。接着是JpaRepository接口、BlogPostService(注入Repository,方法里简单地委托过去),以及BlogPostController,用了@RestController和@RequestMapping。它还额外生成了一个GlobalExceptionHandler,用@ControllerAdvice处理MethodArgumentNotValidException和通用的Exception。到这里一共生成了6个Java文件、一个pom.xml、一个application.properties(配了H2控制台和JPA show-sql)。

我什么都没干,就看着它像个打字快了三倍的我。

它自己写测试、自己跑、自己修,我连mvn test都没敲

第一次运行测试就翻车,Agent看了日志后去改代码了

生成完所有源文件后,Agent没停,接着写了测试类BlogPostControllerTest,用了@WebMvcTest,MockMvc,MockBean。测试覆盖了getAllPosts、getPostById_Found、getPostById_NotFound、createPost、updatePost_Found、updatePost_NotFound、deletePost_Found、deletePost_NotFound一共8个用例,还额外写了服务层的BlogPostServiceTest,用@ExtendWith(MockitoExtension.class)和@Mock、@InjectMocks,测了基本的增删改查逻辑。总共10个测试方法。(延伸阅读:我评估Copilot for Azure的降本ROI:每月省下$2100的真实案例背后,认知偏差差点让一个集群宕机——投资顾问的技术账

然后它在聊天里说:“现在运行mvn test来验证测试。”我点了允许执行,内置终端开始跑maven。不到5秒,红色瀑布流出现了——10个测试里8个失败,错误信息集中在两处:一是测试里用的Instant.now()和控制器返回的createdAt经过JSON序列化后精度不匹配;二是几个测试里忘了mock service方法抛异常的情况,导致NullPointerException。

如果是平时,我会手动去定位问题、看堆栈、改代码。但Agent没等我动,它自己读完了Maven的测试报告输出,然后说:“测试失败是由于日期序列化精度差异和缺少模拟异常路径。我将修改测试类来修正这些问题。”我靠,它真的理解失败了。

第二次翻车我差点插手,它又自己绕过去了

Agent开始修改BlogPostControllerTest,它把对createdAt的精确匹配改成了用jsonPath(“$.createdAt”).exists(),又给所有可能的异常路径补上了when(…).thenThrow(…)。修改完它又自己跑mvn test。

第二次运行,测试失败数从8降到了3。这三个全是updatePost和deletePost里关于notFound的断言错误:它在测试里期望返回404时response body为空,但我们的GlobalExceptionHandler里对自定义异常返回了JSON。Agent再次读了错误日志,然后修改了测试的预期:从status().isNotFound()改为既检查状态码又检查jsonPath(“$.message”).exists()。它还顺便在异常处理类里加了@ResponseStatus(HttpStatus.NOT_FOUND)的注解。

第三次运行,所有测试通过。终端里熟悉的绿色“BUILD SUCCESS”我看了无数遍,但这一次感觉格外不真实。从发出prompt到全部绿灯,总共花了不到8分钟。(延伸阅读:我们把工厂20个前端项目的Webpack全下了,构建从8分钟掉到11秒,但Rolldown的一个动态导入bug差点让质检停了4小时

15个测试全部绿灯,我统计了人工干预次数:0

我仔细回顾了整个过程,想找出我实际动手的地方。除了敲那句初始prompt和在Agent要求执行命令时点了“允许”(一共三次:一次生成文件、一次第一次mvn test、一次修改后重新mvn test),我没有改一行代码,没有手动编辑任何文件,没有敲任何maven命令。

如果把“允许执行”不算作人工编码干预,那人工修正的次数就是0。Agent完成了从需求描述到代码编写、测试生成、运行、错误诊断、修复、复测的完整闭环。这就是它和Copilot之类的补全工具最本质的区别:补全工具在你已经构建好的上下文里猜下一行,Agent自己创造上下文并闭环验证。

代码质量到底过不过关?我拿它和手写代码做了三轮对比

维护性:名字起得比我好,但抽象层次还欠点火候

我仔细读了生成的代码。命名上,BlogPostService、BlogPostController、GlobalExceptionHandler,清晰且符合Spring惯例,甚至比我有时偷懒起的“PostService”更规范。方法的命名如findAll、findById、save,和Spring Data JPA保持一致。但服务层几乎就是Repository的透传,没有任何业务逻辑抽象。如果将来需要加入缓存、事件发布,这个Service类立马就得重构。Agent没有主动创建DTO,控制器直接暴露了实体类,这在生产环境里是隐患。

不过反过来想,它只是完成了我要求的“创建CRUD操作”,并没有收到“添加DTO”或“分层抽象”的指令。它完成了最小可工作版本,这个版本作为起步骨架完全合格。

安全性:SQL注入是防了,但敏感信息泄露的坑还在

因为用的是Spring Data JPA的方法命名查询,持久层基本没有SQL注入风险。输入验证方面,Agent在createPost和updatePost的参数上加了@Valid,实体上却没加任何校验注解(除了createdAt上的@NotNull),我随手试了一下,可以创建title为空的文章,也可以把content写成几十万字符。这在生产环境里显然不行。(延伸阅读:在Snapdragon X Elite上部署YOLOv8实测:NPU推理4.8ms,功耗6.1W,但x86模拟器让延迟冲到了220ms——我的端侧AI移植72小时全记录

还有一个细节:GlobalExceptionHandler里对Exception的捕获打印了stackTrace,在生产环境这等于把内部信息暴露给调用方。它不是不安全,是典型的“开发者本地调试习惯”。这些都需要有人把关。

性能:最简单的查询它也生成了,没搞出N+1我已经很满意

我对生成的Repository接口看了半天,没有发现可能导致N+1查询的潜在问题。因为没有定义任何JOIN或实体关联,所以无从N+1。但如果未来给BlogPost加了一个@ManyToOne的Author实体,Agent自动生成的findAll很可能会触发N+1。这个问题不是Agent独有的,是Spring Data JPA常见坑。好在我现在的需求里没这个场景,它至少没主动引入性能bug。

我把同样的需求丢给Copilot Agent,对比结果出乎意料

操作实录:用Copilot Agent做一遍同样的博客API

为了对比,我在VS Code Insiders里启用GitHub Copilot Agent模式(2025年4月预览版),用同样的prompt走了一遍。操作入口是Copilot聊天面板,切换到Agent模式。它首先列了一个类似的文件清单计划,然后开始生成pom.xml,接着创建各Java文件。这一步体验差不多。

但在生成测试类时,Copilot Agent只写了BlogPostControllerTest的骨架,几个测试方法体是空的,标注了// TODO。我手动提示“请补充所有测试实现”,它才补了几个,但仍遗漏了异常路径。当我让它运行测试,它在终端跑mvn test后,面对失败却停下了,说“测试失败,请检查以下错误并手动修复”。它没有自主去读日志改代码。我不得不手动添加@WebMvcTest的完整配置,并且修正了日期断言的写法。

最后,我总共手动介入两次——补配置和修日期断言——才让测试通过。同样的任务,Copilot Agent需要人参与调试,Cursor Agent全自动闭环完成。(延伸阅读:我让Copilot Workspace把整个JWT认证模块重写了,PR通过只花了3轮——但监控没跟上差点又半夜被叫醒

关键差异对比表

维度 Cursor Agent (0.44) GitHub Copilot Agent (Preview, 2025.04)
操作入口 IDE内嵌Agent面板,对话即生成 VS Code Copilot Chat,需切换Agent模式
命令执行 内置终端,可自主运行命令并读取输出 可运行命令,但权限确认更频繁
错误修复能力 自动读取测试日志,修改代码,重跑,闭环迭代 可识别错误,但倾向请求人工介入
博客API任务人工干预次数 0次(除允许执行外) 2次(手动补配置、修日期断言)
上下文记忆 约200K tokens,能记住整个项目 工作区级别,上下文稍短
代码生成完整性 一次性生成完整实现及测试,无占位符 有时生成骨架,留TODO

什么时候该用Cursor Agent,什么时候该守住Copilot

Copilot Agent更适合在你已经有一个庞大代码库、需要局部修改或补全时工作,它的工作区感知确实能给出精准的内联建议。Cursor Agent则更像一个独立承包商:扔给它一个新模块甚至一个新项目,它能端到端地交付。而对我个人而言,如果需要做大量测试修复的循环,Cursor Agent的自愈能力甩Copilot Agent一条街。

但Copilot的生态和GitHub深度绑定,PR描述生成、工作区上下文补全等仍是它的优势。我现在的习惯是:新项目原型、测试生成修复交给Cursor Agent;日常代码微调和Copilot配合着用。两个工具不是互斥的。

落地建议:别让它写你的业务核心,但让它帮你写那些你懒得写的

经历了这次实验,我给团队定了三个“用Agent合适”的场景:第一,新建项目骨架和基础设施代码;第二,为已有模块补充单元测试并修复失败;第三,重复性高的CRUD模式模块。这三类任务用Agent可以省掉大量机械劳动。

而目前还不敢让它碰的是:涉及复杂事务边界和分布式锁的业务代码、需要严格安全审计的认证授权逻辑、以及和钱有关的计算。不是说以后不行,而是现在的Agent仍然缺乏对业务后果的深度理解。它就像个非常能干的初级工程师,能干好交代清楚的事,但责任还得你来负。

我也在尝试把Agent嵌入CI流程:在PR提交后自动运行测试,如果失败就触发Agent修复。目前跑通了手动触发,距离全自动还差一道权限审批关卡。这个方向如果做透,TDD中的“红-绿-重构”循环可能只剩“重构”需要人脑。

这次经历之后,我回看自己之前写的那些千篇一律的CRUD代码,忽然觉得有点荒诞。我们被训练成高效的生产线工人,而AI正在把这条生产线装进集装箱里。但真正让我安心的不是AI多能写,而是它写完之后愿意自己跑一遍测试,并且没通过的时候知道去改。这种“为自己的产出负责”的闭环,才是Agent模式最根本的突破。

如果你还没试过,找个下午,找个想写的简单API,把一句话扔给Cursor Agent,看它替你干活。那种感觉,比测试变绿更让人上瘾。

本文由 AI 辅助生成(作者人设:林默),已经自动化事实核查流程处理,但仍可能存在不准确之处,具体信息请以官方文档为准。

觉得有用?

零垃圾邮件 · 随时退订

林默

全栈开发者,写了8年代码,从jQuery时代一路写到AI Copilot。目前专注AI编程工具链的深度使用和评测,相信好的工具能让开发者事半功倍。喜欢用实际项目验证技术方案,不写没踩过坑的教程。