返回文章列表

我是怎么给 Cursor 写 Skills 的

·6 分钟阅读·#Cursor#AI#Skill#效率
目录 (8)

我是怎么给 Cursor 写 Skills 的

上周我给自己配了一个前端性能优化的 Agent Skill,用下来感觉挺好使的——问到"我的页面首屏慢"这类问题,AI 直接给出带具体数值的方案,不再是那种"可以考虑使用懒加载"的废话建议。

但我第一次写 skill 的时候,完全不知道该怎么下手,踩了不少坑。这篇文章就记录一下我的思考过程,以及为什么我最终做出了这些设计决定。


先搞清楚 Skill 是怎么工作的

在动手之前,我花了点时间理解 Skill 的工作机制,这一步很关键,不然后面很多决策都会做错。

简单说:Cursor Agent 在回答你的问题时,会扫描 ~/.cursor/skills/ 目录(个人 skill)或 .cursor/skills/(项目 skill),判断哪个 skill 和当前对话相关,然后把相关 skill 的内容悄悄塞进对话上下文里。整个过程对你来说是无感的,你只需要写好问题,AI 自己会去"拿手册"。

我的 frontend-performance skill 最终长这样:

~/.cursor/skills/
└── frontend-performance/
    ├── SKILL.md        ← 主文件(必须有)
    ├── metrics.md      ← 性能指标详解
    ├── checklist.md    ← 优化项清单
    └── patterns.md     ← 代码模板

但我刚开始根本没想到要拆这么多文件,一开始我把所有东西全塞进了 SKILL.md……


我踩的第一个坑:把 SKILL.md 写成了百科全书

最初版本的 SKILL.md 超过了 800 行。我把每个优化方向的完整代码、每个指标的详细解释、每种缓存策略的完整实现,全都塞进去了。逻辑是:内容越全越好嘛,这样 AI 什么都能查到。

结果发现问题很严重:

每次问任何性能相关的问题,AI 都要处理这 800 行内容。上下文窗口是有成本的,这 800 行把本来应该留给对话本身的空间全占掉了。更糟的是,AI 处理超长文档时有个已知问题叫"Lost in the Middle"——中间段的信息容易被忽略。我的 skill 越来越全,但 AI 给出的回答质量反而没变好。

想明白这个之后,我做了一个重要的决定:SKILL.md 只放"导航",不放"实现"。

判断某段内容该不该留在主文件的标准只有一个:AI 在回答 80% 的性能问题时都需要用到它吗?

  • 优化工作流(量化→定位→施策→验证):,每次都用
  • Core Web Vitals 目标值表:,判断好坏的基准,高频查
  • 每个指标的采集代码:拆出去,只有在"帮我写监控"时才需要
  • Service Worker 完整实现:拆出去,只有在"帮我做缓存"时才需要

拆完之后 SKILL.md 只剩 255 行。主文件变成了真正的指挥中心,细节在子文件里按需加载。


第二个坑:description 写成了给人看的说明

我第一版 description 是这样的:

description: 帮助用户优化前端页面性能

写完觉得挺好的,简洁清晰。然后我发现这个 skill 根本不触发。

问题在于:description 不是给人看的,它是 AI 用来决定"要不要加载这个 skill"的检索索引。 AI 会根据你说的话,和每个 skill 的 description 做语义匹配。我写了 10 个字,能覆盖的语义空间太小了。

当用户说"我的 LCP 分数很差",AI 要判断这句话和"帮助用户优化前端页面性能"有多相关——答案是:还好,但不够强。如果 AI 同时有其他 skill 的 description 看起来更匹配,就会优先加载那个。

正确的写法要做两件事:说清楚能做什么(WHAT),再把**用户真实会说的触发词(WHEN)**全都塞进去:

description: 审计并实现 Web 前端性能优化,覆盖 Core Web Vitals、加载性能、
  运行时性能、渲染优化、资源优化、缓存策略、React/Vue 组件优化、
  Bundle 体积优化、监控埋点。
  当用户提到性能优化、首屏加载、白屏、卡顿、LCP/INP/CLS、
  Lighthouse 评分、长任务、包体积大、懒加载、缓存、SSR/SSG 等
  问题时使用此技能。

还有一个细节:description 必须用第三人称写,因为它会被直接注入到 system prompt 里,AI 以第三人称描述自己的能力("该技能审计并实现……"),用"我"或"你"会显得很奇怪。字数上限是 1024 字符,尽量写满。


内容写什么:给决策,不给教程

这是我花了最长时间才想明白的一点。

最开始我在 skill 里写了这样的内容:

Web Worker 是一种在后台线程中运行 JavaScript 的技术,它不会阻塞主线程,因此可以用来处理复杂计算……

然后我反应过来:AI 早就知道什么是 Web Worker 了。我在教一个已经是专家的人背书,毫无意义。

Skill 该写的是 AI 通常不会主动想到的决策规则

CPU 密集型任务使用 Web Worker
避免在主线程执行 > 50ms 的同步计算

还有一类非常有价值但经常被忽视的内容:诊断表

AI 在没有这个表时,遇到"页面卡顿"会给出一大串通用建议——每一条都对,但没有重点。有了诊断表,AI 可以直接聚焦:

用户描述 可能原因 优先排查
列表滚动卡顿 DOM 节点过多/无虚拟化 虚拟列表
点击响应慢 主线程阻塞/长任务 Long Tasks、INP
页面跳动 图片无尺寸/字体替换 图片宽高、font-display

这个表让 AI 从"给所有可能的建议"变成"直接命中最可能的根因",是 skill 里投入产出比最高的内容。


文件怎么命名:按"什么时候用",不按"里面有什么"

拆出去的三个文件我最初想叫:core-web-vitals.mdoptimization-list.mdcode-examples.md

改成现在这样之后:metrics.mdchecklist.mdpatterns.md

区别在于:前者描述的是内容,后者描述的是使用场景。AI 在判断"要不要去读这个文件"时,文件名是重要的提示信号。metrics.md 传达的意思是"当你需要关于指标的信息时来找我",比 core-web-vitals.md 更清晰。

还有一条铁律:文件引用只能一层深。SKILL.md 可以引用 metrics.md,但 metrics.md 不能再引用其他文件——AI 不会递归读取,嵌套引用的内容大概率读不到。


几个常见坑的总结

写完之后回头看,有几个坑特别容易踩:

description 太短、太模糊,skill 永远不触发。我见过有人写"前端工具集",这种 skill 基本废了。

主文件塞了太多完整代码,变成代码手册而不是导航。200 行 Service Worker 实现放在 SKILL.md 里是在害 AI,放在 patterns.md 里才对。

写了时效性强的信息,比如"截至 2024 年 Chrome 115+ 支持 scheduler.yield()"——这类话过一年就过期了。改成"较新浏览器支持 scheduler.yield(),兼容方案用 MessageChannel",稳定得多。

嵌套引用,这个必须避免:

# ❌ AI 大概率读不到 animation-tricks.md
SKILL.md → advanced.md → css-details.md → animation-tricks.md

# ✅ 扁平结构,一步到位
SKILL.md → patterns.md

写完怎么判断质量

我用三个问题自测:

去掉这个 skill,AI 的回答会变差吗? 如果答案是"不会",说明 skill 只是重复了 AI 已知的东西,没有价值。

主文件超过 500 行了吗? 超了就继续拆。信息密度要高,不是行数要多。

用户说了触发词,skill 真的会加载吗? 拿你预期的用户提问,去 description 里检查覆盖情况。"我的页面首屏白屏"这句话——"白屏"这个词在你的 description 里吗?


最终的文件结构

~/.cursor/skills/frontend-performance/
├── SKILL.md       ← 导航 + 速查 + 诊断表
├── metrics.md     ← 指标采集代码 + 工具对比 + 性能预算
├── checklist.md   ← 10类60+条优化清单,可直接复制跟踪
└── patterns.md    ← 10个带 TypeScript 类型的完整代码模板

现在再问"我的页面 LCP 很差怎么办",AI 会加载 SKILL.md,给出聚焦的优化方向。接着如果我说"帮我写采集 LCP 的监控代码",它会去读 metrics.md,给出完整实现。用到什么,读什么,不浪费上下文。


这个 skill 写下来花了大概两个小时,但之后每次问性能相关的问题省的时间远不止这个数。如果你也在用 Cursor,很推荐花时间给自己高频用到的领域做一套 skill——写的时候会逼着你把这个领域的知识真正系统化一遍,这个思考过程本身就值得。