Cursor 实战万字经验分享,与 AI 编码的深度思考
其实除了大家,我自己在很长一段时间也有类似的疑问,对 cursor 的看法也发生过多次改变;而在最近的三个月,我也一直尝试要求自己不要手写任何代码,尽可能全部靠 cursor agent 生成,这个过程中我也做了多次 rule 和开发习惯的调整与对比测试,于是也有了一些心得和感悟,今天讲给大家听。
rsor 编程的过程中,我知道大家偶尔会有如下感受:
- 我只是单纯想和 cursor 聊天聊问题,为什么 cursor 莫名其妙非要去改我的代码?
- 我 prompt 里都说了只改 A 功能,怎么除了 A 还偷偷把我的 B 功能也顺带改了
- 一个功能聊到后面,怎么感觉 cursor 理解越来越笨了,一个功能来来回回死活改不好,还不如我自己动手快,犹豫后续还用不用 AI 写代码。
- 一口气生成整个需求代码了打补丁快?还是边写代码写提问快?
- project rule 和 user rule 什么区别?project rule 拆多大的粒度更合适?后更新的 cursor memories 和前面又有什么区别?
- pro agent 不限额度,我们的 biz 到底限制额度没?
- ....
其实除了大家,我自己在很长一段时间也有类似的疑问,对 cursor 的看法也发生过多次改变;而在最近的三个月,我也一直尝试要求自己不要手写任何代码,尽可能全部靠 cursor agent 生成,这个过程中我也做了多次 rule 和开发习惯的调整与对比测试,于是也有了一些心得和感悟,今天讲给大家听。
壹 ❀ 前置概念
在聊具体问题之前,让我们先建立几个 cursor 中比较重要的概念,这也利于后续大家理解和接受本次的观点。
1.1 cursor 提问的 token 计算
我们知道不同 model 都有不同大小的上下文,上下文越大的模型自然能接受更大的提问信息,那么在 cursor 中我们的任意一次聊天,大致会产生如下的 token 计算:
初始 Token 组成:
初始输入 = 用户问题 + Rules + 对话历史
用户问题 : 我们输入的文字 + 主动添加的上下文(图片、项目目录、文件)。
Rules:project rule + user rule + memories
对话历史:对话产生的历史。
工具调用后的 Token 累积:
cursor 接收用户信息后开始调用 tools 获取更为详细的信息,并为问题回答做准备:
总 Token = 初始输入 + 所有工具调用结果
额外的信息:什么是工具调用?比如我们问代码问题,cursor 经常会出现触发 codebase_search(项目代码查询) 就是一次工具调用,而我们安装的 MCP 其实都内置了多个工具,可以在设置里查看 MCP 点击展开查看内置的 tools。
下图就是 cursor 对话中对于工具的调用:
cursor 模型分为 normal 和 max 两种,normal model 一次 request 最多调用 25 次 tools,用完就要消耗下一个 request 额度,max 模型每次 request 有 200 次 tools 调用且拥有更大的更大的上下文,对于编程这种需要人为精确干预的任务,我不推荐使用 max, max 更适合全程自动化的任务,比如 cursor background agent。
那么到这,我们能有一个基本的结论,在不超出模型上下文的情况下,我们对于问题描述越清晰,AI 对于问题的处理就会越准确;反之上下文中掺杂过多臃肿的无用信息,这会影响 AI 的判断与回答的质量。
因此,我们如果要提升 cursor 对于问题的理解,方向自然聚焦在 rule 优化、用户问题表达和对话历史几个方向,具体怎么做后面再谈。
1.2 关于 project rule
rule 是一种供持久且可重用的上下文定义,project rule 顾名思义属于专为项目配置专属 rule, project rule 跟着项目走,如果你换了一个新项目之前的 project rule 会丢失,需要再次为当前项目新建 project rule。
在 cursor 0.49 版本后,支持在 chat 时输入 /Generate Cursor Rules
由 cursor 自动为当前项目生成 rule,或者直接复用社区中一些比较优秀的 rule 模版,再针对项目情况做二次修改,比如:
project rule 支持四种生效规则:
规则 | 描述 |
---|---|
Always |
Always included in the model context 始终包含在模型上下文中 |
Auto Attached |
Included when files matching a glob pattern are referenced 当引用匹配 glob 模式时包含 |
Agent Requested |
Rule is available to the AI, which decides whether to include it. Must provide a description 规则对 AI 可用,AI 决定是否包含,必须提供描述 |
Manual |
Only included when explicitly mentioned using @ruleName 仅当使用 @ruleName 明确提及时包含 |
同样的,我们先掌握这个信息,具体优化后面再聊。
1.3 关于 user rule
user rule 也是一种用于持续化重用的规则,与 project rule 不同的是此 rule 跟随用户 cursor 账号,如果你配置过一次,后续无论你打开什么项目,用户 rule 都会存在和生效。
另外需要注意的是 user rule 修改做不到实时更新,做简单的测试是定义后直接问 cursor 当前 cursor rule 是什么,如果大家希望 user rule 立马投入使用,最好的办法是在对话中直接输入新版 user rule 将记忆注入进去。
1.4 关于 memories
cursor 1.0 更新了全新的 rule 分类 memories,不过如果需要使用这项能力,需要用户关闭隐私模式,或者将隐私模式调整为这个选项,目前我们 biz 版本已经让叶子调整了团队规则,所以后续新的 cursor feature 大多数大家都可以直接体验。
与 project rule 类似,memories 也是跟着项目走,但两者的本质区别在于:
- Project rules = "我希望你这样做"(主动设置的规则)
- Memories = "我记得你喜欢这样"(从交互中学到的偏好)
cursor 会在日常聊天中自动学习和理解我们的项目预期,你可以主动要求记录 memories,或者在被我们严厉批评时,它也会自主记忆。
主动创建记忆:
cursor 的反省与学习:
1.5 关于套餐和计费
cursor 在本月调整了订阅策略,pro 不再限制 model 调用次数,但限制了问答速率,比如一个小时内你最多问答多少次,速率达到就会进入几小时 CD 阶段,只能使用免费模型;
大家一定会好奇我们 biz 版本是否是无限,这点我麻烦叶子跟 cursor 官方确认了这一点,结合 cursor 官方的定价说明,其实我们现在还是每月固定 500 次 高级模型 request,无限免费模型调用,且大家也能使用 max 模型,但 max 会消耗大家的 reques 次数,按 tools 次数粗略估算,一次 max 请求可能等于 8 次 normal 问答,消耗会非常恐怖。
贰 ❀ 如何让 cursor 听懂人话?
回到分享引言部分的问题,大家使用 cursor 大多数都希望 cursor 真的像一个 AI 伙伴,它能听懂我在说什么,知道我当下要什么,并为我提供最好的问答体验,我们应该如何改善这一点呢?接下来我们从几个方面解决。
2.1 简化和拆解 project rule,要求越多等于越没有要求
我先贴一个官方的最佳实践要求,然后结合 notta web 的项目规则来聊聊我们如何做的更好。
我对于 project rule 有两个非常明确要求,最基本应该包含你当前项目的技术栈使用,以及对应依赖版本;除此之外应该包含社区编码明确要求的规范,因为不同公司开发规范不同,cursor 没办法自然理解你的编码风格。
还记得前面我们聊到因为 token 有限,每次问答尽可能清晰定义,明确要求,以 notta 项目当前的 project rule 我们可以做如下优化:
project rule 需要明确生效的范围,不要一股脑设置 Always
我们目前 notta 5个子项目的 rule type 都设置为了 always,事实上 always 会默认将这些规则添加到每次问答的上下文中,很致命的一点是,我明明在聊 notta web 的需求,cursor 会把 showcase web、插件好几个不相关的上下文也默认带进来,这些会严重浪费 token 数量增加无效信息。
我更推荐使用 Auto Attached 并使用 glob 去明确匹配目录,比如:
或者使用 Manual 模式,在聊天时主动把要匹配的 project rule 添加到上下文中。
内容应该精简,不要重复描述,可以添加代码描述,但并推荐加入大量的代码示例,非常浪费上下文
还是以 notta web 为例,可以看到对于项目技术依赖出现了多次描述
其实这里完全可以做一个合并,而且在 notta web 里还出现了对于插件的说明,其实这就是重复且无效的上下文。
其次,虽然官方提到必要的时候提供例子或参考文件,但不推荐在 rule 写大量的示例代码,除非这个例子非常典型、重要或者适应性非常广,我个人更习惯具体问题分析时提供具体的参考以强化 cursor 理解,那么此时 rule 里的示例本质上就是多余的。
不要添加假大空的规则,如果你觉得某些规则确实偶尔需要,拆解成单独的rule设置为 Manual,具体问题具体引入
还是 notta web 的例子,如下就是假大空的要求:
我觉得一个规则好不好,最简单的例子就是把规则代入到自己的日常开发,你知道怎么做到怎么写代码让 LCP ,FID 更好吗?实话实说我真不知道,太宽泛了;
实不相瞒,这几句废话规则就是第一版 rule 我加进来的( = =。),而且事实证明这小半年我没看到 cursor 在编码上有任何以上要求的体现,甚至在 react 组件时还会给我写出无限渲染的组件,不是 cursor 不想做,是当下真的做不到,冷门且重要的规则单独拆出来,具体问题具体要求!
以现在服务端不同服务有不同的项目,就非常为这些单独的服务都配置独立的 project rule,notta 的项目规则接下来我们也会重新做一次优化。
总结:
2.2 增加过程决策,而非放任 AI 编码
老实说,我之前过度追求提前写好方案,然后迫不及待让 AI 一口气帮我完成整个需求,我觉得这太炫酷了,我只需要扮演 prompt 输入、代码审核和测试的角色做就好了,但事实上需求实际表现让我很失望,我发现生成的代码质量很差,除了目录和框架搭建能用,具体组件的代码非常糟糕。
即便我在 project rule 、user rule,memories 都增加了必要编码的规则,但遗憾的是它就是会出现幻觉和失忆,我突然意识到在 AI 编程上我有一个很严重的错误,在当下过分依赖和相信它的自动化编程,这个过程中我缺少了一个非常重要的环节 -- 决策。
我举一个实际的例子,大家有没有遇到过 cursor 明明代码都写好了,但 cursor 好像突然又意识到了什么,然后立刻对之前实现的代码开始“优化”,这种 AI 的反悔本质上是 AI 遇到了一个决策点,但我们做不到暂停只能任由 AI 替我们决策,于是我们得到了一份薛定谔的代码,在代码 review 之前它可好可坏。
为了避免此类问题的发生,我在 user rule 增加了一个规则,凡是在方案、编码过程遇到任何争议或不确定,必须在第一时间主动告知我由我做决策。
我提供了部分更新 rule 后 cursor 的表现截图:
体验一下好起来了,通过这种互动我能时不时加入更多明确的要求和预期,帮助 cursor 不断完善和理解当下的诉求,代码可用度得到了明显改善。
总结:
2.3 采用渐进式开发,而不是大需求一口气梭哈
说在前面,我不推荐大家输出完方案后让 cursor 一口气基于方案完成需求(非常小的需求除外),需求越大代码质量越烂,这一点我基于不同规模的需求做了多次实验,这个结论我可以百分百确定的同步给大家。
为此,我的改变是在方案阶段我会明确要求 cursor 在双方都没问题之前不要输出任何方案,而确定方案后要按步骤依赖关系将需求拆解为 N 个步骤,通过步骤拆解以及决策的 rule 限制,我能在开发阶段的每个环节及时补充上下文。
因为步骤拆解加干预,这个开发过程理想但不完美的 0 - 100,变成了 0 - 10 - 50 - 70 - 100,看起来后者更麻烦和更慢,但实际体感上快了不少。
总结来说,关于渐进性开发,有如下几个优势:
- 任务粒度越小,AI 完成度越高
- 一口气完成需求往往带来很多 bug 和不正确的代码,AI 特别容易基于错误堆错误(将错误的代码作为上下文继续制造错误),导致怎么改改不对的烦躁情况,小范围利于人为监管和把控。
- 分步骤代码量便于做 code review,一次改一大片很难去理解(有同学出现了 AI 代码漏审的情况)
总结:
2.4 明确要求每次改动基于最小范围修改原则,并提供尽可能清晰的上下文
我举一个实际的例子,我在做 notta 设置 automation 时,希望 cursor 基于新接口数据帮我调整业务逻辑,但我并未要求最小范围这一点,也没提供具体的目录信息,在 AI 完成工作后,我发现因为 AI agent 模块也有自动化的需求,于是 AI 出于“好意”把一个相距十万八千里的目录也给我修改了。
而明确要求最小范围改动原则的好处是,我要什么你给什么,不要画蛇添足,除非我明确要求重构或者优化,一定按我的要求指哪打哪。
关于提供明确的上下文这一点,直接给给大家举一个更实际例子,AI 终端 warp 对于我命令的执行对比:
基于全局目录,要求 wrap 帮我构建 notta 插件 uat 包,纯查找耗时 30 多秒(经历了查找、尝试多次摸索)。
明确指定 notta 插件目录,同样的话术,AI 查找只用了 5 秒。
我们很容易陷入一个误区,我之前总觉得 AI 就是自动化高科技的代表 ,给它一个命令后坐着喝喝茶享受 AI 帮我干活的等待时间,但等待除了不够高效之外,因为目的的不明确,AI 很容易基于它自己的理解做出与我们预期违背的事情。
能直接给目录范围限制,就不要说帮我修改自动化里的什么逻辑,能给 prosemirror 目录就不要说帮我查看编辑器里的需求,cursor 甚至都不知道我们表达的编辑器是不是 prosemirror,AI 只是一个基于概率学的问答机器,所做的一切只是为了让正确的概率变得更高而已。
总结:
2.5 相同需求一个窗口,不同需求不同窗口
有一个非常重要的前提,cursor 每个聊天的窗口上下文不共享;
不知道大家有没有这种感受,我在一个新窗口刚开始跟 AI 对需求时它非常清晰,可随着聊的越来越久,cursor 特别容易对细节失忆或者出现幻觉,这个原因是这个窗口的上下文越来越大(回顾下我们开头的 token 计算原则),导致你原本的问题在上下文中不断被稀释,AI 逐渐失忆和不清晰了。
针对这种情况,有两种办法解决。
更多推荐
所有评论(0)