在 .claude/skills/<名称>/SKILL.md 放项目技能,个人技能放 ~/.claude/skills/;本课小组共用的放项目目录。Claude 靠 description 决定什么时候加载这个技能,所以正文只留步骤,长说明拆到同目录的其他文件。人必须点名才执行的流程,加 disable-model-invocation: true,那是一份命令,见 命令。
会在三种情况下打开这一页:同一段步骤讲了第三遍,想固化成技能 → 按「description 决定加载,正文决定结果」里的四步建;技能建了却从没被自动加载 → 看「技能不被加载或不被照做的四种现象」;从 Cursor 或 TraeCode 迁技能过来 → 看「技能在三个工具里的位置与触发」。
最容易写错的是 description:写成「一个用于处理检索的技能」这种自我介绍,它没告诉 Claude 在什么任务里用,技能就永远不会被自动加载;反过来,把全部细节塞进 description,正文步骤又被挤掉。判断标准只有一条:description 说清「做什么、什么任务里用」,正文说清「分几步、每步看哪个文件」。
把 description 念给同组同学听,他能说出什么任务会触发这个技能吗?
答「不能」,它永远不会被自动加载。把它改成第三人称、写清触发任务,再开一轮新对话实测一次。
一个技能的成败分成两段:先被选中,再被照做。两段对应文件里两个不同的部分,写错哪一段,问题的表现不一样。
.claude/skills/<名称>/SKILL.md,目录名用小写字母与连字符,文件名必须是全大写的 SKILL.md。description 写「修改检索或基于检索结果的回答时使用。包括命中来源、无依据判定,以及只引用当前用户范围内的切片。」正文写成编号步骤,判据指向仓库里的具体文件。
description 写成「一个处理检索的技能」这种自称;把 800 字背景放进正文把步骤淹没;用技能装载面向用户的产品功能;同一流程既写技能又写命令两份。
边界:技能靠 description 触发,所以它管得住「该做的时候做」,管不住「不该做的时候不做」。需要百分百拦住的动作,交给 钩子。
目录名只有一字之差,长说明放哪里、能不能被手动点名,三处也不同。迁技能之前先在这张表里对一遍,迁完开一轮新对话确认它还被加载。
| 项 | 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/ 重名时用后者 |
本课只用项目目录一处,不写个人目录,避免同一个技能在两台电脑上版本不同。跨工具复用同一条步骤时,把 description 原样保留,三处对它的读法一致。
第一份按「按登录用户隔离数据」的项目写,步骤固定、判据指向具体字段。第二份是常见错法,description 写成自我介绍,正文把说明和步骤混在一起。照第一份建,第二份不要抄。
这份没有 disable-model-invocation,所以助手在改到检索或回答时会自己加载它。第 5 步是它的验证方式,照着做一次就能判断这次改动对不对。
--- name: trace-retrieval description: 修改检索或基于检索结果的回答时使用。包括命中来源、无依据判定,以及只引用当前用户范围内的切片。 --- 1. 检索条件中的 scope_id 来自当前会话,不读取请求中的 scope_id。 2. 若使用向量库,点的 id 与数据库切片 id 相同,payload 带上 scope_id。 3. 没有命中时返回无依据,本轮不调用对话模型。 4. 命中之后,回答只使用这些切片中的句子,并带上出处。 5. 用两个所属范围各看一次:当前范围能读到,其他范围读不到。 只改检索与回答,不动数据库表结构。表结构改动走数据库迁移。
这份的 description 是自称,没写触发任务;正文先讲一段背景再讲步骤,助手执行时容易跳过「无依据」那一步。不要抄它。
--- name: helper description: 一个用于处理检索的技能。 --- 检索是产品的核心能力。我们的检索经过多次迭代,参考了多篇资料, 也踩过不少坑。下面说明一些注意事项。 注意无依据的情况也要处理好,具体怎么做可以灵活判断。 其他细节见代码。
反例的修法:把 description 改成「修改检索或基于检索结果的回答时使用」;正文删掉背景,把「没有命中时返回无依据,本轮不调用对话模型」写成编号步骤第 3 步,并补上第 5 步的验证方式。
技能的两段各自会出问题:前两种是没被选中,后两种是被选中了却没照做。按「现象 → 原因 → 修法」对号入座,改完开一轮新对话再验一次。
| 现象 | 原因 | 修法 |
|---|---|---|
| 技能从没被自动加载,每次都要人手动点名 | description 写成了「一个用于处理检索的技能」,没说在什么任务里用 | 改成第三人称并写清触发任务:「修改检索或基于检索结果的回答时使用……」,再开新对话验证 |
| 助手从没提到过这个技能,像是没建过 | 目录或文件名不符,例如文件写成 skill.md,或目录写成 .claude/skill/ | 确认路径为 .claude/skills/<名称>/SKILL.md,文件名全大写;用 ls .claude/skills 逐个核对 |
| 技能被加载了,但步骤 3(无依据不调用对话模型)经常被跳过 | 正文把背景说明和步骤混在一起,步骤被淹没 | 正文只留编号步骤,背景拆到同目录其他文件,正文用一行指向它 |
该由人点名的流程,助手没等人叫就自己跑了;或反过来,输入 / 找不到它 | disable-model-invocation: true 漏写或多写,这一行是命令与技能的唯一区别 | 人点名的加上这行,助手自触发的删掉这行;改完开一轮新对话确认触发方式 |