从一段订单分页查询接口,看两种 AI 编程范式
最近同时用 Codex 和 Cursor 实现了同一个需求:订单分页查询接口,GET/api/orders?pageNum=1&pageSize=10&status=PAID,要求返回分页数据、参数校验、单元测试,技术栈 Spring Boot + MyBatis-Plus。同样的任务跑下来,两者的差异比想象中更大——不是谁更好的问题,而是根本不同的工作逻辑。
需求理解:目标拆解 vs 实时感知
Codex 的做法是「先问清楚,再动手」。
我把需求丢进去,它不会立刻生成代码,而是先反问:确认一下,分页参数是用 pageNum/pageSize 还是 offset/limit?status 枚举值有哪些?是否需要联表查询?这一圈确认下来,相当于帮我做了一遍需求澄清。随后它自动生成一个任务清单:创建 Controller → 编写 Service 接口 → 实现 Mapper 分页 → 参数校验注解 → 单元测试。每一步打勾完成,像个项目助理。
Cursor 则完全相反,「你边写,它边猜」。
我打开项目的OrderController.java,刚敲出@GetMapping("/orders"),Cursor 的灰色虚影已经补全了整段分页逻辑,包括Page<Order>的泛型推断。它不需要我「提交需求」,而是从我当前光标位置、周边代码结构、甚至隔壁文件的OrderService定义里,实时推断我要什么。这种伴随感很强,但代价是:如果项目里已有三套分页封装,Cursor 可能猜错我用哪套。
核心差异在这里:Codex 把需求理解做成显式对话,Cursor 把它变成隐式预测。前者适合需求本身还在变的场景,后者适合「我知道要干嘛,帮我快点写完」的流畅状态。
代码生成:交付完整产物 vs 行内渐进式编辑
Codex 生成代码后,呈现的是一个完整的 Diff 视图。我能看到它新建了哪些文件、修改了哪些行、删除了什么。更关键的是,它把代码放到云端沙箱里跑了一遍,告诉我:编译通过,单元测试 4 个全部绿灯,但有一个边界 case 没覆盖——pageNum 传 0 时的行为未定义。这种「先验收,再合入」的体验,让我敢直接让它改生产代码。
Cursor 的编辑体验则细腻得多。它不会一次性甩给我一整个文件,而是在当前光标处给出行内建议,按 Tab 接受、按 Esc 忽略。我可以让它「把这里的分页逻辑抽成公共方法」,它会精准地在当前函数内部重构,不影响其他文件。但这也意味着,多文件联动时需要我手动导航:改完 Controller 还要自己去 Service 层看看它有没有同步建议。
一个有趣的对比:Codex 生成完代码会问「要自动提交到 Git 吗」;Cursor 则在我保存文件的瞬间,默默把变更标在左侧 gutter 栏里,等我自己决定什么时候 commit。
多文件联动:任务委托 vs 人机协作
这个订单接口涉及到 5 个文件的改动:Controller、Service、Mapper、DTO、Test。Codex 的处理方式是全托管:它自己规划文件依赖顺序,先改 DTO 定义,再动 Mapper,最后补 Controller,全程不需要我切换标签页。甚至它还会顺手把application.yml里的分页插件配置检查一遍,发现我没配pagehelper.helper-dialect=mysql,主动补上。
Cursor 在多文件场景下则更像高级副驾。我可以在聊天框里输入「给这个接口加上分页查询」,它会列出需要改的文件清单,但每改一个文件都要我确认。好处是我随时能打断、调整方向;坏处是文件一多,上下文切换的 cognitive load 明显上升。而且它不会自动去碰application.yml这种「看起来不相关」的配置——除非我明确指出来。
这里能看出来两者的设计哲学分野:Codex 假设开发者愿意授权,它来做完整的上下文管理;Cursor 假设开发者保持掌控,AI 只在被请求时介入。
审查与调试:事后复盘 vs 即时反馈
Codex 的审查环节让我印象深刻。代码生成后,它提供一个可交互的 Diff 面板,我可以逐行质疑:为什么这里用Page<OrderVO>而不是Page<OrderDTO>?它会解释设计考量,并在我坚持时重新生成。配合codex-devtools这类工具,我还能回溯它调用了哪些文件、消耗了多少 Token、哪一步决策导致了某个 bug。这种可观测性对团队沉淀很重要——我能把「Codex 为什么这样改」写成文档,给新人参考。
Cursor 的审查更轻量。它的行内 diff让我一眼看出改了什么,但深度有限。优势在于即时纠错:我写完orderService.page(new Page<>(pageNum, pageSize)),Cursor 立刻提示Page构造参数顺序在 MyBatis-Plus 新版本里变了,建议调换。这种编码过程中的实时纠偏,比事后审查更省时间。
工作流定位:什么时候用谁
跑完这个接口,我对两者的分工有了清晰体感。
Codex 适合的场景:需求相对明确、需要跨模块改动的「任务包」。比如「把订单模块从单表查询改成支持多条件筛选分页」,这种涉及 Controller、Service、Mapper、甚至前端联调的全流程任务,交给 Codex 一次性出结果,我去做验收和微调。它的价值在于减少任务切换成本,让我从「写代码」切换到「审代码」。
Cursor 适合的场景:日常编码的「流状态」。我在已有代码库里修 bug、补逻辑、做重构时,Cursor 的实时补全和行内建议让我不用离开键盘就能完成大部分工作。特别是处理「这里加个参数校验」「那边补个异常处理」这类碎片化需求时,它的伴随感无可替代。
两者并非互斥。我现在的用法是:用 Codex 做架构级任务委托——生成项目骨架、编写完整接口、做跨模块重构;用 Cursor 做编码级伴随——日常 CRUD、局部优化、快速修 bug。Codex 像外包团队,交需求、等交付、做验收;Cursor 像结对编程的搭档,坐旁边随时搭把手。
最终那个订单分页接口,Codex 版本花了 8 分钟从需求到可运行,Cursor 版本我边写边调用了 15 分钟,但后者我在过程中学到了 MyBatis-Plus 分页的一个新特性。时间不是唯一指标,注意力分配方式才是选择的关键。