1.3 三种装法与装后验证

先分清:文件层与组合层

三种装法分属两个完全不同的层,搞混了就会出现“删了文件技能还在”或“删了文件也没用”的困惑:

复制目录 / git 克隆 挂载 bundled 提供方
操作层 文件层 组合层
你改的是什么 磁盘上的技能目录 组合配置里的一行
更新方式 覆盖文件 / git pull 升级 dsh 版本
卸载方式 删目录 摘掉配置行

一句话:前两种是“把货搬进仓库”,第三种是“给仓库接一个自动补货的供应商”。搬运工离职货还在,供应商断供货就没了——这就是两种装法在行为上差别的全部来源。

三种装法怎么选,一张表定:

你的情况 用哪种
单个技能,来自文档或同事 复制目录
一整套技能集合,想持续跟进上游更新 git 克隆
官方技能族(Office 等) 挂载提供方
团队全员统一用 项目级克隆进仓库,或走部署方的 custom / bundled 层

装法一:复制目录(最常用)

适合单个技能、从文档或同事那里拿到的一个文件夹。

# 个人全局(所有项目可用)
mkdir -p ~/.dsh/skills
cp -r my-skill ~/.dsh/skills/

# 仅当前项目,harness 专用层
mkdir -p ./.dsh/skills
cp -r my-skill ./.dsh/skills/

# 仅当前项目,跨 agent 工具层
mkdir -p ./.agents/skills
cp -r my-skill ./.agents/skills/

扁平 .md 同理,把文件放进上述任一 skills 目录即可。装完立刻可以验证,无需重启。

复制完先确认结构,再谈验证:

ls ~/.dsh/skills/my-skill/
# 期望看到 SKILL.md;目录包还应有 references/、scripts/(如有)

装法二:git 克隆(适合成组技能)

适合从一个技能集合仓库批量获取,也是团队协作的标准姿势。

# 个人全局:直接把技能仓库当作 skills 根
git clone https://github.com/anthropics/skills.git ~/.dsh/skills

# 项目级:只取其中需要的技能
mkdir -p .agents/skills
git clone --depth 1 https://github.com/anthropics/skills.git /tmp/skills-src
cp -r /tmp/skills-src/skills/docx .agents/skills/
cp -r /tmp/skills-src/skills/xlsx  .agents/skills/

注意:直接把技能仓库 clone 成 skills 根目录时,仓库里的 spec/、template/、README.md 等非技能文件会一并进来。它们不含 SKILL.md,不会被当成技能,无害但略乱。追求干净就按上面第二种做法只复制需要的技能目录。

更新就是一次 git pull:

cd ~/.dsh/skills && git pull --ff-only

团队场景下更稳的做法是项目级克隆后,在 README 里写清技能从哪来、怎么升级,别让下一个人猜。还有一种零命令的团队变体:把技能目录直接提交进仓库的 .dsh/skills/ 或 .agents/skills/,新人 clone 即得,版本问题直接并入代码评审流程——这是“复制装法”的团队版。

装法三:挂载 bundled 提供方(官方技能族)

DeepSeek Harness 有一类技能是随插件分发的,不需要你复制任何文件,只要在组合配置里挂上提供方。最典型的是 Office 技能族:

- name: '@deepseek-ai/dsh-skill-office'

挂上之后,office、office-docx、office-xlsx、office-pptx、office-export-pdf、office-render、office-recalculate 七个技能一次性进入目录。

这条配置是组合(composition)层面的修改,不是往目录丢文件。具体写法见第二章,也可见《DeepSeek Harness 插件开发从入门到精通》的组合与热重载。

需要定制载体时,这个提供方有三个配置字段:assetRoot(技能资源根,默认包内 assets/)、node(操作技能用的 Node 可执行程序,默认宿主 Node.js)、cli(Kit CLI 入口绝对路径,设 false 禁用操作执行)。一般保持默认即可。另外记住一条硬规则:无效的技能资源会阻止注册——挂载后技能没出现,先查资源路径是否有效。

临时停用:改名加 .off

技能没有开关,但有一个零成本刹车:把目录名(或文件名)加上 .off 后缀,例如 my-skill 改成 my-skill.off。名称立刻不合 kebab-case 规范,技能从目录消失,文件原地不动;想恢复就把后缀去掉。比删了再找回来稳妥得多,也是验证“问题出在技能本身还是别处”的诊断手段。完整的生命周期管理见 1.4。

装后验证三步

装完别急着用,按顺序做三个检查,每步都有明确判据。

第一步:确认技能出现在目录里。 在会话中让 agent 列出可用技能,或直接看 Web UI 的技能目录。判据:新技能以合规名称现身。没出现就先回头看 1.2 的目录优先级——九成问题是放错层或名字不合规。

第二步:确认能被选中。 用一个明确匹配 description 触发条件的任务提问,观察模型是否调用了 skill 工具。判据:提问里最好复现 description 写明的触发场景;模型没选它,问题几乎一定在 description 写得不够触发。

第三步:确认加载后行为正确。 让模型按技能执行一次完整任务,检查产出是否符合技能里写的步骤。bundled 操作类技能(如 Office 族)在此步还要确认解释器与 CLI 实际可用——这类技能的说明在加载时会校验现有解释器和 CLI 文件,缺件会当场暴露,不会留到任务中途才炸。

三个步骤各自的失败信号不同,对照下表定位:

哪步失败 典型症状 先查什么
第一步 目录里根本没有 目录层、名称格式、是否平铺
第二步 技能在,模型不选 description 的触发条件
第三步 选了,产出不对 正文步骤;bundled 技能查解释器与 CLI

第一步失败时,按 1.2 的六层表逐层确认:文件到底落在哪一层、那一层是否参与扫描(bundled 层需要配置才启用)、项目根是否含 .git。第二、三步失败则基本与层级无关,回头看技能内容本身。

一个最小自测技能

如果你怀疑是环境问题而不是技能问题,用下面这个“金丝雀”技能验证链路:

---
name: canary-check
description: 当用户要求做金丝雀自检时使用,返回固定字符串以验证技能加载链路。
---

# 金丝雀自检

用户触发本技能时,只做一件事:原样回复下面这行,不要附加任何解释。

CANARY-OK

把它放进 ~/.dsh/skills/canary-check/SKILL.md,然后问一句“做一次金丝雀自检”。看到 CANARY-OK 就说明发现、目录、加载三条链路全通;看不到,就沿着目录优先级逐层排查。

金丝雀还有第二个用法:换层再测一次。同一个 canary-check 先放用户层、再放项目层,两次提问都应看到 CANARY-OK;某一层看不到,说明那层的扫描有问题——目录不存在、被 .system 跳过、或项目根判断和你想的不一样。测完记得把金丝雀删掉或改名加 .off,别让它常驻目录。

收货检查:拿到一个陌生技能先看三样

从文档、同事或仓库里拿到技能目录后,安装前花一分钟看三处:

  1. SKILL.md 的 frontmatter 是否完整,至少带 name 与 description;
  2. 名称是否 kebab-case,目录名与 frontmatter 里的 name 是否一致;
  3. description 是否写了触发条件——这是你将来能不能用上它的决定因素。

三样有缺,先修再装。否则装完也多半是“装了没反应”,还得回头排查一遍。

卸载

技能没有“卸载命令”,因为它本来就是文件:

rm -rf ~/.dsh/skills/my-skill

bundled 技能则相反——删文件没用,要从组合配置里摘掉那一行提供方,然后重载组合。拿不准要不要彻底卸载时,先改用 .off 后缀停用几天,观察有没有别的流程依赖它。

小结

  • 三种装法分两层:复制与克隆在文件层,挂载提供方在组合层。
  • 装后必做三步验证:目录可见 → 能被选中 → 行为正确。
  • 用金丝雀技能可在三十秒内定位是不是环境问题。
  • 卸载 = 删文件;bundled 技能卸载 = 摘配置行;临时停用 = 加 .off。

延伸阅读