Cursor进阶使用
Table of Contents
本文深入分析Cursor AI编程助手的高级使用技巧,从Context管理到Rules设计,从场景选择到性能优化,帮助开发者充分发挥AI编程的潜力。适合有一定Cursor使用经验的开发者阅读。
一、Context管理
1.1 主动构建Context
很多时候AI理解不准确,根本原因是看到的Context不对。
被动方式(低效):
用户:实现一个用户查询接口
AI:好的(只能看到当前文件和Rules)
结果:代码风格可能和项目不一致,需要多轮修改
主动方式(高效):
Step 1: 先让AI理解架构
用户:分析app/fbs/inbound模块的架构设计,重点关注分层结构和数据流转
Step 2: 提供参考实现
用户:参考 @app/fbs/inbound/access/http/handler.go 中的 QueryOperationIRList 方法,
实现类似的用户查询接口
Step 3: 明确复用点
用户:检查 app/fbs/inbound/domain/defines/ 目录,复用已有的数据结构
效果对比:
- 被动方式:3-5轮对话
- 主动方式:1-2轮生成高质量代码
1.2 最小必要集原则
反直觉的发现:Context不是越多越好。
添加20个相关文件 vs 只添加3-5个最相关文件:
- 前者:生成时间长,可能混淆不同文件的逻辑
- 后者:生成速度快,质量更高
选择策略:
| 类型 | 是否添加 | 说明 |
|---|---|---|
| 接口定义 | ✅ 必须 | 清楚输入输出 |
| 参考实现 | ✅ 必须 | 了解代码风格 |
| 数据模型 | ✅ 必须 | 知道用什么结构 |
| 依赖模块 | ⚠️ 可选 | 只在跨模块调用时添加 |
| 工具函数 | ⚠️ 可选 | 只在需要特定功能时添加 |
| 测试文件 | ❌ 不需要 | 除非在写测试 |
| 配置文件 | ❌ 不需要 | 除非涉及配置逻辑 |
二、Composer vs Chat
2.1 核心差异
Chat模式:
- 快速对话,轻量级修改
- 一次只能操作少量文件
- 适合:单文件修改、代码解释、快速调试
Composer模式:
- 多文件协同,任务规划
- 有任务规划能力,能自动拆解步骤
- 适合:新功能开发、跨文件重构、复杂逻辑实现
2.2 场景选择
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 修改单个方法的逻辑 | Chat | 改动范围小,Chat响应更快 |
| 实现完整的CRUD接口 | Composer | 涉及Handler/Domain/Repo多层 |
| 跨模块数据结构统一 | Composer | 需要修改多个文件,保证一致性 |
| 理解一段复杂代码 | Chat | 只是理解,不需要生成代码 |
操作建议:
- Chat:选中代码 +
Cmd+K,直接描述需求 - Composer:描述完整需求,让它规划步骤并执行
2.3 Composer任务分解
普通用法:
用户:实现用户管理模块
AI:(一次性生成所有代码,容易出错)
进阶用法:
用户:实现用户管理模块,分3个阶段:
Phase 1: 数据模型和Repo层
Phase 2: Domain层业务逻辑
Phase 3: HTTP Handler接入层
每个阶段完成后等我确认再进行下一阶段
AI:好的,现在开始Phase 1...
(等你Review并确认后)
AI:收到,开始Phase 2...
好处:
- 每个阶段可以验证
- 出问题容易定位
- 可以随时调整后续计划
三、Rules设计原则
3.1 从文档思维到接口思维
很多人把.cursorrules当成文档来写,但应该当成**“AI的编程接口”**来设计。
文档式写法(描述性,AI可能理解不准确):
## 错误处理
我们项目使用errcode包处理错误。
错误应该用errcode.WithMessagef包装。
要提供上下文信息。
示例:
if err != nil {
return errcode.WithMessagef(err, "failed to process order %s", orderID)
}
接口式写法(指令性,明确告诉AI做什么):
## 错误处理规范
【强制】所有错误必须用errcode包装
- 使用:errcode.WithMessagef(err, "context: %v", param)
- 禁止:直接返回err
【检查点】
1. 错误信息必须包含:操作+关键参数
2. 敏感信息(密码、token)不能出现在错误信息中
【反例】
❌ return err // 缺少上下文
❌ return errcode.WithMessagef(err, "error") // 信息不足
【正例】
✅ return errcode.WithMessagef(err, "failed to query user, userID: %s", userID)
关键区别:
- 文档式:描述"是什么"
- 接口式:明确"做什么"和"不做什么"
3.2 分级策略
问题:一个.cursorrules文件太长(几千行),AI可能看不完,或者token限制导致截断。
解决:分级设计,让AI优先看到最重要的规则。
# .cursorrules (核心规则)
## 🔴 L0: 强制规则(必须遵守,否则代码无法运行)
- 所有方法参数必须被使用(会导致编译警告)
- HTTP Response Body必须关闭
- 数据库操作必须使用ORM
## 🟡 L1: 重要规则(应该遵守,影响代码质量)
- 错误必须用errcode包装,提供上下文信息
- 遵循DDD分层架构(Handler → Domain → Repo)
- 避免重复定义数据结构,优先复用已有定义
## 🟢 L2: 建议规则(最佳实践,提高可维护性)
- 方法入参用结构体,出参用指针
- 复杂条件判断封装为函数
- 使用卫语句避免深层嵌套
---
## 📚 详细规范(需要时查阅)
详细内容见:docs/coding-standards.md
效果:
- AI优先看到最重要的规则
- 即使Rules被截断,核心部分也能保留
- 分级清晰,容易理解优先级
3.3 Rules优化建议
1. 控制篇幅
- 核心规则控制在1000行以内
- 详细文档放
docs/目录,Rules中引用链接
2. 使用反例+正例
- 不只是描述规则,要给出具体示例
- 反例让AI知道"不能这样做"
- 正例让AI知道"应该这样做"
3. 定期优化
- 发现AI频繁违反某个规则 → 说明规则不够清晰,需要改写
- 某个规则从未被违反 → 可能是废话,可以删除
- 新的常见错误 → 添加到Rules中
四、Cursor擅长的场景
4.1 代码考古:快速理解遗留代码
传统方式:
- 自己读代码,一层层追踪调用链
- 可能要花几个小时才能理解完整流程
Cursor方式:
Step 1: 生成时序图
提示词:分析这个接口的完整调用链路,用Mermaid时序图展示,
重点标注:
1. 跨领域调用(如 inbound → asn → common)
2. 外部系统交互(数据库、RPC、HTTP)
3. 异步任务节点
[粘贴Handler方法代码]
Step 2: 生成数据流图
提示词:展示这个功能的数据流转过程,从HTTP请求到数据库操作,
标注每一步的数据转换
Step 3: 提取核心逻辑
提示词:总结这个功能的:
1. 3个核心业务逻辑
2. 2个关键的边界条件处理
3. 1个需要注意的坑点
效果:
- 时间:从几小时 → 15分钟
- 理解更全面(可视化呈现)
- 可以作为文档留存
4.2 批量重构:数据结构统一
典型场景:发现3个模块重复定义了相同的数据结构(如OperationIRListReq),需要统一。
传统方式(风险高):
1. 全局搜索所有定义
2. 确定标准定义位置
3. 手动修改每个引用
4. 逐个编译验证
风险:容易遗漏,可能引入bug
Cursor方式(更安全):
Step 1: 分析现状
提示词:扫描项目中所有包含"OperationIRListReq"的文件,
列出:
1. 定义位置(哪些文件定义了这个结构体)
2. 引用关系(哪些地方在使用)
3. 字段差异(不同定义间有什么区别)
Step 2: 设计方案
提示词:设计统一方案:
1. 应该保留哪个定义?(考虑架构分层、依赖方向)
2. 如何迁移其他引用?
3. 影响范围和风险点
Step 3: 分模块迁移
提示词:先迁移main_page模块,将其对OperationIRListReq的引用
改为使用 inbound/domain/defines 中的定义
(迁移完后编译验证)
提示词:继续迁移asn模块...
Step 4: 清理重复定义
提示词:删除所有重复的OperationIRListReq定义,只保留标准定义
效果:
- 时间:从1-2天 → 2-3小时
- 更安全:编译期验证,遗漏率接近0
- 可追溯:有完整的重构记录
4.3 测试补充:智能生成边界测试
痛点:单测覆盖率不够,需要补充测试。
普通做法(覆盖不全):
提示词:为这个方法写单元测试
结果:AI只生成一个基本的happy path测试
进阶做法(全面覆盖):
Step 1: 分析代码路径
提示词:分析这个方法的所有代码分支,列出需要测试的场景,包括:
1. 正常流程
2. 边界条件(空输入、空列表、最大值、最小值)
3. 错误场景(数据库错误、依赖服务失败、参数校验失败)
[粘贴方法代码]
AI输出示例:
需要测试的场景:
1. 正常流程:有效输入 → 正确输出
2. 边界条件:
- 空输入
- 空列表
- PageSize = 0
- PageSize > 1000
3. 错误场景:
- 数据库查询失败
- UserID不存在
- 权限不足
Step 2: 逐个生成测试
提示词:为"空输入"场景生成测试用例,要求:
1. 使用gomonkey mock依赖
2. 验证返回的错误类型
3. 测试方法命名:TestMethodName_EmptyInput
Step 3: 验证覆盖率
go test -cover ./path/to/package/
# 检查是否覆盖到目标代码行
效果:
- 覆盖率从60% → 85%+
- 测试质量更高(考虑了边界条件)
- 过程中可能发现潜在bug
4.4 CRUD接口快速开发
这是Cursor最擅长的场景,也是提效最明显的场景。
传统方式(费时费力):
1. 打开YApi,复制接口文档内容
2. 打开Confluence,复制技术设计文档
3. 找到类似的接口实现,手动对比理解
4. 开始写代码:
- 定义Request/Response结构体
- 实现Repo层数据库查询
- 实现Domain层业务逻辑
- 实现Handler层HTTP接入
5. 来回切换文档和IDE,确保实现符合要求
6. 编译、调试、修改
时间:4-6小时
风险:可能遗漏文档细节,代码风格不一致
Cursor方式(文档驱动开发):
提示词模板:
根据以下资料实现SKU池列表查询接口:
【YApi接口文档】
- yapi url: https://apidoc.i.ssc.shopeemobile.com/project/xxx/interface/api/xxx
(Cursor会通过MCP自动读取)
【技术设计文档】
- Confluence链接: https://confluence.shopee.io/pages/xxx
(Cursor会通过MCP自动读取)
【参考实现】
- 文件:app/fbs/inbound/access/http/handler.go
- 方法:QueryOperationIRList
【开发要求】
1. 检查并复用 inbound/domain/defines 中已有的数据结构(避免重复定义)
2. Repo层使用scormv2操作数据库
3. 错误使用errcode包装,提供上下文信息
4. HTTP响应不要定义retcode/message(框架统一处理)
【分步实现】
第1步:定义数据结构(Request/Response)
第2步:实现Repo层(数据库查询)
第3步:实现Domain层(业务逻辑)
第4步:实现Handler层(HTTP接入)
第5步:编译验证
关键优势:
- ✅ 利用MCP自动读取文档,无需手动复制粘贴
- ✅ 提供参考实现,保持代码风格一致
- ✅ 明确开发要求和注意事项
- ✅ 分步实现,每步可验证
效果:
- 时间:从4-6小时 → 不到1小时
- 质量:代码风格统一,符合项目规范
- 准确性:基于真实文档,避免理解偏差
五、性能优化
5.1 减少无效Context
问题症状:Cursor响应越来越慢
常见原因:
- Chat历史太长(几十轮对话)
- Context中包含大文件(几千行)
- Rules文件过大(几千行)
优化策略:
1. 定期清理Chat历史
❌ 在一个Chat里做10个不相关的任务
✅ 新任务开新Chat,保持上下文清爽
2. 大文件只添加关键部分
❌ 添加整个3000行的文件
✅ 只选择相关的方法(100-200行)
✅ 或在Prompt中说明:"只关注XX方法"
3. Rules瘦身
❌ .cursorrules 5000行,全是细节
✅ 核心规则<1000行,详细文档放docs/
✅ 需要时在Prompt中引用:"参考docs/xxx.md"
5.2 Agent模式加速
什么是Agent模式?
- Composer的一种高级模式
- AI会自主规划和执行任务,不需要人工介入每一步
- 适合任务明确、步骤清晰的场景
对比:
普通Composer模式(需要多轮交互):
用户:实现用户查询接口
AI:这是Handler代码
用户:好的,继续写Domain层
AI:这是Domain代码
用户:好的,继续写Repo层
(需要3-5轮交互)
Agent模式(一次性完成):
用户:实现用户查询接口,分3层:Handler、Domain、Repo
参考 app/fbs/inbound 模块的结构
(勾选"Agent模式")
AI:我会分3步完成:
Step 1: 创建Repo层(数据库查询)
Step 2: 创建Domain层(业务逻辑)
Step 3: 创建Handler层(HTTP接入)
开始执行...
(AI自动完成所有步骤,中间不需要确认)
何时使用Agent模式:
- ✅ 标准的CRUD接口
- ✅ 重复性工作(如批量创建类似结构)
- ✅ 步骤明确的任务
何时不用:
- ❌ 复杂的架构设计
- ❌ 需要中间确认的重构
- ❌ 涉及业务判断的逻辑
六、常见问题与解决方案
6.1 问题1:AI"遗忘"了之前的约定
现象:
第1轮对话:
用户:使用scormv2操作数据库
AI:好的(生成了正确的代码)
第5轮对话:
用户:再实现一个类似的查询方法
AI:(竟然用回了scorm v1)
原因:
- Chat历史太长,早期的约定被"遗忘"
- Context权重分配问题,远处的信息权重降低
解决方案:
方案1:重要约定放在Rules中
【强制】数据库操作
- 新代码必须使用scormv2
- 禁止使用scorm v1
方案2:每次提示词中重申
实现XX查询方法,要求:
1. 使用scormv2操作数据库(不要用scorm v1)
2. ...
方案3:使用Composer代替Chat
- Composer有更好的任务记忆能力
- 适合多步骤的任务
6.2 问题2:AI过度优化
现象:
用户:优化这个方法的性能
AI:(不仅优化了性能,还重构了整个模块的结构)
原因:
- 提示词不够精确
- 没有明确"改动边界"
解决方案:明确告诉AI改动范围
改进前:
优化这个方法的性能
改进后:
优化这个方法的性能,要求:
1. 【只修改】这个方法内部的逻辑
2. 【不要修改】方法签名、接口定义
3. 【不要影响】其他调用方
4. 【优化目标】减少数据库查询次数(从N+1改为批量查询)
关键:用【只修改】【不要修改】【不要影响】等明确的边界词。
6.3 问题3:代码能编译,但逻辑错误
现象:
- 代码看起来很规范
- 编译、测试都通过
- 但实际运行时逻辑不对
真实案例:
// 需求:查询过去7天的数据
// AI生成的代码:
startTime := time.Now().AddDate(0, 0, -7)
endTime := time.Now()
// 问题:
// AI理解的"过去7天" = 过去168小时
// 实际需求的"过去7天" = 过去7个自然日(11月24日00:00:00 到 12月1日23:59:59)
根本原因:
- 业务需求没有说清楚
- AI按字面理解,缺少业务上下文
解决方案:业务需求要精确
改进前:
查询过去7天的数据
改进后:
查询过去7个自然日的数据(不是168小时)
- 开始时间:7天前的00:00:00
- 结束时间:今天的23:59:59
- 示例:今天是12月1日,应查询11月24日00:00:00到12月1日23:59:59的数据
要求:
1. 使用timetools.GetDayStart()和timetools.GetDayEnd()方法
2. 时区使用项目配置的时区(不要hardcode)
经验:涉及时间、金额、数量等业务概念时,一定要给出具体示例。