Cursor Skills 怎么组织:与 rules 的分工别搞混
先说这东西是来给谁减负的
写过一阵 Cursor 规则的人多半有同一个感受:.cursor/rules 底下那几个文件越写越长。一开始只是”新文件一律用 TypeScript”这种一句话约束,写着写着就把”发布到 staging 要先跑测试、再打包、再部署、最后确认健康检查”这种多步流程也塞进去了。塞进去之后麻烦就来了——这套流程一年用不上几次,可只要它在规则里,相关的对话就要带着它。
Cursor 官方文档给出的分工,正是冲着这个来的。cursor.com/help/customization/skills 那页直接列了一张 rules 与 skills 的对照表,四行:Purpose 一栏,rules 是”短的编码约束”,skills 是”多步工作流与流程”;Length 一栏,rules 是几行到几百行,skills 通常更长、带详细的分步说明;How applied 一栏差别最关键——rules 是”作为上下文包含在每次(或匹配的)对话里”,skills 是”按需调用,用 /skill-name 或 @skill-name”;Example 一栏,rules 举的是”所有新文件用 TypeScript”,skills 举的是”部署到 staging:跑测试、构建、部署、验证”。
那页最后一句话是判断依据:一句短指令够用就写 rule,需要 Agent 照着一套详细可重复的流程走才写 skill。rules 的写法本站另有专门文章讲,这篇不重复,只盯 skills 这一侧的定义结构和加载条件。
前置条件:先确认目录和版本这两件事
加载位置。 cursor.com/docs/skills 列出四个自动加载的位置:.agents/skills/、.cursor/skills/ 属于项目级(Project-level),~/.agents/skills/、~/.cursor/skills/ 属于用户级(User-level / global)。除这四个之外,文档写明为了兼容性,Cursor 也会从 Claude 和 Codex 的目录加载:.claude/skills/、.codex/skills/、~/.claude/skills/、~/.codex/skills/。
这里有个 Windows 侧的坑要提前说清楚:官方文档写的是 ~/.cursor/skills/ 这种 POSIX 写法。在 Windows 上 ~ 具体展开到哪个目录,这两页文档没有说明,我们没有实测依据,所以不替它填一个路径。稳妥的做法是把 skill 放进项目里的 .cursor/skills/(这个路径在哪个系统上都是相对仓库根的),确认能被发现之后再考虑用户级目录。Linux/macOS 侧 ~ 就是登录用户的主目录,这一点不需要额外确认。
版本。 两页文档里唯一提到版本的地方是迁移工具:/migrate-to-skills 这个内置 skill,cursor.com/docs/skills 写的是”in 2.4”,cursor.com/help/customization/skills 写的是”available in Cursor 2.4+“。除此之外,skills 本身从哪个版本开始可用,这两页没有写明。
在哪个端上生效。 文档的原话是 Cursor 启动时会自动从 skill 目录发现 skills 并提供给 Agent,手动调用的方式是在 Agent chat 里输入 / 搜索技能名。至于 CLI 或其它入口是不是同样的加载行为,这两页没有说明。
SKILL.md 的定义结构
每个 skill 是一个文件夹,文件夹里放一个 SKILL.md。文档给的最小骨架是这样:
.agents/
└── skills/
└── my-skill/
└── SKILL.md
需要带脚本、参考资料和静态资源时,文档给的是这个结构:
.agents/
└── skills/
└── deploy-app/
├── SKILL.md
├── scripts/
│ ├── deploy.sh
│ └── validate.py
├── references/
│ └── REFERENCE.md
└── assets/
└── config-template.json
三个可选目录的用途,文档有一张表:scripts/ 放 agents 可以运行的可执行代码,references/ 放按需加载的补充文档,assets/ 放模板、图片、数据文件这类静态资源。文档同时给了一条组织建议:把主 SKILL.md 保持聚焦,详细的参考材料挪到单独文件里——理由是它自述 agents 会渐进式加载资源,只在需要时才读。
SKILL.md 的 YAML frontmatter 字段表,cursor.com/docs/skills 列了五个:
| 字段 | 必填 | 文档写明的含义 |
|---|---|---|
name | 是 | 技能标识符,只允许小写字母、数字和连字符,必须与父文件夹名一致 |
description | 是 | 描述这个 skill 做什么、什么时候用;agent 据此判断相关性 |
paths | 否 | glob 模式,把 skill 限定到匹配的文件;接受逗号分隔的字符串或列表 |
disable-model-invocation | 否 | 为 true 时,只有显式用 /skill-name 调用才会被包含 |
metadata | 否 | 任意键值映射,放附加元数据 |
name 必须与父文件夹名一致这条容易翻车:你把文件夹改了名却忘了改 frontmatter,这是文档写明的约束,不是我们的猜测。description 那条注意它的定位——文档写明它是 agent 用来判定相关性的依据(“Used by the agent to determine relevance”),也就是说它不是写给人看的说明文字,而是这个 skill 什么时候会被拿出来用的输入。至于 agent 具体怎么用它做判定,文档没有说明,这里也不替它补。
加载条件:什么时候它才会出现在 Agent 面前
这是本篇真正的落点,也是最容易和 rules 搞混的地方。文档写明的路径有这么几条:
一、默认走”自动判断”。 Cursor 启动时自动发现 skills 并把可用技能呈现给 Agent,由 agent 根据上下文决定什么时候相关。注意这和 rules 的”每次对话都带上”不是一回事。
二、paths 收窄作用域。 加了 paths 之后,只有 agent 在读写匹配的文件时这个 skill 才会被呈现出来。文档给的两种写法都能用,列表:
---
name: react-component-patterns
description: Conventions for writing React components in this codebase.
paths:
- "**/*.tsx"
- "packages/ui/**/*.ts"
---
或者一个逗号分隔的字符串:
---
name: python-style
description: Style rules for Python files.
paths: "**/*.py, scripts/**/*.py"
---
文档写明 paths 用的是标准 glob 语法,不设 paths 就表示不管打开哪些文件都可用。另外一条兼容性说明值得记一笔:旧的 globs 字段仍然作为 fallback 被接受,但新 skill 应该用 paths。
三、嵌套目录自带作用域。 目录可以按类别、团队、领域分子目录,Cursor 会递归遍历 skills 根目录,捡起它找到的任何 SKILL.md。这里有一条反直觉的规则:类别文件夹纯粹是组织用的,skill 的身份来自包含 SKILL.md 的那个文件夹,不是它上面那层类别。也就是说 .cursor/skills/shipping/land-it/SKILL.md 里的 name 要写 land-it,不是 shipping。
更进一步,仓库里任何位置的 .cursor/skills/(或 .agents/skills/)都会被捡到,monorepo 可以把 skill 和它适用的包放在一起:
my-monorepo/
├── .cursor/skills/ # repo-wide skills
│ └── land-it/SKILL.md
└── apps/
└── web/
└── .cursor/skills/ # app-specific skills
└── deploy-web/SKILL.md
文档写明,嵌套项目目录里的 skills 会自动被限定到那个目录下的文件——上例里 deploy-web 只在 agent 处理 apps/web/ 下的文件时才被呈现,而仓库级 .cursor/skills/ 里的到处都可用。这种嵌套目录不需要再设 paths,文档明说了它与 paths 效果相似、不必重复配置。
四、彻底关掉自动调用。 把 disable-model-invocation 设成 true,这个 skill 就退化成传统斜杠命令的行为:只有你在聊天里显式输入 /skill-name 才会进上下文。
五、手动触发的两种方式。 cursor.com/help/customization/skills 写的是:输入 / 加技能名运行(例子是 /write-tests),或者输入 @ 选中它作为上下文附加。cursor.com/docs/skills 那页只写了 / 这一种,没有提 @。
一个把几条组合起来的示例:
---
name: deploy-web
description: Deploy the web app to staging. Use when deploying code or when the user mentions releases.
paths: "apps/web/**/*.ts"
disable-model-invocation: true
---
以上为按官方文档中的参数语义组合的示例,未经实测,以官方文档与 --help 的实际输出为准。
边界:这几处别当成保证
- 两页文档的
SKILL.md写法不一致。cursor.com/docs/skills写的是”每个 skill 在一个带 YAML frontmatter 的SKILL.md文件里定义”,且name、description标为必填;而cursor.com/help/customization/skills里手动创建那一节给的示例是一个完全没有 frontmatter 的SKILL.md(只有一个标题和四步列表)。两处放在一起就是这样,不一致的原因这两页都没有解释,我们也不替它解释——按必填口径写 frontmatter 是更保守的做法。 - 迁移不是全量的。
/migrate-to-skills转换的是两类:alwaysApply: false(或未定义)且没有定义globs的动态规则,以及用户级和工作区级的斜杠命令(转成disable-model-invocation: true以保留显式调用行为)。文档明说:alwaysApply: true或带具体globs的规则不迁移,因为它们有明确的触发条件、与 skill 行为不同;用户规则也不迁移,因为它们不存在于文件系统上。 - 脚本的执行是有边界的。 文档说脚本可以用任何语言写——Bash、Python、JavaScript 或 agent 实现支持的任何可执行格式,agent 读取说明后执行被引用的脚本。它同时给了写法建议:脚本应自包含、带有用的错误信息、优雅处理边界情况。这里要提醒的是:这意味着 skill 里的脚本是会在你的环境里被真正执行的,权限与安全边界只写文档能核到的部分,其余请结合自身环境评估。
- 文档没有说明的部分。 skills 被自动判定为”相关”的具体机制、
description要写多长才够、多个 skill 同时匹配时怎么排序——这两页都没有说明,不要按直觉补。
怎么确认配对了
按文档能核到的手段有三条,从便宜到贵:
- 对文件结构。 文件夹名与 frontmatter 的
name是否逐字一致(小写字母、数字、连字符);SKILL.md是不是直接躺在那个同名文件夹里,而不是多包了一层。 - 看集中入口。
cursor.com/docs/skills写明可以在侧栏的 Customize 里进入 Skills 查看已发现的技能,来自 plugins 或项目的 skill 会和 rules 一起出现在 Agent Decides 分组下。我们没有截图,不描述它长什么样,只说文档写了有这么一处可以确认”发现到了没有”。 - 走手动调用兜底。 按文档,输入
/搜技能名能不能搜到,是”被发现了”与”没被发现”最直接的分界。搜得到但自动场景下没用上,那是相关性判断的问题,多半要回头改description或paths;搜都搜不到,问题在目录和文件名,不在描述。
另外别忘了 paths 与嵌套目录这两个作用域是会互相叠加错觉的:一个放在 apps/web/.cursor/skills/ 下的 skill 本来就只在那个目录范围内被呈现,如果你又给它写了一个指向别处的 paths,按文档的语义它就更难被触发。要么靠目录位置,要么靠 paths,别两头下注。
Agent Skills 官方文档自述是一个开放标准,也正因为如此,Cursor 这边的目录发现规则、兼容目录列表、迁移条件都是产品侧的实现约定,随版本变动——这几条尤其要按官方文档最新内容为准,别照着半年前的笔记配。
本文依据 Cursor 官方文档(cursor.com/docs 与 cursor.com/help)于 2026-08-18 的公开内容整理。
该产品闭源,本文只复述官方文档写明的机制,不推断其内部实现;
我们没有对文中涉及的功能做过实测,因此不涉及界面外观、操作手感与运行速度的任何描述。
该产品迭代频繁,文中涉及的设置项与命令随版本变动,请以官方文档最新内容为准。
本文不涉及订阅价格、额度与模型清单,相关信息请以官方定价与模型说明页为准。
安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。