在我用Cursor写代码的第三个月,我终于被这四个词搞崩溃了。
起因很简单:我看到一个帖子说“给Cursor配上skill之后,代码审查效率翻倍”,然后又看到一个教程说“写好rules,AI才会真正听你的话”。我把两者都配置好之后,发现Chat里输入内容时又冒出个Commands,再一翻更新日志,发现还有subAgents。那一刻,我盯着设置面板问自己:这些东西到底各管哪一摊?如果我把规则写进了Skill,把Skill做成了Command,把Command塞给了subAgents,会发生什么?
答案是我全都试过。结果就是一连串“奇怪问题”:规则没生效、技能唤不出来、指令重复执行、子代理跟个普通Chat一样……排查一圈之后我才意识到,这四个概念表面长得很像,本质上却是完全不同的四套机制。这篇文章不聊Cursor的安装,也不聊模型配置,我专门把这四兄弟的边界拆清楚,并附上我自己梳理出来的用法组合和踩坑记录。
1. 先把四个词放到正确的位置上
很多人的第一反应是:Rules、Skills、Commands、subAgents,不都是“教AI做事的吗”?对,它们都能影响AI的行为,但影响的方式、生效的时机、作用的对象,差别极大。
我用一句大白话概括:Rules是给AI立的规矩,Skills是给AI看的操作手册,Commands是你替自己准备的快捷输入模板,subAgents则是你雇来的专职员工。这四者不是同一层的东西,硬放在一起比“谁更强”没有意义,你得先看看它们分别在哪个环节起作用。
1.1 Rules:常驻上下文的“行为准则”
Rules最像公司制度。你入职一家公司,不需要每次做事前都翻一遍员工手册,但手册里的内容会一直在后台约束你:上班不能迟到、代码必须过lint、文档必须写注释。
在Cursor里,Rules就是这样的存在。它写在项目根目录的.cursor/rules下,或者通过设置面板里的Rules入口维护。规则文件可以采用Markdown格式(通常是.mdc后缀),通过文件头部的description和globs字段,告诉AI“这条规则在什么条件下要加载”。
举个例子,我想让Cursor在处理所有TypeScript文件时自动遵守编码规范,就可以写一个.mdc文件:
--- description: 后端TypeScript代码必须遵守的规范 globs: src/**/*.ts --- - 所有函数必须显式声明返回值类型 - 禁止使用 `any`,如需绕过必须注释说明原因 - 错误处理统一返回 `Result<T, Error>` 对象,禁止直接抛出字符串 - 新增公共API必须同步补充JSDoc注释注意这行globs: src/**/*.ts。它意味着:只要用户打开、编辑、引用src目录下的.ts文件,这条规则就会自动被带进AI的上下文。它不需要你“调用”什么,也不需要你每次手动提醒,只要你触碰了对应的文件,规则就跟着走。
这就是Rules的核心特征——被动且常驻。它不负责执行某个具体功能,它负责给AI的所有行为划定边界。
1.2 Skills:可以随时取用的“技能包”
Skills解决的是另一个问题:有些任务有固定套路,比如“代码审查”“生成单元测试”“重构某段逻辑”,AI如果没经过指导,做出来的东西往往不专业。Skill的思想就是把这些套路写成一份操作手册,让AI在用户提出相关需求时,能“照着手册做”。
Skills以文件夹为单位,通常是一个目录(如.cursor/skills/code-review/),里面有一个核心的SKILL.md文件。这个文件的结构和Rules有点像,也有name和description,但对触发方式的描述更讲究。因为Skill不是常驻的,它靠description让AI判断“什么时候该动用这个技能”。
比如我写过一个代码审查技能:
--- name: code-review description: 当用户要求对代码进行审查、检查代码质量、发现潜在Bug时使用。适用于单文件或多文件评审。 --- 执行代码审查时,请严格按以下步骤操作: 1. 先通读代码,弄清函数职责和调用链,不要边看边改。 2. 按“正确性、性能、可读性、可维护性”四个维度输出问题清单。 3. 每个问题标注严重级别(P0/P1/P2),P0为会导致崩溃或数据丢失的问题。 4. 对每个问题给出最小改动的修复示例,禁止一次性重写整个文件。 5. 最后输出一段总结,说明当前代码的整体健康度。关键在于触发方式。当我在Chat里输入“帮我看看这段代码有什么问题”时,Cursor会先识别意图,发现这符合code-review技能的description描述,于是自动把技能中的步骤注入当前会话。这个过程不需要我输入“使用技能”三个字,它是AI基于描述主动匹配,半主动式加载。
但我得说句实话:技能描述写得好不好,直接决定了这个机制好不好用。描述太笼统,AI可能误触发;描述太详细,AI可能反而抓不住关键词。这个话题后面单独展开,这里先记住定位——Skills是“做具体事的操作手册”。
1.3 Commands:属于你的“快捷指令宏”
Commands这三个里面最好理解。它就是一个可复用prompt模板,本质上是帮你省去每次敲一大段指令的麻烦。你可以把它理解为输入法里的自定义短语,或者Excel里的宏:你存好一段内容,想用时一键调出来。
Cursor里可以通过命令面板,或者直接在输入框输入/唤起命令列表。比如我自定义了一个/chinese-review命令,内容是:
请用中文对当前选中的代码进行review,要求: - 先概括这段代码的职责 - 再讲存在的问题 - 最后给出修改建议这个命令本身没有智能,它不会像Rules一样自动匹配文件,也不会像Skill一样被AI按意图召唤。你只有主动调用它,它才存在。它是全手动的效率工具,作用仅限于把输入那段话变成一次按键操作。
很多人犯的错,是把自己常用的Commands一股脑写进了Rules里,导致每次对话都要白白占一堆上下文。这个坑我后面细说。
1.4 subAgents:可以指定角色的“专职员工”
subAgents是这四个里最“重”的一个。它相当于你在Cursor里创建一个带专属身份的对话代理:给它一个名字、一段角色设定、一整套工作流程,然后在需要时切换到它,让它以一个独立的身份来处理任务。它更像“团队里的一名同事”,而不是一段提示词。
比如我建过一个“接口设计评审员”。它的设定是:只关注API设计的合理性,包括RESTful风格、参数校验、状态码语义、兼容性等。我在写新的接口时,切换到这个子代理,它会以一个专业评审者的视角挑毛病,而不是像主Agent那样更关注整体业务逻辑。
这里有一个重要区分:subAgents自带上下文隔离。它和主对话处于不同的上下文窗口,你给它一个任务,它会在自己的“小世界”里干活,不会把主对话的历史记录全带进来。这在处理大型任务时能显著节省token,也能让AI专注于某个具体角色。
为了更直观,我把四者的关键差异整理成一张表:
| 概念 | 一句话定位 | 生效方式 | 类比 |
|---|---|---|---|
| Rules | 行为准则,划定边界 | 被动常驻,命中即加载 | 公司制度 |
| Skills | 执行某项任务的固定套路 | 半自动,按描述匹配意图 | 操作手册 |
| Commands | 可复用的输入模板 | 全手动,主动调用 | 快捷键宏 |
| subAgents | 带独立身份和上下文的代理 | 显式切换,任务分发 | 专职员工 |
2. 触发逻辑才是四者的真正分水岭
我之所以花了很多时间才搞明白这四个概念,是因为我一开始总盯着“它们都能让AI做某件事”这个共同点,而没有注意到它们各自是怎么被唤醒的。搞清楚触发逻辑,比背下各自的功能列表重要得多。
2.1 静态匹配与动态注入
把四个概念放在一起看,本质区别在于“谁来决定什么时候生效”。
Rules是由文件路径决定的。AI在处理某个文件时,通过globs做静态匹配,匹配到了就把规则注入上下文。这中间没有“AI思考”的环节——只要你打开的文件命中了src/**/*.ts,规则就是铁打的,哪怕你觉得这次对话根本用不到它,它也会在。所以Rules需要精简,你可以把Rules理解成一个“环境变量”,它的存在是持续的。
Skills的匹配则是由意图决定的。AI读取对话内容,判断“用户是不是想让我做这件事”,然后通过description与技能库做语义匹配,匹配到就加载该技能,匹配不到就不用。它是动态的,需要AI“听懂”你的意思。这带来一个天然问题:如果用户的表达太模糊,技能就匹配不上,表现为“技能不生效”。这也是我在社区里看到对Skills抱怨最多的原因——不是技能没配好,而是你和AI之间没有一个明确的“信号”。Commands则是三者中最直白的。它不依赖文件路径,也不依赖AI理解意图。你按下快捷键,它就是执行,不存在“漏匹配”的情况。所以Commands最适合用在那些高频、固定、必须生效的场景,比如“解释这段代码”“总结本周工作日志”“生成commit message”。它胜在确定性。
subAgents比较特殊,它的触发是你主动选择一个人格。这相当于你从“和一个全才聊天”变成“和一个专才聊天”。选定之后,上下文就切过去了,所有后续任务都在这个角色设定之下进行。它跟常规Chat最大的不同是任务边界清晰,且带自己的专属指令。
2.2 为什么“谁来决定触发”如此重要
因为触发方式决定了你的维护成本。
Rules一旦写得多而乱,整个项目的AI上下文都会变臃肿,轻则浪费token,重则AI被互相矛盾的规则搞糊涂。Skills一旦description写得不到位,就可能出现“AI偶尔调用、偶尔不调用”的玄学状态,这种不稳定对工程化的流程是致命的。Commands没有调度问题,但你如果存了几百条命令,自己都不记得有哪些,那它也就失去了快捷的意义。subAgents如果设定不严谨,它就会退化成普通Chat,徒增管理成本。
我常用的一个判断标准是:
- 如果希望AI“永远遵守”,放在Rules里;
- 如果希望AI“遇到同类型任务时按标准流程做”,放在Skills里;
- 如果只是希望“我一键输入一大段常用话术”,放在Commands里;
- 如果希望“让不同角色专注解决不同问题”,拆成多个subAgents。
2.3 一个典型任务的四视角演示
我用一个真实场景来演示四者的差异——任务是“把这段代码改成异步版本”。
如果只配置了Rules,AI在改代码时会遵循我的规则,比如“改动前先理清调用关系”“禁止破坏原有错误处理逻辑”,但它不会有什么特别的“异步改造手法”,它只是按一个合格程序员的通识去做。
如果我在项目里加了“async-refactor”这个Skill,AI一旦识别出我的需求是“改造异步”,就会自动装载技能:先分析当前函数的调用栈,再检查调用方是否需要同步调整,然后逐步修改,最后跑一遍类型检查。整个流程被标准化了,质量更可控。
如果我用一个Command,比如/async-refactor,那么我调用它时,系统只是把一段写好的指令发送给AI,让AI按指令做。这里没有技能步骤的约束,AI理解多少理解多少,效果取决于这个指令本身写得有多仔细。
如果我用subAgents,我会切换到“异步重构专员”这个身份,然后告诉它:“当前项目下面这几个文件需要做异步改造”。这个专员会按照我预先给它配置的严谨流程去执行,并且只关心这个任务,不带入之前闲聊的上下文。
所以你看,四者可以做完同一件事,但稳定性和可预期性完全不同。如果你是靠Cursor混饭吃的开发者,想让输出质量稳定,Skills和subAgents才是主力,Rules做环境约束,Commands做效率补充。
3. 组合使用的实战方案:一份配置四层分工
搞清楚了边界,真正有价值的是怎么让它们协同工作。我在实际项目中总结出一套“四层配置法”,以一个小型的“Python API接口评审+文档生成”场景为例,完整走一遍。
3.1 第一层:用Rules设定项目底线
我在项目根目录的.cursor/rules下建了一个项目规范.mdc,内容不长,全部是禁止性和强制性要求:
--- description: 项目全局开发规范 globs: **/*.py alwaysApply: true --- - 新增接口必须声明在 `api/` 目录下的Blueprint中,禁止在入口文件堆路由 - 所有请求参数必须通过Pydantic模型校验 - 对外返回的JSON必须使用统一格式:`{"code": 0, "msg": "ok", "data": {}}` - 如果你不确定一段代码的归属模块,先询问用户,禁止自行猜测注意这里有个alwaysApply: true字段,它的意思是:只要项目内的Python文件被处理,不管具体是哪个文件,这条规则都强制生效。这适合放那种“必须绝对遵守”的项目级铁律。
Rules层要尽量克制。我见过有人把上百条规则塞进Rules,结果AI在长对话后半段开始忽略部分规则,因为上下文被撑爆了。我的经验是:Rules只放“不遵守就会出大问题”的硬性约束,理想情况控制在十句话以内。
3.2 第二层:用Skills沉淀标准流程
接下来建立一个“接口评审”技能,这是整个组合里的核心。目录结构如下:
.cursor/skills/api-review/ ├── SKILL.md └── templates/ └── review-report.mdSKILL.md这样写:
--- name: api-review description: 当用户要求评审接口设计、检查OpenAPI文档、验证接口参数校验逻辑时使用。适合新接口开发完成后的自查阶段。 --- 1. 先定位当前项目所有由该Blueprint注册的路由。 2. 逐一检查每个路由: - HTTP方法选择是否合理,POST是否被误用来做查询 - 参数是否经过Pydantic校验,是否存在直接使用request.json取值的情况 - 返回格式是否满足统一封装结构 - 是否缺少必要的错误状态码捕获 3. 将问题按“设计问题/实现问题/文档问题”分类输出。 4. 输出审查报告(模板见文件:templates/review-report.md)这套技能被AI通过语义匹配自动触发。比如我在Chat里说“我把新接口写完了,你帮我检查下”,它就会主动执行上面四个步骤。但如果我说的是“帮我改个Bug”,这个技能就不会被调起。
把反复要用到的检查流程沉淀到SKILL.md里,是我觉得最值得培养的使用习惯。它相当于把“我知道该怎么做”移交给AI,让AI每次执行都稳定在一个水平线上。你可以把团队里最资深的评审者的口头检查清单拿出来,转写成Skill描述,效果立竿见影。
3.3 第三层:用Commands做快速入口
Commands在这套体系里的角色比较“轻”,它负责把一些常用操作变成固定入口。我创建了下面几个:
/review-this:内容为“请使用 api-review 技能审查当前打开的文件,重点检查参数校验和返回格式,输出审查报告”。/gen-doc:内容为“基于当前文件中的Blueprint路由,生成OpenAPI文档片段,并按项目规范输出”。/fix-style:内容为“修复当前文件中的代码风格问题,仅做格式化,不改变行为”。
它们的价值在于:显式地控制触发。哪怕AI没能在对话中自动识别出你想调用某个技能,通过命令入口也能强制指定。这对那些“语义上容易被误判”的场景特别有用。
这里有一个细节:Commands本身不用写太长,因为长逻辑已经被放进了Skill里,Command只需要做“指名道姓”的调用即可。
3.4 第四层:用subAgents做角色分工
项目场景变大之后,主对话的上下文会越拖越长,这时候我会把任务按角色拆给不同的subAgents。比如在当前项目里,我维护了三个:
| 子代理名 | 角色定位 | 主要负责 |
|---|---|---|
| 接口评审官 | 专注于API设计与安全审查 | 新接口的自查与返工 |
| 文档助手 | 专注于技术文档撰写 | 生成OpenAPI文档、README、接口变更日志 |
| 性能顾问 | 专注于慢查询与瓶颈排查 | 分析N+1查询、索引失效、响应时间瓶颈 |
一个比较关键的点:subAgents并不是简单的“换个人设”,而是把你对某个角色的全部要求都预先配置好,包括工作流程、输出格式、审慎检查清单。这样你切换过去时,它的行为是稳定且可预期的。
比如“接口评审官”的system提示词里有一条硬性要求:“输出所有问题前,必须先检查接口的鉴权逻辑,禁止在未确认鉴权的情况下通过评审。”这个约束如果你放在主对话里,可能因为上下文太长而失效,但放在子代理里,它就是独立的职责,几乎不会被其他话题稀释。
3.5 组合起来看整体工作流
实际操作时,我的流程是这个样子的:
- 新接口写完,我在Chat里输入
/review-this。这个Command会强制调起“接口评审官”这个子代理,并让它按api-review技能的步骤执行。 - 子代理审查时,项目里的Rules会同时生效,确保它输出的修改建议符合统一封装规范。
- 审查通过后,我调用
/gen-doc让“文档助手”生成OpenAPI片段。 - 最后,如果涉及慢查询,我再切换到“性能顾问”做专项排查。
四个组件各司其职:Rules保证底线,Skills保证流程,Commands保证触发,subAgents保证分工。单独拎出任何一个,都能工作,但组合起来才能应对真正复杂的项目。
4. 容易踩的坑:我栽过的四类跟斗
工具越用越深,踩的坑也跟着变多。下面这几个问题我都在真实项目中遇到过,这里还原一下排查过程,给后来人提个醒。
4.1 为什么Rules有时候“不生效”
我先说现象:我在Rules里写了一条“所有Python文件必须使用类型注解”,然后让AI生成一段新代码,它确实照做了。但过了一会儿,在同一个对话里,我让它修改另一个文件时,它又写出了无注解的代码。我一度认为Rules失效了。
排查之后发现,问题出在globs的匹配范围。我最初写的是globs: src/**/*.py,这只会命中src目录下的文件。当我在项目根目录新建临时脚本的时候,该规则根本不覆盖。后来我改成globs: **/*.py,问题就消失了。
另一个原因是上下文溢出。当对话历史非常长时,旧的Rules内容可能被AI从上下文中“挤出”。这属于大模型机制的固有限制,不是Cursor的Bug。应对方法很简单:把最关键的规则放在alwaysApply: true的规则文件里,并且尽量精简,不要在Rules里堆砌无关的废话。
4.2 为什么Skill“叫不出来”
“我叫AI用技能,但它好像完全没听到。”这也是高频问题。
排查路径是这样的:先看技能文件夹里SKILL.md的description。如果你的description写得比较虚,比如“这是一个帮助用户的技能”,AI就没法把用户的实际请求和这个技能关联起来。description里必须包含“什么时候用”和“任务关键词”。比如我现在的写法是“当用户要求评审接口设计、检查OpenAPI文档、验证接口参数校验逻辑时使用”,这样AI才能精准匹配。
还有一个我踩过的坑:技能名里带空格或特殊符号。早期我建过一个技能叫code-review-v2,因为文件夹路径里带了-,倒没出问题;但团队里另一个同事命名用了空格,结果始终无法正常调用。我的建议是:技能名统一使用小写字母和连字符,文件夹名保持一致,不要干“文件夹叫A,文件里的name叫B”这种事。
4.3 把Commands当成Rules写,结果每次对话都超长
这是我自己最典型的反面教材。早期我没有形成“四层分层”的概念,觉得“让AI每次都这么做”,最稳妥的方式就是写进Rules。结果我把一长串“命令模板”(例如“当我说review时,请按以下5条执行……”)放进了Rules文件。它的确生效了,但也意味着每一次对话,AI都要把这串长指令充当背景知识,白白消耗上下文空间。
后来我把这串内容挪到了Skill里,把“触发方式”从“常驻加载”改成了“按意图匹配”,上下文立刻瘦身。这个教训的本质是:常驻的东西越少越好,按需加载的东西可以多一点。
那Commands的正确用法是什么?我认为是“你自己最常用的、不需要AI思考要不要用的动作”。比如“总结当前文件”“生成提交信息”,这些动作你自己主动触发就好,不需要AI去识别意图。
4.4 subAgents“能力弱”,其实是设定太单薄
有人觉得subAgents相比于直接对话并没有强多少,我一开始也这么觉得。后来对比了我和同事的配置,发现问题出在“角色设定”的颗粒度上。
如果我只写一句“你是Python专家”,那它和主对话没有任何区别。但如果我像下面这样配置,表现就完全不同了:
你是本项目的接口评审官。你的职责是在接口合入前发现设计缺陷。 每次审查必须完成以下动作: 1. 检查是否包含鉴权校验 2. 检查请求参数是否经过Pydantic模型 3. 检查返回格式是否与统一封装一致 4. 检查是否存在敏感信息泄露风险 在输出结论之前,你必须逐条打勾确认。未确认完毕,不允许输出“整体无问题”之类的结论。差别就在于:我给了它强制流程和审慎检查清单。它不是“一个专家”,而是“一个按固定流程办案的执法者”。如果你希望某个子代理稳定输出特定风格的结果,你得把它当成一个新员工来培训,而不是给它贴个标签了事。
4.5 实践中的几条铁律
把上面这些教训总结成几条更通用的原则:
- Rules做减法:只写硬约束,控制在少量条数以内。任何“可以靠按需触发”的内容都不要放这里。
- Skill的description才是灵魂:多花时间打磨触发字段,比反复调试技能内容本身收益更高。
- Commands保持短小:如果一段Command超过几行,说明里面的逻辑应该下沉到Skill里。
- subAgents要配流程:只给角色名不给流程的subAgents,跟普通对话没有区别。
- 命名规范全家桶:文件夹、技能名、命令名统一用小写连字符,空格和中文最容易在路径匹配时出问题。
5. 关于这四者的几个额外建议
前面说的偏“道”,最后再聊几个更贴近实际操作的细节。
如果你的目标只是“让Cursor输出的中文更自然”,其实不用折腾界面汉化之类的东西。在全局Rules里加一行“请始终使用中文回复,并保持技术术语准确”,立刻能让所有对话默认变成中文输出,这比改设置面板里的语言选项更直接。这也是我见过很多人在Rules里配置的第一条规则。
如果你维护的是团队级项目,建议把Rules和Skills的目录纳入Git管理。我现在的项目里,.cursor/rules和.cursor/skills都是代码仓库的一部分,团队成员克隆代码后立刻获得统一配置。评审口径一致之后,团队Pull Request的风格都会收敛不少,这算是额外红利。
最后再强调一次容易忽略的细节:Skills文件夹的名字和SKILL.md里声明的name要严格对应,路径不要带空格。我踩过一次之后学乖了,现在创建任何技能都先想清楚“用户在什么场景下会提到这件事”,然后把这句话反推出description,再动笔写正文。这大概也是我推荐所有人采用的工作顺序——不是先写内容,而是先设计触发条件。
Cursor这四兄弟,每代版本都有微调,但核心边界不会变:Rules管底线,Skills管方法,Commands管效率,subAgents管分工。把这层关系理顺了,再看网上那种“一条规则让Cursor飞起”“这个Skill神了”之类的帖子,你就能自动过滤掉80%没有营养的内容,因为它们都只是这四层里某一层的局部优化而已。