DSH plugin 开发教程:从环境准备、脚手架到打包上架,DSH 插件开发完整教程与新手入门流程

插件开发发布于 2026-09-12作者: DeepSeek Plugin 插件市场
DSH pluginDeepSeek Harness插件开发教程Cordisbundle
DeepSeek Harness(DSH)插件开发教程:从准备 Node 与 pnpm、创建插件工程、用 cordis.yml 挂载调试,到打包成 bundle 并装进 profile 验证。六步跑通第一个可安装插件。

DSH plugin 开发教程的完整路径是六步:准备环境 → 创建插件工程 → 写 apply → 用 cordis.yml 挂载调试 → 打包成 bundle → 装进 profile 验证。 前三步让插件跑起来,后三步把它变成别人能装的包。本文按官方文档的顺序给出每一步的确切命令与预期输出。无论你把它叫 DSH插件 还是 DeepSeek插件,走的都是同一套插件框架与同一份命令约定。

DSH plugin 开发第一步:准备环境

DSH plugin 开发需要能跑源码版的 DeepSeek Harness,官方教程从仓库检出开始。 前置条件是 Node 与 pnpm 装好,然后 clone 并安装依赖(来源):

bash
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install

如果你还没装好宿主本体,先按《DSH plugin 开发环境搭建》把 Node 版本与 pnpm 配置妥当——版本不匹配会在后面每一步都制造假故障。

DSH plugin 开发第二步:创建插件工程

在仓库根下建一个临时目录放插件源码,tmp/scratch-* 都不进版本控制。 官方教程的做法:

bash
mkdir -p scratch-plugin/src

这不是必须叫 scratch-plugin,只是官方示例的命名。真正要遵守的只有一条:插件的模块路径由 profile 目录解析,本地调试时用绝对路径引用最省事,所以把源码放在检出内。

DSH plugin 开发第三步:写 apply 让插件能加载

一个 DSH plugin 最小就是导出 apply 的 TypeScript 模块。 创建 scratch-plugin/src/my-plugin.ts

ts
import type { Context } from '@deepseek-ai/cordis'

export const name = 'hello-plugin'

export function apply(ctx: Context) {
  // 必需依赖在 apply 运行前就已就绪。
  console.log('[hello-plugin] plugin loaded!')
}

name 是标识,apply 是入口,ctx 是注册能力的通道。想深入导出与命名的规范细节,见《DSH plugin 开发规范》。

DSH plugin 开发第四步:用 cordis.yml 挂载调试

--patch 覆盖层把本地插件插进配置树,启动 Web UI 看输出。 三步(来源):

  1. 取仓库根的绝对路径 —— 在仓库根执行 pwd预期:打印出仓库根的绝对路径,下一步的 name 要用它。
bash
pwd
  1. 写覆盖层配置 —— 创建 scratch-plugin/cordis.yml,把 name 换成上一步打印的真实路径:
yaml
- insert:
    - id: hello
      name: '/absolute/path/to/deepseek-harness/scratch-plugin/src/my-plugin.ts'
  1. 带 patch 启动 —— 执行下面的命令。预期:Web UI 在 http://127.0.0.1:3080 起来,启动过程中终端打印 [hello-plugin] plugin loaded!
bash
pnpm dsh web --patch ./scratch-plugin/cordis.yml

两个必须记住的点:插件路径必须绝对patch 文件只贡献配置,不会改变加载器解析模块路径的 profile 目录

DSH plugin 开发第五步:打包成 bundle

要让别人能装,就得把插件做成「组合包」(bundle)。 目录结构:

hello-plugin/
├── package.json       # 声明 dsh.bundle
├── cordis.patch.yml   # 该组合包贡献的配置层
└── index.js           # patch 行引用的插件模块

package.json 的四项声明:

json
{
  "name": "dsh-hello-plugin",
  "version": "0.1.0",
  "type": "module",
  "main": "index.js",
  "files": ["index.js", "cordis.patch.yml"],
  "dsh": { "bundle": { "patch": "./cordis.patch.yml" } }
}

cordis.patch.yml包名引用自己:

yaml
- insert:
  - id: hello
    name: dsh-hello-plugin

注意这里的差异:调试期的 cordis.yml 用绝对路径指向源文件,发布期的 cordis.patch.yml 用包名——因为安装后包已经在 profile 的依赖里解析得到。

DSH plugin 开发第六步:装进 profile 验证

add、再 --dump-config、最后启动,三步都不能省。 dsh plugin 会把参数转发给 profile 目录里的 pnpm(来源):

  1. 装进 profile —— 执行 dsh plugin --profile demo add ./hello-plugin预期:包被写进 profile 依赖;因为包声明了 dsh.bundle,DSH 会把它追加进 dsh.profile.bundles
  2. 核对配置层 —— 执行 dsh --profile demo --dump-config预期:打印出的配置树里能看到你的 patch 行。跳过这一步直接启动,很容易把「没挂载」误判成「插件代码有 bug」。
  3. 启动验证 —— 执行 dsh --profile demo预期:插件在运行中的插件树里生效,终端能看到它的输出。

想先看看社区里同类插件的成品长什么样,可以在 DSH Plugin Hub 里挑一个装起来对照。

六步跑通后,最容易卡住的三处:

  1. 路径写成相对路径 —— 第四步的 cordis.ymlname 必须是绝对路径,否则加载器从 profile 目录解析,找不到文件。
  2. 打包漏了 cordis.patch.yml —— files 里没写它,npm 不会带上,安装方拿不到配置层,插件装了不挂载。
  3. 本地目录安装与发布包混淆 —— dsh plugin add ./hello-plugin 装的是本地目录,与从 npm 装包的解析路径不同;本地目录安装的细节见《DSH plugin 本地目录安装》。

六步走通后,把成品提交到社区收录的流程见《DSH plugin 发布到插件市场》;如果插件装上了但一直不激活,按《DSH plugin 装了不生效》用 Fiber 状态定位。

来源:官方「你的第一个插件」官方 Cordis 教程dsh CLI README

常见问题

DSH plugin 开发教程里,从零到能装进 profile 一共要几步?

DSH plugin 开发教程的完整路径是六步:**准备环境 → 创建插件工程 → 写 apply → 用 cordis.yml 挂载调试 → 打包成 bundle → 装进 profile 验证**。前三步把插件跑起来,后三步把它变成可分发的包。官方教程要求从「已完成 run-from-source 的仓库检出」开始,也就是先有能跑源码版的 DeepSeek Harness(来源:官方「你的第一个插件」)。

开发 DSH plugin 一定要克隆整个 DeepSeek Harness 仓库吗?

开发 DSH plugin 的官方教程确实从仓库检出开始:官方要求在 clone 并 pnpm install 之后,从仓库根创建插件目录,再用 --patch 覆盖层加载本地插件。原因是插件的模块路径由 profile 目录解析,本地调试最省事的做法是把源码放在检出内、用绝对路径引用。如果你只想验证一个独立包,可以跳到第五步的 bundle 流程,用 dsh plugin add 安装(来源:官方「你的第一个插件」)。

DSH plugin 开发时怎么把本地插件挂进 Web UI 调试?

DSH plugin 开发时用 --patch 覆盖层挂载:先 pwd 拿到仓库根绝对路径,然后写一个 cordis.yml,用 insert 把插件路径插进配置树,最后 pnpm dsh web --patch ./scratch-plugin/cordis.yml 启动。**插件路径必须是绝对路径**,而且 patch 文件只贡献配置、不改变加载器解析模块路径的 profile 目录(来源:官方「你的第一个插件」)。

DSH plugin 打包成 bundle 时,package.json 必须声明哪些字段?

DSH plugin 打包时 package.json 至少要声明四项:**main 指向插件入口、type: modulefiles 包含入口与 cordis.patch.yml、以及 dsh.bundle.patch 指向该 patch 文件**。少了 files 里的 cordis.patch.yml,安装方拿不到配置层,插件装了也不会被挂载——这是打包环节最常见的漏项(来源:官方「打包与安装插件」)。

DSH plugin 开发教程里最后一步怎么验证安装成功?

DSH plugin 开发的最后一步是**先把配置层打印出来核对,再启动**:用 dsh plugin --profile demo add ./hello-plugin 装进 profile,接着 dsh --profile demo --dump-config 确认你的 patch 行已经进配置树,最后 dsh --profile demo 启动并观察插件输出。跳过 --dump-config 直接启动,会把「没挂载」误判成「插件代码有问题」(来源:dsh CLI README)。

相关术语

cordis.yml
cordis.yml 是 DeepSeek Harness 的配置树文件,描述有哪些插件、如何配置、如何组织。本地调试时可用一份 overlay 文件通过 --patch 叠加到现有 profile 上,插入尚未发布的插件。https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/cordis-tutorial/index.zh.md
bundle(组合包)
bundle 是 DSH plugin 的分发单位,由 package.json 的 dsh.bundle.patch 指向一份 cordis.patch.yml,安装后该 patch 会被追加进 profile 的 dsh.profile.bundles。https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/develop/basic/index.md
--patch(覆盖层)
--patch 是 DSH plugin 的本地调试开关,把一个额外的配置文件叠加到当前 profile 上,用于在不发布包的前提下把本地插件挂进运行中的插件树。https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/README.md

来源