DeepSeek Harness 深度评测 · Ep2DEEP DIVE

Ep 2 DeepSeek Harness 深度评测 连载中

领域 Agent 与框架

DeepSeek Harness Ep 2:Skill——能力是怎么「长」出来的

2026-08-20 阅读约 12 分钟 正文约 4920 字

视频版:B站 公开投稿中无对应视频(已核对全部 16 个投稿) 视频总览 →

本期要点POINTS

本期要点

本期未收录要点:抽取阶段判定该篇正文没有可提炼的线索性结论(不造数、不空着)。

关键实测数据DATA

关键实测数据

1 条
本期自测读数
2026-08-17 — 2026-08-17 · 自有数据
1 条
本地(本机 Mac)
不与他环境混评
0 / 1
原始记录可直达
公开仓固定链接(带 commit SHA)
本地(本机 Mac) · 1 条
被测项 指标 值 实测日期 原始记录
dsh(DeepSeek Harness) 仓库包数量 54 个 2026-08-17 未收录

口径:本地与云不混评(每条读数标了运行环境,两边数字不放在一起比); 一行 = 一条可核读数;论文与第三方数字不进本表(见上方来源表)。 「原始记录」指向公开仓 cnopens/ruiowl-evidence 的固定链接(带 commit SHA,防漂移);标「未收录」者为本地从未留存原始数据文件,不补造。

锐Owl · 解构系列 · DeepSeek Harness(Ep 2/5) 素材:2026-08-17 clone(commit 99f6f02)源码逐层拆解,全部论断带文件路径/行号


一、54 个包,先看入口

上一期我们拆完内核留下三问:插件生态、热卸载、Typert 边界。三周过去,stars 从 4 万涨到 14.5 万——热度涨了,但「一切皆插件」到底是工程事实还是营销口号,答案得回到代码里找。

仓库里 54 个包,每个包是一个插件。其中有一个叫 skill——它是「能力」的载体。为什么从它入手?因为 skill 是这套插件哲学最小可观测的样本:看懂 skill 从哪来、谁说了算、怎么失效、谁能调用,就看懂了 harness 的插件机制。


二、形态:一份写给模型看的说明书

2.1 磁盘上的两种长相

一份 skill 在磁盘上可以是两种形态(skill-filesystem/src/index.ts:719-747):

  • 目录 bundle:<root>/<name>/SKILL.md,目录即资源基址
  • 扁平文件:<root>/<name>.md

命名有硬性约束:kebab-case,严格匹配 /^[a-z0-9]+(?:-[a-z0-9]+)*$/(packages/skill/skill/src/index.ts:20,34-36)。为什么这么严?因为名字会被当作用户命令、也会被模型当工具名——太松会出问题。

2.2 摘要先行,正文按需

文件格式是 YAML frontmatter + Markdown 正文(skill-filesystem/src/index.ts:909-935)。必需字段只有 name 和 description——缺了,整个文件被直接忽略(:810-819)。

关键设计在暴露面:目录暴露给模型的,只有 name 和 description 两行字。正文?模型需要的时候才加载。这就是「摘要先行、正文按需」——不给模型灌无关信息。这个约定和 Anthropic 的 Agent Skills 一致,但 dsh 在后面几层多做了很多。


三、注册表:skill 从哪来、谁说了算

3.1 六级优先级链

skill 的发现路径被排成一条优先级链(skill-filesystem/src/index.ts:241-261):

根 source rank
<project>/.dsh/skills project-dsh 100
<project>/.agents/skills project-agents 200
customSkillDirs[] custom 300
~/.dsh/skills user-dsh 400
~/.agents/skills user-agents 500
$DSH_BUNDLED_SKILL_DIR bundled 600

← 表格可左右滑动查看

rank 越小越优先——同一个 skill 名,项目里的盖掉用户目录的。这是写死在代码里的规则,不是约定俗成。

3.2 注册即效果,卸载即撤销

所有 provider 走同一个入口 registerProvider()(packages/skill/skill/src/index.ts:391-429)——注册时返回一个「注销函数」,effect 销毁时自动注销并失效缓存。这是整套 harness 的纪律:你注册了什么,你就负责在销毁时撤销。

3.3 scope 层遮蔽

每个 agent 看到的是「自己的」skill 层,不是全局一锅端(skill/src/index.ts:363-366,552-566):层间 scope 链最近层整体遮蔽远层,调用哪个 agent 就看哪个 scope。模型能看到的 skill 集合,随会话上下文变化。


四、监控:文件一变,立刻失效

skill 存在文件里,文件会变——系统必须让模型看到新的。两条失效通道:

通道一:文件系统监听(skill-filesystem/src/index.ts:487-540)。根目录存在时用 chokidar:depth: 1 + awaitWriteFinish 200ms 稳定阈值;事件过滤只关心深度 1 的 *.md、深度 2 的 SKILL.md 和目录增删(:658-675)。事件 → queueInvalidation(microtask 去重)→ 缓存清空 + skills/change 事件。

通道二:模型自己写文件也失效(:139-142,332-337)。监听 fs/observed 事件,仅当 actor 工具名是 edit/write 时按路径命中判断失效——模型改完 skill 文件,立刻重新发现,不用等下一次会话。

缓存本身是 revision 化的:collectCache key = {cwd, scopeChain, revision},上限 128 条(:644-646),invalidateCache() 递增 revision + 清空 + 发事件(:622-626)。发现期间 revision 变化则重试,最多 2 次,否则返回 complete: false 不缓存(:520-550)——宁可慢,不给你过期数据。


五、调用:双通道进同一扇门

skill 的调用有两条路,互不干扰:

通道一:模型工具调用。tool-skill 注册名为 skill 的工具(tool-skill/src/index.ts:81-161),与普通工具同机制。但它是一个只读加载器:不执行动作,仅把指令全文取回,presentCall 标记 kind: 'read'(:157-159)——无副作用。

通道二:用户手势调用。第二个 agent/pre-step 钩子扫描用户消息里的 /name 手势(正则 :409),命中且 user-invocable 时把全文作为指令注入(:177-204)。

两条路径产出同一个规范块:<skill_content><skill_resources>…</skill_resources><skill_instructions>…</skill_instructions></skill_content>(skill/src/index.ts:171-184)。控制粒度也在:disable-model-invocation(默认 false)和 user-invocable(默认 true)分别控制两条通道(skill-filesystem/src/index.ts:992-1008)——可以做成「只给用户用、不给模型用」的 skill。

会话目录注入是增量的:agent/pre-step 钩子注入 <available_skills> 摘要目录,sha256 digest 判重,变化时替换目录或发空墓碑(tool-skill/src/index.ts:213-251)——模型每轮看到的是「随会话持久化」的注入消息,不是静态 prompt。


六、与 Claude Code 的分水岭

维度 Claude Code dsh
架构 目录扫描(静态) 分层注册表 + provider 抽象(可编程注入)
优先级 项目层遮蔽用户层 6 级 rank + scope 层遮蔽 + 同层注册序
调用 模型单一通道 双通道(模型 skill 工具 / 用户 /name 手势)
失效 无显式缓存失效 revision 化缓存 + chokidar/watchFile 双向监控 + fs/observed 联动
渲染 直接注入裸 markdown 规范 <skill_content> 包装 + resourceBase 资源提示

← 表格可左右滑动查看

这些差异指向同一个哲学:工具给一个功能,平台给一套规则。Claude Code 的 skill 是静态扫描——快但不可编排;dsh 的 skill 是注册表 + provider——动态的、可编程注入、可分层遮蔽、可按 scope 隔离。这是「平台化」和「工具化」的分水岭。


七、格局:热度背后的工程纪律

四万星到十四万星,涨的是热度;热度背后的成色,是这套没人看见的工程纪律:注册即效果、卸载即撤销、文件变则失效、双通道进同一扇门。

下一期拆同一套纪律的另一面:hooks 与热卸载——装上容易,卸下来要静默。


参考来源

# 数据/论断 来源
[1] 命名正则 kebab-case、缺 frontmatter 忽略 packages/skill/skill/src/index.ts:20,34-36 + skill-filesystem/src/index.ts:810-819,909-935
[2] 目录/扁平两形态 skill-filesystem/src/index.ts:719-747
[3] 6 级 rank 表 skill-filesystem/src/index.ts:241-261
[4] registerProvider + effect 注销 skill/skill/src/index.ts:391-429
[5] scope 层遮蔽 skill/skill/src/index.ts:363-366,552-566
[6] chokidar depth:1 / awaitWriteFinish 200ms skill-filesystem/src/index.ts:487-540
[7] 事件过滤 + fs/observed 联动 skill-filesystem/src/index.ts:658-675,139-142,332-337
[8] revision 缓存失效 + skills/change skill-filesystem/src/index.ts:622-646
[9] 双通道 + <skill_content> 规范块 tool-skill/src/index.ts:213-251 + skill/src/index.ts:171-184
[10] disable-model-invocation / user-invocable skill-filesystem/src/index.ts:992-1008
[11] Claude Code 对比 分析层:Anthropic 公开文档 + 本机制对比归纳

← 表格可左右滑动查看


锐Owl · 观察者 · 解构者 · 传播者

信号来源SIGNALS

信号来源

这一期从哪条雷达长出来(雷达 → 产出的双向可追溯):

node_links/radar_items.intent 的 feeds 指向关系当前为 0(M2 首轮回填统一先落 standalone,待人工指认)——回填后此处显示「雷达 YYYY-Www 条目 ③ → 已成为本期」。

来源表SOURCES

来源表

该篇正文里没有可解析的「来源」小节(早期篇目未写文末来源表)——不补造。