1.1 skill 是什么:按需加载的指令包
一句话定义
在 DeepSeek Harness 里,skill 是一份可复用的 agent 指令:它以 Markdown 形式存在,平时只贡献一条“名称 + 描述”给模型看,等任务匹配上时才被完整加载进上下文。它不新增进程、不打开端口,却能把某个领域的专业做法一次性注入会话。
官方子系统文档对它的定位很直接:skill 是可选的指令而非会话事件。这句话有两层含义,值得拆开。
第一,它是指令,不是事件。会话事件是运行时产生的结构化消息,会自行流动;skill 不会在后台自行触发,它只在你或模型选中它时,把一段文本送进上下文。第二,它是可选的——一个技能都不装,harness 照常工作;技能增减改变的是模型的能力面,不是会话的基本形态。
它不是插件,也不是工具
初学者最容易把三个概念混在一起。先用一张表把它们分开:
| 概念 | 本质 | 谁来实现 | 什么时候加载 | 例子 |
|---|---|---|---|---|
| 插件 | 代码模块,导出 apply |
你或第三方开发者 | 启动时随组合装载 | @deepseek-ai/dsh-skill-office |
| 工具 | 模型可调用的函数 | 插件注册到 ctx.tools |
会话全程可用 | read、bash、skill |
| skill | 一段指令文本 | 任何人写 Markdown | 按需加载 | office-docx、dsh-code-review |
容易含糊的维度再对照一遍:
| 维度 | 插件 | 工具 | skill |
|---|---|---|---|
| 载体 | 代码包 | 注册表里的函数 | Markdown 文件 |
| 常驻开销 | 随组合常驻 | 占一条目录条目 | 只占一条摘要 |
| 完整内容何时进上下文 | 不进去(它是机制) | 调用时进参数与结果 | 选中时才进正文 |
| 能否被 git 管理 | 能 | 随插件走 | 能,且就是纯文本 |
| 编写门槛 | 会写代码 | 会写代码 | 会写 Markdown |
关键差别在加载时机。工具是常驻的,注册了多少模型就看到多少;skill 是候诊式的——注册表里躺着几十个,模型目录里只显示几十条摘要,真正读正文的只有被选中的那一两个。
这就是官方所说的渐进加载(progressive loading):先花极小的代价让模型知道有这么一个技能、什么时候该用,等真用上了再付出完整正文的上下文成本。
三类接口:提供方、观测与控制
技能注册表 ctx.skills 不是一个扁平列表,它把本地、内嵌、远程或其他提供方组合在一起。理解这三个接口,后面讲优先级、失效与排查都用得到:
| 接口 | 职责 |
|---|---|
SkillProvider |
技能的来源抽象。本地目录、内嵌集合、远程服务都可以包装成提供方。注册动作是同步的;远程提供方的初始化与发现发生在 list() 的 await 阶段 |
SkillProviderObservation |
一次读取得到的观测快照。观测可能不完整:某个提供方 list() 被拒时记录日志,该次观测会省略它的结果 |
SkillProviderControl |
注册作用域内的控制能力,含 signal(注册失败或 dispose 时中止)与 invalidate()(仅在精确注册仍活动时清除已完成目录) |
这些接口意味着:技能出现与否不是一次性的启动动作,而是每次读取时由各提供方现场汇报的结果。这也解释了为什么改文件、换 scope 会影响下一刻的目录。
摘要里有什么:SkillSummary 字段表
模型看到的目录条目来自 SkillSummary,字段不多,各有用途:
| 字段 | 含义 |
|---|---|
name |
技能名,kebab-case,同时是目录名或文件名 |
description |
一句话说明做什么、何时用;模型唯一必读字段 |
whenToUse |
可选的触发条件补充 |
invocation |
调用策略,含 modelInvocable 与 userInvocable 两个独立布尔 |
source |
来源桶,如 project-dsh、user-dsh、bundled |
provider |
拥有该技能正文的提供方名 |
path |
指令文件的绝对路径;虚拟技能没有此字段 |
注意官方的明确边界:模型可调用的会话目录只使用 name 与 description,从不使用正文或绝对文件路径。path 是给人排查用的,不是给模型用的。
一个 skill 长什么样
skill 的物理形态只有两种。
形式一:目录包(推荐,可带附件)
my-skill/
├── SKILL.md # 必需:指令正文,开头是 frontmatter
├── references/ # 可选:按需展开的参考资料
│ └── checklist.md
└── scripts/ # 可选:配套脚本
└── verify.py
形式二:扁平 Markdown 文件
skills/
└── my-skill.md # 文件名即技能名
两者的加载结果完全一致,区别只在于目录包能带参考资料与脚本,适合内容较多的技能。
SKILL.md 的骨架
一份合格的 SKILL.md 由 frontmatter 加正文构成。frontmatter 声明元数据,正文写指令:
---
name: my-skill
description: 一句话说明这个技能做什么、什么时候该用它。这是模型唯一必读的字段,务必写清触发条件。
---
# 我的技能
## 适用场景
什么时候该启用本技能。
## 执行步骤
1. 第一步做什么
2. 第二步做什么
3. 交付前检查什么
## 注意事项
容易踩的坑与红线。
其中 description 是整个 skill 里最值钱的一行。模型的技能目录只展示名称与描述,正文和绝对路径都不给模型看。描述写得含糊,技能就永远不会被选中——这是技能“装了没反应”的头号原因。
名称有硬性格式
skill 名称必须是 kebab-case,也就是小写字母、数字与连字符的组合:
^[a-z0-9]+(?:-[a-z0-9]+)*$
✅ office-docx dsh-code-review webapp-testing
❌ Office_Docx dshCodeReview webapp.testing
名字同时是目录名(或文件名),改名字等于换一个技能。
模型怎么用它
加载路径有两条,互补而非二选一:
| 路径 | 触发者 | 形式 | 适用 |
|---|---|---|---|
| 模型自选 | 模型 | 调用 skill 工具,按名称加载 |
任务匹配上时自动发生 |
| 用户直调 | 人 | 输入 /技能名 |
你明确知道要用哪个 |
每个技能还带一对布尔控制,官方称之为调用策略(SkillInvocationPolicy):
| 字段 | 含义 |
|---|---|
modelInvocable |
是否出现在面向模型的目录与加载器里 |
userInvocable |
是否出现在面向人的命令目录与加载器里 |
把 modelInvocable 关掉、userInvocable 打开,就得到一个只给你自己用的私有技能——模型看不到,也不会擅自执行。适合放带有个人偏好或敏感内部信息的指令。日常两种都可以用:让模型自己挑,需要强制走某套流程时(比如必须按公司规范写周报)直接斜杠调用。
渐进加载的价值,数量上去后才显出来
只装一个技能时,渐进加载的优势看不出来——就一个,全量加载也无所谓。价值出现在技能数量上去之后:
- 常驻成本:每条技能只贡献 name 与 description 两行,几十个技能也不过几十条摘要;
- 完整成本:只有被选中的技能付出正文代价,一次通常是一两个;
- 若换成全量注入:每份正文动辄数百行,开销随技能数量线性膨胀,很快挤占任务本身需要的空间。
这也是官方把 description 定为模型唯一必读字段的原因:摘要就是全部广告位,广告写砸了,商品再好也卖不出去。
description 写废的三种典型
按踩坑频率排:
- 只写功能,不写触发条件。 例如“Excel 处理技能”——模型知道它能干什么,却不知道什么时候该找它。对照官方技能的写法:“电子表格文件是主要输入或输出时使用”,触发条件写在明面上;需要时也可以用
whenToUse显式补充。 - 触发条件过于宽泛。 “处理文档时使用”几乎匹配一切任务,等于没有;候选一多,模型反而难以取舍。触发条件越具体,命中越稳。
- 把正文抄进描述。 唯一必读字段被复述内容占满,触发信息被稀释。描述要回答的是“什么时候用”,不是“里面有什么”。
为什么它值得你花时间
把 skill 和另外两种“教 agent 做事”的方式对比,优势就出来了:
| 方式 | 成本 | 复用性 | 版本管理 |
|---|---|---|---|
| 每次在对话里重复交代 | 低(单次) | 无 | 无 |
| 写进系统提示词 | 中 | 全局生效、无法按需 | 难 |
| 做成 skill | 一次性写 | 任意项目可复用 | 可随 git 走 |
第三条是重点:skill 就是仓库里的普通文件,意味着它可以被 review、被 diff、被回滚。团队可以把“我们公司怎么写迁移脚本”沉淀成技能提交进仓库,新人 clone 下来即用——这是把个人经验变成组织资产的最短路径。
小结
- skill = 按需加载的指令包,形态是
SKILL.md目录或扁平.md文件。 - 名称必须 kebab-case;
description决定模型能不能选中它。 - 模型通过
skill工具自选,人通过/名称直调;两个调用开关可做仅供本人使用的技能。 - 提供方、观测、控制三类接口支撑起注册表;进模型目录的只有 name 与 description。
- 它是文件,所以天然可复用、可评审、可版本化。
下一节解决第一个实操问题:这么多层目录,skill 到底该放哪一层。
延伸阅读
- 官方子系统参考:skill 子系统
- 本书后续:1.2 装到哪个目录
- 配套概念:DeepSeek Harness 工具系统
