一个技能就是一个文件夹,里面一个 SKILL.md 是入口,其余都是被它点名的配角。 这一篇把文件夹拆开:frontmatter 管什么、正文写几段、被引用的文件怎么放、两个作用域谁覆盖谁。
上一篇把技能跑通了,这一篇回来看结构。 结构清楚了,后面写复杂技能(带模板、带脚本、带参考资料)才不会乱。 这也是第 6 章工程化的地基——那边讲的「可扩展」「可容错」,全靠这里的目录约定撑着。
一、一个文件夹,一个文件
技能的物理形态简单到有点意外:一个文件夹,里面一个 SKILL.md。 文件夹名通常就是技能名,SKILL.md 是唯一入口。除此之外什么都没要求。 但真干活的技能,文件夹里往往不止一个文件。常见的是四样。
| 文件 | 作用 | 谁读它 |
|---|---|---|
| SKILL.md | 入口:说明什么时候用、怎么干 | 智能体先读它 |
| references/ | 参考资料:风格指南、规范、案例 | 正文点名才读 |
| templates/ | 模板:输出要套的骨架 | 正文点名才读 |
| scripts/ | 脚本:确定性计算、格式校验 | 正文点名才跑 |
这四样里,只有 SKILL.md 是必须的。另外三样都是「等技能变复杂了再加」。 新手最常见的错误是一上来就四样齐全,结果 SKILL.md 里塞了三个还不存在的引用。 正确的顺序是反过来的:先只有 SKILL.md,跑到不顺了,再拆出参考文件。
二、frontmatter 的三行
文件开头那三行 --- 包起来的部分叫 frontmatter。它只有两个必填字段。
name 是技能名,通常和文件夹名一致。description 是一句话广告词。
第三个字段视平台而定,有的支持 license、有的支持 allowed-tools。不写也行。
description 是这一整份文件里最重要的一行字。
它不进正文、不参与执行,只干一件事:在几十个技能里,让模型认出「这次该用我」。
所以它要写成「什么情况下用」,不是「我是什么」。
对比一下同一件事的两种写法。
差的写法:「会议纪要技能」。
好的写法:「把带说话人前缀的会议转承稿整理成四段式纪要,当用户给出会议记录、录音转写稿、讨论稿,
要求整理成纪要或待办时使用」。
后者把触发场景写进去了:会议记录、录音转写、讨论稿、纪要、待办。
这些词就是模型判断时的线索。一个都没有,它就认不出来。
三、正文写三段:何时用、怎么做、别做什么
正文没有格式要求,Markdown 就行。但好用的技能,正文结构高度一致,都是三段。 第一段,何时用。什么输入、什么场景。这一段是给「已经选中了但还在犹豫」的模型看的。 第二段,怎么做。步骤,编号列出来。每一步要么是可执行的动作,要么是可检查的产出。 第三段,别做什么。边界,用否定句。这是最容易被省略、又最能救命的一段。 为什么第三段最重要?因为模型遇到没写清楚的边界时,默认行为是「自由发挥」。 而自由发挥在结构化任务里的表现,通常是加内容——加它觉得你可能需要的东西。 「不编造没出现过的数字」,这句话能挡掉的错误,比十条「要准确」加起来还多。 三段写下来,一份技能正文大概 30 到 60 行。超过 100 行,多半是掺了不该进来的东西。
四、被点名的文件和脚本
references、templates、scripts 这三样,只有在 SKILL.md 正文里被点名,才会被用上。
放在那儿不提,等于没有。这一点跟很多人想的不一样。
点名的写法很朴素,就是在正文里写清楚「去读哪个文件」。
第一步,先读 references/style-guide.md,记住禁用词表。
这句话的作用不只是告诉模型去哪读,还告诉它什么时候读。
时机很重要:风格指南要在动笔前读,模板要在动笔前读,校验脚本要在写完之后跑。
顺序错了,读到的信息用不上。
至于 scripts,它的价值在于把确定性的事从模型手里拿走。
「检查有没有禁用词」这种事,写十行脚本比写十句提示词可靠得多。
这一课第 3 章会专门讲「哪些活交给模型、哪些交给脚本」,这里先记住这个分工的存在。
五、全局与项目:同名谁赢
技能能放在两个地方:用户目录(全局)和项目目录(项目级)。 全局的对所有项目生效,项目级的只在这个仓库里生效。 两边都有同名技能时,项目覆盖全局,而且是整份覆盖,不是合并。 这条规矩的设计意图很清楚:团队默认值放全局,某个项目要特事特办,就在自己仓库里改。 改的人不用去动别人的机器,也不用说服所有人。 代价是容易混乱:同事装了全局版,你装了项目版,两个人看到的行为不一样。 所以团队里推技能,项目级优先,全局只放那种「所有项目都一模一样」的东西。
六、本章小结
第一章就讲了三件事:环境怎么搭、第一个技能怎么跑通、文件夹长什么样。 三件事背后是同一个判断:技能是文本,不是程序。 它的门槛不在编程,在于你能不能把「我要什么」和「不要什么」说清楚。 说清楚了,一个文件夹一个文件就能干活;说不清楚,写多少代码都不管用。 下一章往里走一层:为什么这么简单的东西能起作用,它在智能体里到底占哪个位置。
七、动手 Demo:把一个 SKILL.md 拆开,量一量三段各占多少
这一段真建一个带参考文档、模板、脚本的完整技能包,然后逐段量它的体量。 最后模拟一次「全局与项目同名」,看覆盖发生在哪一层。
skills/writing/
SKILL.md # 入口,正文点名下面三样
references/style-guide.md
templates/article.md
scripts/check_style.py
实跑输出:
--------------------------------------------------------------------
把一个 SKILL.md 拆开,量一量三段各占多少
--------------------------------------------------------------------
① 一个技能包的真实形状
--------------------------------------------------------------------
└── writing/
├── SKILL.md
├── references/
│ └── style-guide.md
├── scripts/
│ └── check_style.py
└── templates/
└── article.md
一个技能文件夹里可以有四样东西:SKILL.md、参考文档、模板、脚本。
SKILL.md 是唯一的入口,另外三样都是被它点名叫进来的。
② 三段结构:frontmatter、正文、被引用的文件
--------------------------------------------------------------------
| 部分 | 体量 | 粗算 token | 什么时候进上下文 |
|---|---|---:|---|
| frontmatter | 2 行 | 54 | 每次都进上下文 |
| 正文 | 14 行 | 169 | 选中技能才读 |
| 参考文件三份 | 3 个 | 117 | 读到那一步才读 |
常驻 54、触发 169、用到 117。这就是「按需加载」的三级台阶。
! token 是本沙箱按「中文 1.6 字一个」粗估的,只用来比大小,不是真分词结果。
③ frontmatter 只有三行有用
--------------------------------------------------------------------
name: writing
description: 按指定的风格把中文草稿改写成可直接发布的版本,含标题、开头、分节与结尾。
description 按指定的风格把中文草稿改写成可直接发布的版本,含标题、开头、分节与结尾。
name writing
name 是技能的名字,description 是它的广告词,两个都是必填。
! description 不是给你看的,是给模型挑技能时看的。
! 这一条后面单开一节讲,它是整本书里最容易写砸的一行字。
④ 正文写什么:步骤、规矩、边界
--------------------------------------------------------------------
| 小节 | 行数 | 最后一行 |
|---|---|---|
| 何时用 | 2 | 用户给出一段草稿,要求改成可发布的文章时。 |
| 步骤 | 4 | 3. 写完用 scripts/check_style.py 自查一遍。 |
| 三条硬规矩 | 4 | 3. 禁用词一个都不许出现。 |
正文的三块,对应三件事:什么时候用、怎么做、别做什么。
缺了第三块最要命——只写「怎么做」的技能,遇到边界情况会自由发挥。
⑤ 全局与项目两个作用域,同名谁赢
--------------------------------------------------------------------
| 技能名 | 生效的那份 | description |
|---|---|---|
| report | 项目 | 本项目专用版:四段式周报,多一段风险 |
同名时项目覆盖全局。这条规矩的目的是:让团队默认值能落地,
同时允许某个项目在自己的仓库里改掉它,不用去动别人的机器。
! 覆盖是整份覆盖,不是合并。项目的 description 写了什么,就只认那一份。
第一段是技能包的真实形状:一个入口加三样配角,四样东西各自有明确职责。 第二段把整份文件拆成三段量了一遍:常驻是 frontmatter、触发是正文、用到是那三个文件。 这三个数就是「按需加载」的三级台阶,第 2 章会把它们展开讲。 token 是本沙箱按「中文 1.6 字一个」粗估的,只用来比大小,不是真分词结果。 第三段把 frontmatter 逐行打了出来——就三行,两个字段有用。 第四段把正文按二级标题切开,看每一节有多少行、最后一句是什么。 这一眼能看出技能写得糙不糙:全是步骤没有边界的那份,一定有坑。 第五段是覆盖实验。同名 report,全局那份是三段式,项目那份是四段式(多一段风险)。 结果生效的是项目那份,而且是整份覆盖——项目的 description 写了什么,就只认那一份。
30 秒实验
- 把你写的技能按「何时用、怎么做、别做什么」三段重排一遍,缺哪段补哪段。
- 在正文里给每个参考文件标上「什么时候读」,标不出来的就说明它不该存在。
- 故意在两个作用域各放一个同名技能,看你的客户端认哪份。认错了就是你放错了地方。
常见误区
- 一上来就把 references、templates、scripts 全建好。 空目录不会让技能变强,只会让 SKILL.md 里的引用指向不存在的东西。先只有一个文件,跑到不顺再拆。
- 把参考文档放在目录里但正文不提。不点名的文件不会被读,它只是占地方。 要么在正文里写清「第几步读它」,要么删掉。
- 以为项目级技能会自动同步给同事。技能是文件,文件要跟着仓库走。 没进仓库的项目级技能,只在你自己的机器上生效。
自测三问(点开对答案)
1. 一个技能文件夹里,哪样东西是必须的? —— 只有 SKILL.md。其余三样(参考、模板、脚本)都是等技能复杂了再加,加了还要在正文里点名。 2. 为什么说 description 是整份文件里最重要的一行? —— 它决定技能选不选得上。正文写得再好,description 认不出触发场景,技能就永远不会被读。 3. 全局与项目同名时,覆盖是整份还是逐字段合并? —— 整份覆盖。项目那份写了什么就只认那一份,不会和全局的字段拼起来。第一章到此为止。下一章往里走:技能在智能体里占哪个位置,为什么这么简单的文本能起作用。
- ☐ (本篇完,下一篇 2.1 智能体的六大要素)