我写了一份 Cursor 快速入门指南

6,452 阅读10分钟

前言

在第一次使用 Cursor 完成需求开发后,我深受震撼。这种“用自然语言描述需求,直接实现功能”的编程体验,正是我高中第一次接触编程时所憧憬的。然而,Cursor 生成的代码有时显得不够规范,难以维护。对于小型工具,这或许可以接受,但在工程级项目中,这种缺陷就显得尤为突出。

幸运的是,我在阅读官方文档时发现了 RulesNotepads 功能。这两个工具能够有效约束 AI 的行为,使其在实现功能的同时,生成更符合预期的代码。

在实际的项目开发中,我们可以通过制定 Rules 规则来统一项目级的代码风格。这样一来,团队成员在开发时只需专注于需求实现,无需过多担心 AI 生成代码的格式和可维护性问题,从而大幅提升开发效率和代码质量。

以上是一些思考,接下来分享一下一些 Cursor 的用法,大纲如下:

image.png

有其他想要了解的功能可以参考:docs.cursor.com/get-started…

Cursor 介绍

Chat&Composer模式

  • Chat 模式类似于现阶段的 AI 插件,如 MiOne和Marscode等,只是针对用户的 query 提供对应的回答。不会生成或者写入文件,需要用户手动 apply
  • Composer:和 Chat 模式的区别在于,在生成代码以后会自动创建文件或在已有文件中进行编辑。

小Tips:如果不确定 AI 生成的是否正确,则可以点击 Composer 窗口中的 save all 先保存,调试通过后,通过 Accept all 来接受代码

Cursor 上下文

Cursor 提供了 @ 操作符号,它可以唤醒一些指令,其中包含四种上下文。分别为:Code、文件、文件夹和 Codebase

  • Code 表示的一段代码
  • Codebase 表示当前工作区即当前项目代码,可以通过正则选择需要扫描的文件

其优先级为:Code > 文件 > 文件夹 > Codebase

Cursor Git

通过 @git 的语法,你可以获取到最近的几次提交。比如你可以询问:这次提交的变更有哪些?这两次变更有什么差异等。

  • 对比主分支和当前分支的差异,适合于 Review 代码
  • 对于当前没有提交的变更和最新的一次提交之间的差异
  • 生成 Git 提交文案

Cursor Docs

docs.cursor.com/context/@-s…

Cursor 支持通过链接的方式引入一个文档。这个功能非常有用,比如你在做三方对接(如接入 SpringSecurity)的时候,你只需要将文档的链接给它,它就会自动学习这个文档中的内容,后续的对话中就可以通过 @Docs 的方式引用作为本次 query 的上下文。

Cursor 使用

局部对话

通过 Ctrl/Command + K 来唤起局部对话框,此时可以针对选中的代码进行提问

Cursor Normal&Agent

当你在使用 Composer 模式的时候,一定可以发现在点击提交的时候,旁边有一个 Normal 和 Agent 的切换。

两者的区别如下:

  • Agent 模式会自动执行一些命令,如在编写 python 代码的时候,它会自动执行需要安装包的命令。

官方称该模式为:YOLO Mode(You Only Look Once Mode)

Cursor Rules

Cursor Rules 是 Cursor 提供给用户用来约束模型生成的内容的机制。当在使用 AI 时如果不对模型生成内容进行约束,特别的新的项目,就会导致生成的代码千奇百怪,难以维护。因此在实际的项目开发中,需要针对项目配置模型约束。

全局 Rules & Project Rules

  • 全局 Rules。配置全局范围的 Rules,对 AI 行为进行全局约束。
  • Project Rules。可以通过项目目录中创建 .cursorrules 文件来指定,或者在 seeting -> Project Rules 中指定。

全局约束

告知 AI 它的职责和如何去完成它的任务

你是一名资深后端开发专家,精通 Java、Spring、SpringBoot、MyBatis、MyBatisplus、RocketMq以及各种中间件,如:Zookeeper、Nacos、SpringCloud、SpringSecurity等。你思维缜密,能够提供细致入微的答案,并擅长逻辑推理。你会仔细提供准确、事实性、深思熟虑的答案,并且在推理方面堪称天才
- 严格按照用户的需求执行。
- 首先逐步思考——用伪代码详细描述你的构建计划。
- 确认后,再编写代码!
- 始终编写正确、符合最佳实践、遵循 DRY 原则(不要重复自己)、无错误、功能完整且可运行的代码,同时确保代码符合以下列出的 代码实现指南。
- 优先考虑代码的易读性和简洁性,而不是性能。
- 完全实现所有请求的功能。
- 不要留下任何待办事项、占位符或缺失的部分。
- 确保代码完整!彻底验证最终结果。
- 简洁明了,尽量减少其他描述。
- 如果你认为可能没有正确答案,请明确说明。
- 如果你不知道答案,请直接说明,而不是猜测。
- **注意:尽量使用已经存在的目录,而不是自建目录**
- 你需要严格按照 cursorrules 中的内容来生成代码,不要遗漏任何内容

编码环境

说明当前项目所使用的技术栈

## 编码环境
用户询问以下编程语言相关的问题:
- Java
- Spring&SpringBoot&SpringSecurity
- MyBatis&MybatisPlus
- RocketMq
- Nacos
- Maven
- SpringSecurity

代码实现指南

说明当前项目具体的代码如何实现,比如 DB 的创建表的规范,用户上下文怎么获取、项目结构的含义等。

1. 项目使用 DDD 的方式来实现代码,你需要注意如下几点:
  1. 领域层和仓库层的入参都要使用 DO、仓库层的实体对象需要添加 PO 的后缀
  2. Application或者Service层的输出必须的 DTO,接口层的返回可以是 DTO 也可以自己定义 VO
  3. 每一层对应的对象都需要添加对应的后缀,并且后缀要全大写。如仓库层的实体 UserPO,领域层领域 UserDO,应用层的DTO UserDTO
  4. 项目的类之间的转换需要使用 MapStruct 来完成
2. 在使用三方依赖的时候,需要将对应的依赖内容先添加到 maven 依赖中
3. 所有的接口都按照 RestFul 的风格定义,并且你需要区分接口的使用场景,如:前端使用、OpenApi、小程序端使用。
  1. 如果你无法通过用户的上下文知道需要你生成的接口的使用场景,你可以再次询问用户
  2. 前端统一前缀使用 /api/fe/v1/xxxxx,OpenApi 使用 /api/open/v1/xxxx,小程序使用 /mini-program/v1/xxxx并且三个入口的文件需要区分不同的文件夹
  3. 对于批量查询接口,你需要涉及分页的能力,不能使用内存分页,只能在 DB 层面做分页,并且要考虑深分页的问题
  4.  所有的接口返回需要返回 BaseResp 对象,BaseResp 的定义如下:
  @Data
  public class BaseResp<T> {
      private String code;
      private String message;
      private T data;
  }
  4. 对于应用层,需要注意如下几点:
      1. 函数的输入和输出都是 DTO

历史记录

由于每次使用 AI 生成代码,于是我让 AI 帮我将每一次 Query 后的结论进行总结并记录到文件中。提示词如下:

## 历史记录
1. 针对你回答用户问题的答案,你需要将本次回答的内容记录到项目的根路径下的 .cursor-history 文件里,格式如下:
2025-11-11 10:10:10
变更内容如下:
1. 增加用户模块
2. 修改用户管理内容
3. 增加用户内容
涉及文件为:
xxxx.java
xxxx.java
2. 你需要按照倒序的方式记录这个历史纪录

可以发现:rules 文件中做的事情就是:约束模型行为,规范它的输出

项目开发者可以自行在文件中定义自己项目的规则,引导 AI 产出的内容更加的符合自己的预期。

但需要注意的一点是:尽量不要写太多的内容到 cursorrules 文件中,内容太多的话,AI 不会全部理解,而是会做后续内容的截断。

如果需要写更多的内容的话,可以参考下述 notepads 的能力来完成。

Cursor notepads

在使用 .cursorrules 时有一个问题,你无法去引用一个文件。需要将文件内容复制到 .cursorrules 中,但规则文件越大模型处理效果越不好,因此为了解决这个问题,Cursor 提供了一个 notepads 的工具。通过 .cursorrules 完成的均可以通过 notepads 完成。

文件附件:可以附加文档和参考文件(.cursorrules 不支持)。

你可以定义当前项目所使用到的项目的结构说明、代码模板,然后通过 @ 在 Chat 或者 Composer 中使用。

常见的一些使用案例:

  • 动态样板生成:创建常见代码模式的模板,存储项目特定的脚手架规则,保持团队代码结构的一致性。
  • 架构文档:前端规范、后端设计模式、数据模型文档、系统架构指南。
  • 开发指南:编码标准、项目特定规则、最佳实践、团队约定。

数据库规范

- 你需要根据用户的输入来推断可能使用到的表的结构,并按照如下的格式生成。
- 其中 create_time、update_time、create_user、update_user 是必须拥有的字段。
- ext和is_deleted可以根据用户的需求来选择添加
- 对于唯一索引,其需要同一个前缀为 ux_,如:ux_business_key_type;对于非唯一索引,需要同一个前缀为 idx_,如:idx_business_key_type
CREATE TABLE `user_audit` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户日志ID',
`business_key` varchar(100) NOT NULL DEFAULT '' COMMENT '业务实体ID或索引,如用户名',
`operator` varchar(64) NOT NULL DEFAULT '0' COMMENT '操作人',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '版本号',
`ext` json DEFAULT NULL COMMENT '扩展属性',
`is_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '是否删除0为未删除,1为删除',
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
`create_user` varchar(32) NOT NULL DEFAULT '' COMMENT '创建人',
`update_user` varchar(32) NOT NULL DEFAULT '' COMMENT '更新人',
PRIMARY KEY (`id`),
KEY `idx_business_key_type` (`business_key`,`operate_type`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='用户审计表'

远程调用开发代码模板

 # 远程调用开发规范
## HTTP 远程调用
对于远程调用层,需要注意如下几点:
  1. 你需要使用 @HttpExchange 的能力来完成远程调用,并且让项目中的第三方配置收口到同一个配置节点下。示例如下:
@HttpExchange
public interface IntentRemoteClient {
    
    @PostExchange(value = "/api/open/agent/intent")
    BaseResp<IntentResponse> recognizeIntent(
        @RequestBody IntentRequest request
    );
}

@Data
@ConfigurationProperties(prefix = "api")
public class ApiProperties {
    /**
     * 应用依赖的外部服务的配置, 这些外部服务使用 MiPaaS 认证中心提供的认证
     */
    @Valid
    @NotEmpty
    private Map<String, ExternalService> external;

    /**
     * 外部服务配置
     */
    @Data
    public static class ExternalService {
        /**
         * 服务 API 的基础 URL
         */
        @NotBlank
        @URL
        private String baseUrl;
        /**
         * 对一些配置的覆写
         */
        private ExternalServicePropertiesOverrides overrides;
    }

    /**
     * 认证使用不同的 URL 和 认证凭据的配置
     */
    @Getter
    @AllArgsConstructor
    public static class ExternalServicePropertiesOverrides {
        private String authServiceBaseUrl;
        private ClientCredential clientCredential;
    }

    @Getter
    @AllArgsConstructor
    public static class ClientCredential {
        private String appId;
        private String appSecret;
    }
} 

@Configuration
@EnableConfigurationProperties(ApiProperties.class)
public class RestApiConfig {

    private final Map<String, ApiProperties.ExternalService> services;

    public RestApiConfig(ApiProperties appProperties) {
        this.services = appProperties.getExternal();
    }
    
    @Bean
    public IntentRemoteClient intentRemoteClient() {
        // 1. 获取服务对应的配置
        var svc = findServiceConfiguration("intent");
        // 2. 构建 Client
        var httpClient = HttpClient.create()
          .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
          .wiretap(true)
          .responseTimeout(Duration.ofSeconds(10));
        var client = WebClient.builder()
          .baseUrl(svc.getBaseUrl())
          .codecs(clientCodecConfigurer -> clientCodecConfigurer.defaultCodecs().maxInMemorySize(50 * 1024 * 1024))
          .clientConnector(new ReactorClientHttpConnector(httpClient))
          .filter(new AuthorizationAuthFilter(svc.getOverrides().getClientCredential().getAppId(),
            svc.getOverrides().getClientCredential().getAppSecret(), svc.getBaseUrl()))
          .build();
        var factory = HttpServiceProxyFactory.builderFor(WebClientAdapter.create(client)).build();

        return factory.createClient(IntentRemoteClient.class);
    }

    /**
     * 生成服务配置
     *
     * @param name 服务名称
     * @return ExternalService
     */
    @NotNull
    private ApiProperties.ExternalService findServiceConfiguration(@NotNull String name) {
        var svc = services.get(name);
        if (svc == null) {
            throw new IllegalArgumentException("no such service");
        }
        return svc;
    }
} 

基于 notepads 你可以在项目中创建每一个领域的约束和模板,来让 AI 学习。在实际的开发中可以配合 cursorrules 和 notepads 一起使用。