前言¶
DeepSeek Harness(DSH)的理念是「一切皆插件」,用户可以自行扩展功能。在长期使用中,你可能会积累一批可复用的角色设定、提示词模板和本地知识文档。把它们零散地放在文本编辑器或笔记里,用时再手动复制粘贴,不仅容易出错,也难以统一管理。dsh-gen 是一个为 DSH 服务的技能与预设管理器,它把这些资源打包成模型可调用的「技能」,并在设置面板中提供统一的配置入口。
插件由 Idun 维护,定位是「技能 / 预设」管理器,思路类似 Gemini 的 Gems。它区分两种机制完全不同的对象:技能和预设。技能是一个「角色」,包含身份、行为准则和可挂载的知识文档;预设则是一段提示词文本,用于填入输入框。两者通过设置面板的 Dsh-Gen 页进行管理,每个启用的技能还会注册成 DSH 的 runtime skill,出现在模型的技能目录里。
技能与预设的区别¶
| 技能(Skill) | 预设(Preset) | |
|---|---|---|
| 是什么 | 一个角色:身份 + 行为准则 + 可挂载的知识文档 | 一段提示词文本:常用指令、格式要求、回答准则 |
| 选中后 | 给当前会话绑定角色,注入系统提示 | 把文本填入输入框,等你发送 |
| 可挂知识 | 是 | 否 |
| 典型用途 | 「代笔人」「严苛读者」 | 「翻译成英文」「按这个格式输出」 |
技能通过系统提示注入会话,不会被后续提问稀释;预设走文本填充路径,适合一次性指令。插件会在设置面板新增 Dsh-Gen 页,提供两个标签页分别管理技能与预设。
安装¶
前置条件¶
- 已安装 DeepSeek Harness(桌面版或
dshCLI) - Node.js
^22.19.0 || >=24.0.0
从压缩包安装(推荐)¶
-
解压到任意目录,例如:
- Windows:C:\Users\<你>\.dsh\plugins\dsh-gen
- macOS/Linux:~/.dsh/plugins/dsh-gen -
进入目标 profile 目录:
cd ~/.dsh/profiles/desktop
- 使用 DSH 自带的 pnpm 安装(注意用
file:前缀指向解压目录):
node ~/.dsh/dsh-runtimes/dsh-primary-runtime/dependencies/pnpm/bin/pnpm.cjs \
add file:C:/Users/<你>/.dsh/plugins/dsh-gen --offline
手动挂载¶
- 把项目目录放到
~/.dsh/profiles/desktop/node_modules/dsh-gen(Windows 下建议用目录联接,便于改代码即时生效):
mklink /J "%USERPROFILE%\.dsh\profiles\desktop\node_modules\dsh-gen" "C:\path\to\dsh-gen"
- 编辑
~/.dsh/profiles/desktop/package.json,在两处登记:
{
"dependencies": {
"dsh-gen": "file:C:/path/to/dsh-gen"
},
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-gen"]
}
}
}
- 重启 DSH。
验证安装¶
启动后打开 设置 → Dsh-Gen,能看到「技能 / 预设」两个标签即安装成功。插件加载痕迹写在 $DSH_HOME/dsh-gen/load-trace.log,排查问题时先看它。
设置面板:Dsh-Gen¶
页面顶部是「技能 / 预设」两个标签(各自带数量),右侧是操作区:
| 按钮 | 作用 |
|---|---|
| 导入 | 从 .json / .dshgen 文件导入技能或预设 |
| 备份全部 | 把全部技能与预设(含知识文件内容)打包成一个 JSON 下载 |
| 新建 | 下拉菜单,选择新建技能或预设 |
新建下拉菜单从按钮右下方展开,只做垂直位移,不会横向跳动。
技能列表¶
每张卡显示头像、名称、说明、知识文件数与更新时间。卡片上有六个操作:
| 图标 | 作用 |
|---|---|
| 对话气泡 | 在 dsh-gen 工作区新建会话,并直接绑定该技能的角色 |
| 复制 | 克隆技能(知识文件一并复制) |
| 铅笔 | 打开编辑器修改 |
| 下载 | 导出这一个技能为 JSON |
| 垃圾桶 | 删除技能(连同其知识文件) |
| 眼睛 | 控制该技能是否出现在会话内选择器里 |
预设列表¶
卡片显示预设内容的前 46 个字。操作有:新建对话、克隆、编辑、导出、删除、隐藏。
预设的「新建对话」只开一个普通会话,不绑定角色——因为预设不是角色。
技能编辑器¶
整页两栏。左栏填写「名称 / 说明 / 指令 / 知识」(外加「停用知识引用」),右栏实时预览。左上角返回列表,右上角保存。
- 从模板选择:内置 5 个开箱可用的技能模板,点一下自动填好名称、说明与指令:
- 代码审查规范官:按严重程度分级指出问题,给可执行的修改建议
- 技术架构评估师:评估方案的扩展性、成本与风险,给出取舍建议
- 技术文档撰写员:把零散信息整理成结构清晰、可直接交付的文档
- 问题排查与根因分析专家:现象分析 → 假设推导 → 验证定位 → 根因治理
-
数据清洗与转换顾问:识别脏数据,给出清洗规则与转换脚本
-
指令预览支持 Markdown:标题、有序/无序列表、代码块(带复制按钮)、表格、引用块、加粗都按对话里的样子渲染。代码块和表格超宽时在预览区内滚动,不会撑破布局。
-
知识挂载:可以在首次保存之前就添加文件,随保存一起落盘,不必先存一次再加。
-
查看文件内容:点击知识行可打开文档查看器,见下。
预设编辑器¶
只有「名称」与「内容」两个字段,右栏预览显示「预设内容」。刻意保持极简——预设就是一段要粘进输入框的文字,不需要指令、知识这些技能专属的概念。
文档查看器¶
点知识文件打开,带「预览 / 源码」切换:
- 预览:用与「指令」预览相同的 Markdown 渲染器,标题、列表、代码块、表格、引用都能正确显示。Markdown 类文件(
.md/.markdown/.mdx/.txt)默认进这个模式。 - 源码:等宽字体的原始文本,缩进与换行保持字面意义。非 Markdown 文件默认进这个模式。
- 顶部显示文件大小,右侧有「复制全文」。
- 超过 128KB 的文件只预览前 128KB,会明确标注。
- 二进制文件不尝试解码,直接提示改用文件工具读取。
会话内选择器¶
输入框工具行上的胶囊按钮。点开后是扇形卡组,每页 5 张。
底部控制条:
[切换查看预设] │ ← ●● → │ 共 N 第 x/y 组
- 最左侧的切换按钮在「技能卡组」与「预设卡组」之间切换。按钮文案是「切换查看 X」,其中 X 是点击后会切到的那一类,不是当前正在看的那一类。
- 中间是翻页箭头与组数圆点(组数超过 6 时圆点退化为
1/12文字)。 - 右侧显示总数与当前组号。
三种选法:
| 操作 | 技能卡 | 预设卡 |
|---|---|---|
| 单击 | 绑定当前会话的角色 | 内容填入输入框 |
| 滚轮 | 逐张切换高亮,不滚动背后页面 | 同左 |
| 长按拖拽 | 按住约 0.22 秒「入手」,上拖松手即「出牌」 | 同左,松手后填入输入框 |
长按拖拽的细节:
- 按住后卡片放大 1.08、上浮 26px、随指针倾斜(±14°),其余卡片降到 50% 透明度。
- 松手时向上超过 42px(或水平超过 92px)判定为出牌,卡片飞向上方淡出。
- 未达阈值则回落原位,不选中。
- 单击仍然是最快路径,不受长按影响。
其他行为:
- 弹出层锚定在胶囊按钮正中央(
translateX(-50%)),带升起动效。 - 静置 60 秒无操作自动收纳,期间任何指针/滚轮/按键操作都会重新计时。
- 弹出层上半部分完全透明,卡片直接浮在对话之上;只有底部控制条是实体胶囊。
- 技能卡显示说明摘要(最多 46 字,两行截断);预设卡显示提示词摘要,元信息标注「提示词预设」。
角色注入¶
技能选中后以系统提示的形式注入会话,不是塞进输入框,因此不会被后续提问稀释。注入内容包含技能名称、说明、指令,以及知识文件的绝对路径清单。绑定关系按会话 id 实时查表,所以给已存在的会话换技能,下一轮立即生效。
数据容错¶
gens.json被外部修改(手动编辑、恢复备份)时,宿主会按mtime:size检测并自动重读,同时重新注册技能。- 知识文件的绝对路径失效时(数据目录搬家、跨机器恢复备份),读取会自动按文件名在该技能的知识目录里找回,并把修复后的路径写回存储。
- 备份与克隆走同一套修复逻辑;确实找不到的文件会在备份完成后弹窗列出,不会静默丢失。
使用¶
新建一个技能¶
- 设置 → Dsh-Gen → 新建 → 技能
- 填写 名称(必填)与 说明(会出现在选择器卡片上,建议一两句话说清用途)
- 在 指令 里写角色设定,支持 Markdown;也可以点右上角 从模板选择 起步
- 在 知识 里添加本地文档(可选),右侧预览会同步显示
- 点右上角 保存
新建一个预设¶
- 设置 → Dsh-Gen → 新建 → 预设
- 填写 名称 与 内容
- 保存后自动回到预设标签页
在对话里使用¶
技能:
- 从设置页:点卡片上的对话气泡,直接开一个绑定好角色的新会话。
- 从会话里:点输入框左侧的胶囊,在技能卡组里选一张,当前会话立刻切换角色。
- 取消角色:打开选择器,点底部「取消技能角色」。
预设:
- 打开选择器,点底部切换按钮进入预设卡组,选一张。
- 内容会写进输入框,检查后再发送。
- 也可以长按拖拽「出牌」,效果相同。
备份与迁移¶
- 备份全部:导出全部技能与预设(含知识文件内容)为一个 JSON。
- 导入:把这个 JSON 或单个技能的导出文件喂回去。
- 换机器时也可以直接拷贝整个
$DSH_HOME/dsh-gen/目录。
工作原理¶
技能如何注册¶
插件加载时读取存储,为每个启用且 kind 为 skill 的条目调用:
ctx.skills.register({
name, // kebab-case,中文名会退化成 skill-<id 后缀>
description, // 以「技能名」开头,便于模型匹配中文标题
content, // Markdown 正文:## 指令 + ## 知识库(含绝对路径)
resourceBase: { kind: 'directory', path },
metadata,
});
模型通过 DSH 的 skill 工具按需加载这些条目。预设不注册成 skill,它只是文本。
角色如何注入会话¶
插件注册了一个全局 system prompt 区段,其正文是一个按会话 id 查表的函数:
会话 id → 技能 id → 该技能的名称/说明/指令/知识路径
这样做的两个好处:
- 角色是系统级设定,不会因为用户后续提问而失效;
- 给已存在的会话切换技能,下一轮立即生效,不需要重建会话。
绑定关系存在 gens.json 的 bindings 字段里,删除技能时会一并清理。
预设如何进入输入框¶
预设不走角色通道,它要的是「把文本放进输入框」。实现上有两条路径,优先官方 API:
conversation.input.setDraft(text)— 会话自己的草稿存储。输入框就是从这里渲染的,所以写进去的文本会正常参与重渲染与撤销,行为和手动输入一致。- DOM 兜底 — 若当前组合下拿不到
conversation服务,则直接写 live 的<textarea>/ contenteditable,用原生 value setter 让 React 的受控输入感知到变化。
两者都失败时会明确弹窗提示,不会静默丢弃。
前端如何拿到数据¶
宿主端(lib/index.js)通过 TypertRemoteService 暴露 14 个 RPC 方法:
| 方法 | 用途 |
|---|---|
listGens |
读取全部技能与预设,附工作区信息 |
saveGen |
新建或更新(同一事务里可附带知识文件与删除项) |
deleteGen |
删除条目及其知识文件 |
addKnowledge / removeKnowledge |
单独增删知识文件 |
readKnowledgeFile |
读取知识文件内容(含 128KB 预览上限与路径自动修复) |
cloneGen |
克隆技能或预设 |
exportGen / exportAllGens |
导出单个 / 全部 |
importPackage |
导入导出包 |
openWorkspace |
取回 dsh-gen 工作区的 id 与路径 |
bindSession / unbindSession / sessionBinding |
会话与技能的绑定关系 |
浏览器端(lib/client.js)用 ctx.remote.$mount() 挂载这些描述符,再通过 ctx.get('remote.dshGen') 调用。
文件结构与关联¶
dsh-gen/
├── package.json 插件清单:入口、导出、DSH 集成声明、peer 依赖
├── cordis.patch.yml 向 Cordis 插件树插入本插件的补丁行
├── README.md 本文档
├── LICENSE MIT
├── .gitignore 排除用户数据与构建产物
├── .npmignore 发布时排除开发文件
└── lib/
├── index.js 宿主端:存储、RPC、技能注册、提示注入、工作区
└── client.js 浏览器端:设置页 UI、选择器、查看器、RPC 描述符
各文件职责与关联¶
package.json — 插件身份的来源,DSH 靠它发现插件:
{
"main": "lib/index.js", // 宿主端入口
"exports": {
"./client": "./lib/client.js" // 浏览器端入口
},
"dsh": {
"bundle": { "patch": "./cordis.patch.yml" }, // 自动注册进插件树
"client": { "platform": "web", "inject": [...] } // 让前端 bundle 被发现
}
}
dsh.bundle.patch指向cordis.patch.yml,DSH 启动时据此把插件插入 Cordis 树。dsh.client声明这是一个 Web 端插件,并列出它依赖的前端服务。peerDependencies只声明宿主会提供的包(cordis、typert-protocol、react),因此插件本身不需要打包 node_modules。
cordis.patch.yml — 三行插件树补丁:
- insert:
- id: dsh-gen
name: dsh-gen
lib/index.js(宿主端) — 模块顶层 export const name = 'dsh-gen',apply(ctx) 里完成:
- 建立
$DSH_HOME/dsh-gen目录并注册为工作区(标题dsh-gen) - 读取 / 写入
gens.json(按mtime:size检测外部改动并自动重读) - 为每个启用的技能注册 runtime skill(预设跳过)
- 注册 system prompt 区段做角色注入
- 通过
TypertRemoteService暴露 RPC - 写
load-trace.log记录加载过程
lib/client.js(浏览器端) — 用 window.__ModuleLoader__.load({ id, factory }) 包装,在 apply(ctx) 里挂两个 UI 槽位:
| 槽位 | 组件 | 说明 |
|---|---|---|
s |
设置页 UI | 技能 / 预设列表、新建、编辑、导入、导出、备份等 |
s |
会话内选择器 | 输入框工具行上的胶囊按钮,切换技能 / 预设卡组 |
适用场景与注意¶
适合需要长期维护一套角色设定、提示词模板和知识文档的开发者,尤其是经常在多个会话中复用相同角色或指令的用户。安装前请检查源码与许可证,确保符合你的使用场景。
插件以当前 DSH 进程权限运行,所有数据存储在 $DSH_HOME/dsh-gen/ 目录下。换机器迁移时可直接拷贝该目录。
结语¶
dsh-gen 将零散的指令与知识文档打包成模型可调用的技能,通过设置面板和会话内选择器提供统一入口,兼顾易用性与灵活性。安装后打开设置 → Dsh-Gen,即可开始创建自己的技能与预设。
- 目录页:https://www.skillhub.cn/plugins/Idun/dsh-gen
- GitHub:https://github.com/Idun/dsh-gen