ARCHITECTURE · 08

Skills 技能机制:DeepSeek Harness 如何发现和加载技能

直接答案

技能(skill)在 DeepSeek Harness 里是"可选指令",不是工具、也不是会话事件。本地技能按固定优先级从六个位置发现;模型平时只看到一份只含名称和描述的目录,判断需要时才通过 skill 工具加载完整正文。能否被模型或用户调用,由技能文件头部的两个开关独立控制。

技能是什么,不是什么

官方事实

skill(技能)是可选指令:一段写给模型看的操作说明,通常附带脚本和参考资料。两个边界要先划清:

  • skill ≠ 工具:在 SKILL.md 里写"请查询数据库"不会凭空产生数据库工具——技能只提供指令,工具得另装(本站教程已验证,工具侧见工具系统页)。
  • skill 不是会话事件:它的词汇定义在 skills 子系统,不在核心包里。

能力族由四个角色组成:服务定义 dsh-skillctx.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随发行版自带的目录
示意图
01六个位置按优先级从高到低纵向排列,每条标注路径与 rank 值;顶部标注"数值小者胜";同名技能在高优先级处画实心点、低优先级处画被遮蔽的空心点。图注:项目根 = 含 .git 的最近祖先目录。

项目根 = 含 .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 节。

示意图
02左右两阶段。左:技能目录(只有名称 + 描述的名片墙)经 pre-step 注入会话历史,标注"占少量上下文";右:模型调用 skill 工具,某个技能的正文 + 资源被加载进上下文,标注"占较多上下文,按需发生"。digest 变化触发目录替换画成虚线回路。

加载与调用策略:两个独立开关

官方事实教程实测

模型通过 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

证据与来源

本页包含:官方事实 / 教程实测

#事实声明状态来源
1skill 是可选指令、不是会话事件、不定义工具官方事实
2能力族四角色(dsh-skill / skill-filesystem / skill-badge / tool-skill)官方事实
3六档 rank 发现优先级与项目根判定官方事实教程实测
4kebab-case 命名、两种形态、不支持嵌套递归发现官方事实教程实测
5目录只含 name + 转义 description、pre-step 注入、digest 替换经 agent.inject()官方事实教程实测
6目录消息属于会话历史而非 World State官方事实
7skill 工具加载流程、三段返回结构、resourceBase 按需解析官方事实
8两个 frontmatter 开关默认允许、双关技能仅受信调用方可获取官方事实教程实测
9Chokidar 监视、skills/change 无 diff 通知官方事实教程实测
10token 影响:目录与已加载正文都占上下文教程实测本站已验证内容
  • 本站教程内容 src/content/tutorials/skills.ts:497
11skill ≠ 工具(写指令不产生工具)教程实测本站已验证内容
  • 本站教程内容 src/content/tutorials/plugin-skills-mcp.ts:274
12自动路由未触发的排查顺序、只改正文的影响范围教程实测官方事实
适用版本
DSH 0.1.1-rc.2(2026 年 8 月,开发者预览阶段)
发布
2026-08-26
更新
2026-08-26
最后核验
2026-08-26