ARCHITECTURE · 08
Skills 技能机制:DeepSeek Harness 如何发现和加载技能
直接答案
技能(skill)在 DeepSeek Harness 里是"可选指令",不是工具、也不是会话事件。本地技能按固定优先级从六个位置发现;模型平时只看到一份只含名称和描述的目录,判断需要时才通过skill 工具加载完整正文。能否被模型或用户调用,由技能文件头部的两个开关独立控制。技能是什么,不是什么
skill(技能)是可选指令:一段写给模型看的操作说明,通常附带脚本和参考资料。两个边界要先划清:
- skill ≠ 工具:在
SKILL.md里写"请查询数据库"不会凭空产生数据库工具——技能只提供指令,工具得另装(本站教程已验证,工具侧见工具系统页)。 - skill 不是会话事件:它的词汇定义在 skills 子系统,不在核心包里。
能力族由四个角色组成:服务定义 dsh-skill(ctx.skills 提供方注册表)、本地提供方 dsh-skill-filesystem、随包徽章提供方 dsh-skill-badge、消费方 dsh-tool-skill(拥有目录和面向模型的 skill 工具)。服务定义 / 提供方 / 消费方框架见插件系统页。
发现机制:六个位置,按优先级来
本地提供方按 rank(优先级数值,小者胜)从六个位置发现技能(官方表与本站教程一致):
| rank | 位置 |
|---|---|
| 100 | <项目根>/.dsh/skills |
| 200 | <项目根>/.agents/skills |
| 300 | 配置里的 customSkillDirs(自定义目录) |
| 400 | <dshHome>/skills |
| 500 | <agentsHome>/skills |
| 600 | 随发行版自带的目录 |
项目根 = 含 .git 的最近祖先目录,找不到就用当前工作目录。命名规则:技能名必须是 kebab-case(小写字母数字加连字符),本地提供方接受目录包 <name>/SKILL.md 和平铺的 <name>.md 两种形态,不支持嵌套递归发现——**/SKILL.md 这种多层结构不会被扫到,别把技能藏进子目录的多层结构里。
目录注入:模型先看到名片,再决定要不要正文
模型看到的技能目录只含名称和经规范化、XML 转义的描述——不含正文、路径、来源、提供方。注入机制:
- 首次:在第一个非空完整视图时,通过
agent/pre-step注入一条持久的 user 角色<system-reminder>(系统提醒)消息; - 后续:每个模型步骤前对
<available_skills>条目算 digest(摘要指纹),发现变化就通过agent.inject()追加一条持久的完整目录替换; - 目录消息属于会话历史,而不是某种全局状态。
这个设计控制了 token(模型计费与上下文单位)成本:目录短、正文长,只在需要时加载。但目录本身也占上下文——技能装得越多目录越长,加载过的正文也会进入后续上下文(本站教程实测口径)。pre-step 与 inject 机制出处见 Agent Loop页第 3 节。
加载与调用策略:两个独立开关
模型通过 skill({ name }) 工具加载完整正文(走与原生工具相同的流水线,见工具系统页):先按 isModelInvocable 拒绝无权调用的技能,加载前后各检查一次策略;返回结果含 <skill_content>(正文)、<skill_resources>(资源清单)、<skill_instructions>(使用说明);resourceBase 只按需解析显式引用的脚本和参考资料。
调用策略由技能文件头部(frontmatter)的两个独立开关控制:
disable-model-invocation:关掉后模型不能主动调用;user-invocable:关掉后用户不能用/name斜杠调用。
两个都省略时默认允许。两个都关掉的技能,只能由受信的 ctx.skills.get() 调用方获取。
变更检测与常见误读
文件监视器(Chokidar watcher)盯着根目录的添加、移除和条目变更;skills/change 是一条没有 diff(差异明细)的失效通知——只说"变了",消费方自己重新获取。
三个常见误读,都是本站教程验证过的:
- 自动路由没触发 ≠ 技能无效:模型判断主要靠名称和描述,先用
/name显式调用验证加载链路,再调描述; - 只改正文不会重发目录消息:也不改写先前的工具结果,只影响后续
skill工具调用; - 改名或改描述才会触发目录更新(按 digest 比对机制推导:digest 只对目录条目计算,而目录条目只含名称和描述,所以正文变化不会产生新 digest)。
EVIDENCE
证据与来源
本页包含:官方事实 / 教程实测
| # | 事实声明 | 状态 | 来源 |
|---|---|---|---|
| 1 | skill 是可选指令、不是会话事件、不定义工具 | 官方事实 | |
| 2 | 能力族四角色(dsh-skill / skill-filesystem / skill-badge / tool-skill) | 官方事实 | |
| 3 | 六档 rank 发现优先级与项目根判定 | 官方事实教程实测 |
|
| 4 | kebab-case 命名、两种形态、不支持嵌套递归发现 | 官方事实教程实测 |
|
| 5 | 目录只含 name + 转义 description、pre-step 注入、digest 替换经 agent.inject() | 官方事实教程实测 |
|
| 6 | 目录消息属于会话历史而非 World State | 官方事实 | |
| 7 | skill 工具加载流程、三段返回结构、resourceBase 按需解析 | 官方事实 | |
| 8 | 两个 frontmatter 开关默认允许、双关技能仅受信调用方可获取 | 官方事实教程实测 |
|
| 9 | Chokidar 监视、skills/change 无 diff 通知 | 官方事实教程实测 |
|
| 10 | token 影响:目录与已加载正文都占上下文 | 教程实测本站已验证内容 |
|
| 11 | skill ≠ 工具(写指令不产生工具) | 教程实测本站已验证内容 |
|
| 12 | 自动路由未触发的排查顺序、只改正文的影响范围 | 教程实测官方事实 |
|