ByteNoteByteNote

字节笔记本

2026年8月29日

Skills 和 Cursor Rules 其实是同一套抽象

API中转
¥120

很多人把 Skills 和 Cursor Rules 当成两套互相替代的产品。底层其实是同一件事:一段带触发条件的 Markdown,在对的时候被塞进代理的上下文。差别几乎只在「什么时候塞进去」,以及旁边能不能挂脚本和参考文件。

搞清这件事,仓库里的规则就不会一边写 .mdc、一边再抄一份 SKILL.md

同一套东西,两套文件名

两边都是「元数据 + 正文」:

  • 元数据告诉运行时什么时候该加载(始终、按文件、按描述、手动)
  • 正文是给模型看的说明,加载之后就是普通上下文

Cursor 的 Project Rule 是 .cursor/rules/*.mdc

markdown
---
description: 后端 RPC 服务约定
alwaysApply: false
---

- 每个服务单独放 `src/services/`
- 边界处校验输入,再往里传
- 错误返回带 `code` 和 `message` 的对象,不要抛裸字符串

Agent Skill 是一个目录加 SKILL.md,开放标准在 agentskills.io,参考实现在 anthropics/skills

markdown
---
name: rpc-conventions
description: 写或改后端 RPC 服务时用。覆盖目录、校验和错误格式。
---

- 每个服务单独放 `src/services/`
- 边界处校验输入,再往里传
- 错误返回带 `code` 和 `message` 的对象,不要抛裸字符串

正文可以一字不差。换的是包装:Rule 是单文件加 alwaysApply / globs;Skill 是文件夹,还可以带 scripts/references/assets/。Cursor 文档也把 Skills 写成按需发现的步骤型 how-to,Rules 写成始终生效的声明式约束。见 Cursor RulesCursor Agent Skills

真正差在加载时机

模型不会跨请求记住你昨天说过的规矩。Rules 和 Skills 都是在补这块,只是付费方式不同。

触发Cursor RuleAgent Skill
每条对话都带alwaysApply: true不这么干(只有 name + description 常驻)
打开某些文件才带globs: src/**/*.tsxpaths(Cursor 扩展字段,按文件才露出)
代理自己判断alwaysApply: false + descriptiondescription 对上任务再读全文
你手动点名聊天里 @rule-name/skill-name

Skill 的加载分三步,规范里叫渐进披露:启动时只读 name 和 description;任务对上了再读 SKILL.md 全文;需要时再打开旁边的脚本或参考文件。一百个技能只占一小段目录,不会把窗口撑满。

alwaysApply: true 的 Rule 没有这层缓冲:全文每次都进上下文。所以长流程、检查清单、带脚本的发版步骤不该写成 Always Apply。Cursor 自己也提供 /migrate-to-skills:把「Apply Intelligently」、没有 glob 的动态 Rule,以及 slash command,收成 Skill。alwaysApply: true 和带 glob 的 Rule 不会被迁走,因为它们的触发条件和 Skill 不一样。

仓库里怎么放

常见位置(项目级优先于用户级):

用途路径
Cursor 项目规则.cursor/rules/*.mdc
Cursor 技能.cursor/skills/<name>/SKILL.md
跨客户端技能.agents/skills/<name>/SKILL.md
用户级技能~/.cursor/skills/~/.agents/skills/
短全局说明仓库根的 AGENTS.md(或嵌套目录里的同名文件)

新技能优先写进 .agents/skills,Claude Code、Cursor、Codex、Gemini CLI 这类兼容客户端都能扫到,不必维护三份拷贝。旧的 .cursor/rules 不用删光:该常驻的继续当 Rule。

Team Rules(Cursor 团队后台)是另一条线:纯文本、可强制、优先级高于项目规则。它不走 .mdc 目录,也不被 /migrate-to-skills 处理。组织级红线放那里,项目流程放仓库。

怎么选:四条就够

按「这次对话必须带着吗」选,不要按品牌选。

  1. 每次请求都要守住的短约束 → Always Apply Rule。版权头、禁止改 dist/、提交信息格式。控制在几十行,官方建议单条 Rule 别超过 500 行,大了就拆。
  2. 只在某类文件上成立 → 带 globs 的 Rule。组件命名、CSS 模块位置、migration 必须有 up/down。打开匹配文件才注入,比 Always Apply 便宜。
  3. 偶尔才走的多步流程 → Skill。发版检查、修某个内部 SDK、按仓库规矩开 PR。正文可以长,旁边可以挂脚本;用不到时几乎不占窗口。
  4. 你想自己决定何时跑、代理不许自作主张 → Skill,并加上 disable-model-invocation: true,只用 /skill-name 触发。部署、发消息、任何有副作用的清单都适合。

AGENTS.md 留给 clone 下来就要知道的短事实:测试命令、分支策略、绝对不要做的事。专项流程塞进去,无关任务也会一直背着。

动手:把一条动态 Rule 收成 Skill

假设你已经有一条「智能应用」的发版规则,没有 glob。frontmatter 只写 description(例如「把当前分支发到 staging 时用」),alwaysApply 为 false。正文三步:跑测试、打 tag 推到 origin、CI 绿了再切 staging。

这正是 Cursor 内置 /migrate-to-skills 会收走的类型。也可以手写:在仓库建 .agents/skills/ship-staging/SKILL.md,name 用 ship-staging,description 写清何时用、何时不要用(不要在只改文案时触发)。正文同样三步,失败就停,不要自己发明回滚。

description 是路由键。写「什么时候该用」,最好带一句「什么时候不该用」。代理只靠这句话决定要不要打开全文。空泛的「帮助部署」几乎等于没写。

需要脚本就放在同目录的 scripts/ 下,正文用相对路径指过去,例如 ship-staging/SKILL.md 旁边放 scripts/smoke.sh。Cursor 还可以给 Skill 加 paths 字段(如 src/**/*.ts),只在碰这些文件时才露出,行为和带 glob 的 Rule 接近,但全文仍然是按需加载。

常见踩坑

  • Always Apply 里贴完整风格指南。模型本来就会常见风格,重复的约定交给 linter。Rule 只写你们仓库特有的、而且反复踩过的坑。
  • 同一段说明既当 Rule 又当 Skill。迁完删掉旧的动态 Rule,否则描述对上时会加载两次。
  • Skill 正文复述代理已经会的工具。别写「用 git 提交」这种常识。写你们团队的验收:测哪些、谁有权推、失败怎么回。
  • 密钥写进文件。Rule 和 Skill 都会进 Git。地址和 token 走环境变量,文件里只写怎么读。
  • description 写成长文案。目录阶段只看这一段。太长会被截断,关键词丢了就不会被点到。把触发场景放第一句。

改完在一次干净会话里试两句:一句应该触发(把这支分支发 staging),一句不该触发(把 README 错别字改了)。Skill 只在第一句被打开,才算路由写对了。Cursor 里也可以问它当前加载了哪些 Rule / Skill,对上文档再提交。

和 MCP、命令怎么并列

三层别搅在一起:

  • MCP:给代理新的手,连数据库、浏览器、内部 API。
  • Rules / Skills:给代理说明书。前者常驻或按文件,后者按任务。
  • Slash command:在 Cursor 里正在收进 Skill(加上 disable-model-invocation 就能保留「只有你能点」)。Claude Code 也把 .claude/commands/ 和 Skill 合成同一套斜杠命令。

所以「Skills 取代了 Rules」这句不成立。被收走的是那种其实是流程、却写成了动态 Rule 的文件。真正的常驻约束还该是 Rule。开放标准那一层,则让同一份 SKILL.md 能在 Cursor、Claude Code 和其他兼容客户端里复用,官方目录见 anthropics/skills

落地时按这个顺序就行:先把 Always Apply 砍短,再把带步骤的动态 Rule 迁成 Skill,新流程直接写进 .agents/skills。同一套抽象,两套触发,仓库里只维护一份正文。

分享: