把技能写成 .cursor/skills/<名称>/SKILL.md,name 与目录名相同。助手按 description 决定要不要用,所以用第三人称在 description 里写两件事:做什么、在什么任务里用。长说明放进同目录的 reference.md,SKILL.md 只留步骤。
三种情况下会打开这一页:同一类改动(例如改检索)每次都要从头讲一遍做法 → 照「示例:改检索或助手回答」抄 SKILL.md 与 reference.md 两件套;技能从来没被自动用过,或者不该自己跑的流程自己跑了 → 到「常见错误」的现象表里对一行,多数是 description 写成名词短语,或漏了 disable-model-invocation: true;从 Claude Code 或 TraeCode 搬过来 → 先逐行核「技能在三处」。
两处写错都让它「文件在、但不触发」:description 写成「检索规范」这种没有动作、没有场景的名词短语,助手判断不出时机;该由人点名的流程没加 disable-model-invocation: true,助手会在相关任务里自己套用。
这次任务出现时,助手只看 description,能判断出该读这个技能吗?
判断不出,技能放在仓库里也等于没有。把 description 补成两件事——做什么、在什么任务里用;缺后半句的,助手只能靠猜。
技能是「任务一出现就该想起」的步骤,它和命令的区别只在 disable-model-invocation 这一个字段:加了就是命令(只认人输入斜杠),不加才是技能。description 是唯一的触发依据,在里面写清两件事:做什么、在什么任务里用。
reference.md,按需读。description 写成「修改检索或基于检索结果的回答时使用,包括命中来源、无依据判定」;正文用编号列步骤;细节放 reference.md。
description 只写成名词「检索规范」;把字段清单和阈值全塞进 SKILL.md;把产品面向用户的功能写成技能;给人点名的流程忘了加开关。
和产品里的「技能」分开:面向用户的产品能力写在需求和接口说明里。本页的技能是仓库里给编程助手的步骤,不把产品能力写成 .cursor/skills/。
三家技能目录的路径规律一致,差别在长说明放哪、以及 TraeCode 多出来的兼容开关。从别的工具搬过来时逐行核这张表。
| 项 | Claude Code | Cursor | TraeCode |
|---|---|---|---|
| 项目位置 | .claude/skills/<名称>/SKILL.md | .cursor/skills/<名称>/SKILL.md | .trae/skills/<名称>/SKILL.md |
| 个人位置 | ~/.claude/skills/ | —— | ~/.trae-cn/skills |
| 长说明放哪 | 正文留步骤 | 同目录 reference.md | 同目录其他文件 |
| 触发依据 | description | description,第三人称写「做什么、在什么任务里用」 | description |
| 重名与兼容 | —— | —— | 规范里的 .agents/skills/ 要另开「设置 → 技能与命令 → 导入设置」的开关;与 .trae/skills/ 重名时用后者 |
Cursor 这一列的关键是要把长说明挪到 reference.md。这是它和另两家唯一的结构差异,也是本组示例里 trace-retrieval 要配一个 reference.md 的原因。
SKILL.md 只留五步;字段清单、判定阈值、边界都放进同目录的 reference.md。
正文只有步骤。助手在这一步不需要读字段细节。
--- name: trace-retrieval description: 修改检索或基于检索结果的回答时使用。包括命中来源、无依据判定,以及只引用当前用户范围内的切片。 --- 1. 检索条件中的 scope_id 来自当前会话,不读取请求中的 scope_id。 2. 若使用向量库,点的 id 与数据库切片 id 相同,payload 带上 scope_id。 3. 没有命中时返回无依据,本轮不调用对话模型。 4. 命中之后,回答只使用这些切片中的句子,并带上出处。 5. 用两个所属范围各看一次:当前范围能读到,其他范围读不到。
和 SKILL.md 同一个目录。步骤里说不清的字段和阈值写在这里。
# 检索改造参考 ## 字段 - 切片表:id、scope_id、content、source - 向量库点的 id 与切片表 id 相同 - payload 至少带 scope_id 与 source ## 判定 - 相似度阈值:本仓库取 0.75,低于它视作没有命中;具体取值以本项目实测为准 - 没有命中时返回「无依据」,本轮不调用对话模型 - 命中之后,回答里的每句话都要能在返回的切片里找到 ## 边界 - 只改检索或回答时读这份 - 改表结构属于迁移,另有规则(见 .cursor/rules/),不在本技能范围
写完拿真实任务验一次:提一个改检索的请求,看助手有没有自动用上这个技能。这件事需要人点名才跑时,它就该是命令——在 SKILL.md 里加上 disable-model-invocation: true,见 命令。
技能不触发时没有报错,从现象反查。
| 现象 | 原因 | 修法 |
|---|---|---|
| 明明有改检索的技能,助手每次都自己现编一套做法 | description 写成名词短语「检索规范」,没有动作也没有使用场景,触发判断不中 | 改写成第三人称、写清两件事:「修改检索或基于检索结果的回答时使用,包括命中来源、无依据判定」 |
| 本该人点名才跑的流程,助手在相关任务里自己执行了 | 技能没加 disable-model-invocation: true,被当成可自动调用的技能 | 在前置元数据加 disable-model-invocation: true,它就变成命令 |
SKILL.md 写到 400 行,助手跳着读、漏掉中间步骤 | 整份 SKILL.md 就是进上下文的内容,太长会丢信息 | 正文只留步骤;字段清单、阈值、边界移到同目录 reference.md |
把「给用户看的问答功能」写成了 .cursor/skills/ 下的一份技能 | 技能是给编程助手的步骤,不是产品能力 | 产品能力回到需求和接口说明;技能里只留「怎么改这类代码」的步骤 |
TraeCode 里把技能放在 .agents/skills/,对话里调不到 | 该目录要另开「设置 → 技能与命令 → 导入设置」的开关;与 .trae/skills/ 重名时用后者 | 打开那个开关,或直接放到 .trae/skills/ 下 |