news 2026/9/6 8:03:22

从零手写DeepSeek Harness插件:构建、安装到发布GitHub全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零手写DeepSeek Harness插件:构建、安装到发布GitHub全流程

这次我们来看一个很实操的话题:从零手写一个正式的 DeepSeek Harness 插件,跑通“写代码 -> 构建文件 -> 装进插件目录 -> 发布到 GitHub”的完整闭环。DeepSeek Harness(下文简称 DSH)是一款面向大模型任务编排的桌面端工具,很多人在里面管理提示词、配置模型、跑批处理任务,但内置能力终究是有限的。想给 DSH 加上自定义命令、外部 API 调用或者专属工作流,最直接的方式就是写一个插件。

这篇文章不打算讲虚的。我会从项目初始化开始,带你把插件清单、入口代码、构建产物、本地安装、调试验证全部走一遍,最后把插件以开源项目的形式发布到 GitHub。这套流程走完,你的插件就已经具备被 DSH 插件市场收录的雏形。需要提前说明的是,DSH 不同版本的插件 API 可能有差异,文中的字段名和函数名是通用插件设计范式,实际落地时请以你安装版本的官方文档为准。

如果你已经在用 DSH,但觉得它不够“顺手”;或者你正想给团队内部工具链做一个能统一调用大模型能力的插件,这篇文章可以直接收藏。

1. DeepSeek Harness 插件核心能力速览

能力项说明
插件形态一个标准 Node.js 项目,提供插件清单和入口文件,DSH 启动时扫描并加载
开发语言JavaScript / TypeScript 均可,推荐 TypeScript 便于维护
运行环境Node.js 18+,包管理器建议使用 pnpm
插件目录通常位于用户配置目录下的plugins子目录,例如~/.deepseek-harness/plugins,具体路径以官方文档为准
主要功能注册自定义命令、调用外部 API、封装本地模型调用、扩展工作流节点、监听任务事件
发布方式GitHub 仓库 + Release 产物,后续可提交到 DSH 插件市场
适合场景本地工具链集成、团队内部技能沉淀、API 能力封装、批量任务编排

DSH 插件本质上是一个“被 DSH 宿主环境托管的小型 Node.js 模块”。它不需要独立启动服务,而是由 DSH 在进程内加载,通过注册函数把能力暴露给用户。这个模型和 VS Code 插件、JetBrains 插件的思路是类似的,只不过 DSH 的职责更聚焦在大模型工作流上。

2. 适用场景与使用边界

先想清楚你要用插件解决什么问题,再动手写代码。

DSH 插件适合做这些事情:

  • 给 DSH 加自定义命令,把重复操作收敛成一条指令。
  • 封装 DeepSeek API 或其他模型 API,让不熟悉接口的人也能直接调用。
  • 结合 Harness 的任务编排能力,做批量文本处理、批量翻译、批量摘要。
  • 把团队内部的提示词模板、工具调用封装成插件,统一对外提供服务。

同样,DSH 插件有些事不适合做:

  • 不适合在插件里做重型数据处理,DSH 的定位是编排和调度,不是数据清洗引擎。
  • 不适合绕过 DSH 的鉴权机制去直接读取宿主敏感配置。
  • 不适合把插件做成后台常驻服务,插件生命周期应该由 DSH 管理。

合规边界是必须提前说清楚的。插件如果调用大模型接口,API Key 一定不能硬编码在源码里,必须通过环境变量或配置项注入,并且不要把.env文件提交到 GitHub。插件在处理文本、图片、音频时,要考虑数据隐私,不能把用户未经授权的数据上送到公开服务。涉及人脸、声音、版权素材的,必须先确认授权。发布到 GitHub 时,选一个明确的 LICENSE,不要默认“代码公开了就是随便用”。

3. 环境准备与前置条件

在写代码之前,先把环境检查一遍。下面这份清单是通用要求,具体版本以你本机为准。

检查项要求验证命令
Node.js18 或更高版本node -v
包管理器pnpm 8 或更高版本pnpm -v
TypeScript5.x,编译用npx tsc -v
Git最新稳定版git --version
DSH 桌面端已安装,能正常启动从应用界面查看版本号

如果node -v报错,说明 Node.js 没安装或者没加入 PATH,先去官网安装 LTS 版本。pnpm 的安装方式比较简单:

npm install -g pnpm

DSH 插件目录的位置非常关键。不同操作系统的路径不太一样,我先给一个常见约定,你可以在 DSH 设置页或者官方文档里确认本机路径:

# Windows 通常是 C:\Users\<你的用户名>\.deepseek-harness\plugins # macOS / Linux 通常是 ~/.deepseek-harness/plugins

这个目录就是插件的“安装目的地”。DSH 在启动时扫描该目录,读取每个子目录里的插件清单,然后把插件加载到进程中。

另外,需要确认 DSH 是否提供了 CLI 工具,比如dsh命令。如果提供,可以在终端快速执行dsh --version,后续调试会更方便。不提供也没关系,我们后面主要通过界面日志来排查问题。

4. 初始化插件项目

先创建一个项目目录,并初始化package.json

mkdir dsh-plugin-demo cd dsh-plugin-demo pnpm init

pnpm init会交互式生成package.json。这里给一份更完整的示例,你直接替换掉生成的文件内容即可:

{ "name": "dsh-plugin-demo", "version": "0.1.0", "description": "A demo plugin for DeepSeek Harness", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsc", "dev": "tsc --watch", "clean": "rm -rf dist" }, "keywords": [ "deepseek-harness", "dsh-plugin" ], "license": "MIT", "devDependencies": { "typescript": "^5.4.0" } }

这里的核心字段是main,它指向构建产物的入口文件。DSH 加载插件时,会先看插件清单文件,再根据main字段找到真正的执行代码。

接着创建 TypeScript 配置文件tsconfig.json

{ "compilerOptions": { "target": "ES2022", "module": "CommonJS", "moduleResolution": "Node", "outDir": "dist", "rootDir": "src", "declaration": true, "strict": true, "esModuleInterop": true, "skipLibCheck": true }, "include": ["src"] }

这里采用 CommonJS 模块规范,因为 Node.js 环境下 CommonJS 兼容性最好,DSH 作为宿主进程加载插件时不容易踩模块规范冲突的坑。

如果 DSH 官方提供了插件类型声明包,例如@deepseek-harness/plugin-types,可以安装它以获得代码提示:

pnpm add -D @deepseek-harness/plugin-types

没有找到类型包也没关系,暂时用any声明上下文对象,跑通流程后再根据官方文档补类型。

5. 编写插件清单文件

插件清单是 DSH 识别插件的关键文件。它告诉宿主:插件叫什么、入口在哪、激活时机是什么、提供了哪些命令。下面用一个通用示例说明结构,字段名以你本机 DSH 版本为准。

创建plugin.json

{ "name": "dsh-plugin-demo", "displayName": "DSH Demo Plugin", "version": "0.1.0", "description": "A demo plugin for DeepSeek Harness", "main": "dist/index.js", "activationEvents": [ "onCommand:dsh-demo.sayHello" ], "commands": [ { "command": "dsh-demo.sayHello", "title": "Say Hello" } ] }

字段说明:

  • name:插件的唯一名称,建议用dsh-plugin-前缀,避免和其他插件冲突。
  • displayName:插件市场中显示的名称,可以更友好。
  • main:入口文件,和package.json里的main保持一致。
  • activationEvents:激活事件列表。DSH 不需要在启动时立即加载所有插件,而是等到某个命令被触发时才激活,这样启动更快,资源占用更低。
  • commands:插件对外暴露的命令列表。用户可以在 DSH 命令面板或界面上看到这些命令。

这段配置解决的就是“插件如何被发现”的问题。没有清单文件,DSH 无法知道这个目录是普通文件夹还是插件。

6. 实现插件核心逻辑

创建src目录,写入口文件:

mkdir src touch src/index.ts

先实现一个最简单的命令注册逻辑:

export function activate(ctx: any) { ctx.registerCommand("dsh-demo.sayHello", async (params: any) => { const name = params?.name ?? "DeepSeek Harness"; return { message: `Hello, ${name}!` }; }); } export function deactivate() { // 释放资源 console.log("dsh-plugin-demo deactivated"); }

这里的关键函数是activatedeactivateactivate在插件被激活时调用,ctx是 DSH 注入的上下文对象,里面提供了registerCommand这样的注册 API。deactivate在插件被卸载或 DSH 退出时调用,适合清理定时器、关闭连接。

ctx.registerCommand是通用插件设计范式,如果你的 DSH 版本里叫registerAction或者别的名字,替换一下即可,整体思路不变。

接下来,我们再写一个稍微“正式”一点的插件命令,让插件真正调用 DeepSeek API。这里给出通用请求示例,接口地址和模型名以 DeepSeek 开放平台文档为准:

export function activate(ctx: any) { ctx.registerCommand("dsh-demo.translate", async (params: any) => { const apiKey = process.env.DEEPSEEK_API_KEY; if (!apiKey) { throw new Error("DEEPSEEK_API_KEY is not set"); } const response = await fetch("https://api.deepseek.com/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${apiKey}` }, body: JSON.stringify({ model: "deepseek-chat", messages: [ { role: "system", content: "You are a translation engine. Translate the user input to English." }, { role: "user", content: params.text } ] }) }); if (!response.ok) { throw new Error(`API request failed: ${response.status}`); } const data = await response.json(); return data.choices?.[0]?.message?.content ?? ""; }); }

这段代码演示了三个关键点:

  • 通过process.env读取环境变量,而不是把 API Key 写死在代码里。
  • 使用 Node.js 18+ 内置的fetch,不需要额外安装请求库。
  • 命令函数可以是异步的,返回结果会交给 DSH 界面展示。

在开发阶段,可以通过.env文件配置环境变量,但.env必须放进.gitignore,绝对不能提交到 GitHub。

7. 构建插件并安装到插件目录

代码写好后,先编译成可发布的文件,再把文件“落”到 DSH 插件目录。这一步就是标题里说的“落成文件、装进插件目录”。

先安装依赖并构建:

pnpm install pnpm build

构建完成后,dist目录下会出现index.js。检查一下产物是否存在:

ls dist

然后把插件文件复制到 DSH 插件目录。以 macOS / Linux 为例:

mkdir -p ~/.deepseek-harness/plugins/dsh-plugin-demo cp -r dist package.json plugin.json ~/.deepseek-harness/plugins/dsh-plugin-demo/

Windows PowerShell 下可以这样:

New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.deepseek-harness\plugins\dsh-plugin-demo" Copy-Item -Recurse dist, package.json, plugin.json "$env:USERPROFILE\.deepseek-harness\plugins\dsh-plugin-demo\"

复制完成后,重启 DSH。启动后打开插件管理面板,正常情况下dsh-plugin-demo会出现在插件列表里,状态为“已加载”或“已启用”。

这里有一个常见误区:很多人只复制了dist,漏掉了plugin.json,结果 DSH 找不到插件清单,加载失败。所以复制时要确保plugin.jsonpackage.json都在插件目录下。

如果 DSH 界面看不到插件列表,可以检查插件目录的目录名是否和plugin.json里的name一致,部分版本的 DSH 会要求目录名等于插件名。

8. 功能测试与效果验证

插件装好后,按下面这张表逐项验证。

测试项输入预期结果通过标准
插件加载在 DSH 插件管理界面查看列表插件名称和版本号正常显示没有加载失败提示
命令调用执行dsh-demo.sayHello返回Hello, DeepSeek Harness!命令面板能看到输出
参数传递执行dsh-demo.sayHello,传入{ "name": "CSDN" }返回Hello, CSDN!参数能被正确解析
环境变量缺失不设置 API Key,执行dsh-demo.translate抛出明确错误信息提示DEEPSEEK_API_KEY is not set
API 调用设置 API Key,执行dsh-demo.translate,文本传一段中文返回英文翻译结果接口连通,结果正确

执行命令的方式取决于 DSH 的交互设计。如果 DSH 有命令面板,直接搜索命令名;如果插件命令可以绑定到界面按钮,也可以从界面上触发。

测试时如果命令一直不出现,优先检查activationEvents。很多插件系统要求命令必须先在事件列表里声明,才能被触发。示例里的onCommand:dsh-demo.sayHello就承担这个职责。

9. 日志与问题排查

插件运行中出现问题,先看日志。DSH 通常会把日志写到用户配置目录下的logs文件夹:

# macOS / Linux tail -f ~/.deepseek-harness/logs/dsh.log # Windows PowerShell Get-Content -Path "$env:USERPROFILE\.deepseek-harness\logs\dsh.log" -Tail 50 -Wait

在插件代码里,可以用console.log输出运行时信息,DSH 的日志面板一般会捕获stdout。如果你的 DSH 版本不显示console.log,可以改成往日志文件追加写入:

import fs from "fs"; import path from "path"; function log(message: string) { const logPath = path.join(process.env.DSH_LOG_DIR ?? ".", "dsh-plugin-demo.log"); fs.appendFileSync(logPath, `${new Date().toISOString()} ${message}\n`); }

调试时保持简单:先确认插件有没有被加载,再确认命令有没有被注册,最后才查网络请求和数据处理逻辑。不要一上来就怀疑 DSH 本身有问题。

10. 发布到 GitHub

插件在本地验证通过后,就可以正式归档并发布到 GitHub。发布不等于简单传一下代码,一个正式的插件项目至少包含三样东西:完整的代码仓库、清晰的 README、明确的 LICENSE。

先在项目根目录创建.gitignore

node_modules/ dist/ .env *.log

然后初始化 Git 仓库并提交代码:

git init git add . git commit -m "feat: init dsh plugin demo" git branch -M main git remote add origin https://github.com/<your-name>/dsh-plugin-demo.git git push -u origin main

推送代码后,打一个版本标签,创建 Release:

git tag v0.1.0 git push origin v0.1.0

在 GitHub 仓库页面的 Releases 区域创建一个新 Release,关联到v0.1.0标签,然后把构建产物dist打包上传。为了便于用户直接下载安装,可以在 Release 里附带dsh-plugin-demo.zip,里面包含distplugin.jsonpackage.jsonREADME.md

README 是容易被忽略但极其重要的部分。一份合格的插件 README 至少包含:

  • 插件是干什么的。
  • 环境要求:Node.js 版本、DSH 版本。
  • 安装方式:手动复制到插件目录,或通过 DSH 插件市场安装。
  • 使用方式:命令名称、参数说明、示例。
  • 配置项:需要设置哪些环境变量。
  • LICENSE 声明。

例如:

# dsh-plugin-demo A demo plugin for DeepSeek Harness. ## Features - `dsh-demo.sayHello`: Say hello to DeepSeek Harness. - `dsh-demo.translate`: Translate text using DeepSeek API. ## Install Copy `dist`, `package.json`, `plugin.json` to your DSH plugins directory. ## Usage Set environment variable `DEEPSEEK_API_KEY`, then run command `dsh-demo.translate`.

如果 DSH 插件市场支持通过 GitHub 仓库收录插件,按官方指引提交仓库地址即可。如果暂时不支持,GitHub Release 本身就是最直接的分发路径,用户下载压缩包后手动安装。

11. 常见问题与排查方法

问题现象可能原因排查方式解决方案
插件没有出现在 DSH 插件列表插件目录位置不对检查 DSH 配置里的插件路径把插件目录复制到正确位置
插件列表有名称,但命令无法触发plugin.jsonactivationEvents缺失检查命令事件是否声明补上onCommand:<命令名>
命令触发后提示找不到入口main字段路径错误检查dist/index.js是否存在重新执行pnpm build
构建报 TS 类型错误类型声明缺失查看报错信息先注释或改为any,后续补类型
API 调用超时网络环境不通或接口地址错误用 curl 单独测试接口连通性确认网络和接口地址
API 返回 401API Key 无效或未配置检查环境变量是否传入 DSH 进程在 DSH 启动前设置环境变量
修改代码后不生效插件未重载重启 DSH确认构建成功后再复制文件
插件加载时进程崩溃入口文件抛错查看 DSH 日志定位activate里的异常逻辑

这里单独说一下 API Key 的传递问题。如果你在终端启动 DSH,process.env会继承终端的变量;如果是双击应用图标启动,环境变量可能不会自动继承,这时候需要在 DSH 的设置界面里配置环境变量,或者使用官方文档推荐的方式注入。

12. 最佳实践与合规提醒

插件做得越久,越应该注意工程化细节。下面这几条是我建议你在发布插件前检查的:

使用dsh-plugin-命名前缀,避免与 npm 包名冲突。插件发布到 GitHub 后,如果后续上架 DSH 插件市场,好的命名习惯能减少很多麻烦。构建产物和源码分离管理,dist目录可以提交到仓库,方便用户直接下载使用,但不建议把node_modules提交进去。插件要提供最小测试用例,至少在 README 里写清楚输入输出,让别人能快速验证。如果插件支持批量任务,要在代码里做好失败重试和日志记录,避免批处理中途卡死。

合规方面再强调一次:不在代码中硬编码密钥,不把.env提交到仓库,不采集用户数据,不处理未授权的图片、音频、视频素材。插件调用第三方 API 时,要遵守目标服务的条款,避免用批量接口做超出权限的事情。想发布到公开平台时,检查 LICENSE 兼容性,如果不确定就用 MIT 这种宽松协议。

13. 总结与下一步

这次我们走完了一个 DSH 插件的完整生命周期:初始化项目、写plugin.json清单、实现activate注册命令、构建产物、复制进插件目录、本地测试、发布 GitHub Release。

最值得先验证的是插件能不能被 DSH 正常加载。只有加载成功,后面的事件监听、API 调用、批量任务才有意义。最容易踩的坑是插件目录路径错误和main字段指向不存在的文件,这两个问题排查起来并不复杂,但比较耽误时间。

下一步建议你去看安装版本对应的 DSH 官方插件开发文档,把命令注册、上下文对象、事件监听这些 API 替换成真实字段。如果官方提供了示例仓库,直接 clone 下来对照修改,比对着这篇文章硬套更准确。跑通一个最小插件之后,再去扩展你真正需要的能力,效率会高很多。

这篇教程覆盖的是插件开发的基础链路,适合作为你入职 DSH 插件生态的起点。可以先收藏备用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 5:53:26

STM32 TrustZone下手写UART中断:从安全配置到HAL回调全解析

上周处理一个 STM32L552 的项目&#xff0c;客户在已有 TrustZone 分区方案的前提下&#xff0c;要求给非安全侧新增一路 USART1 中断收发&#xff0c;还被特别要求不能重新跑 CubeMX 生成。原因很直接&#xff1a;工程里已经手工改过链接脚本、SAU 配置和安全侧初始化代码&…

作者头像 李华
网站建设 2026/9/4 5:45:54

公共桌面会话隔离工具:从输入校验到离线报告的完整实现

公共桌面会话隔离工具&#xff1a;从输入校验到离线报告的完整实现 项目编号&#xff1a;20260830-007。本文代码、测试、文档、示例数据和效果图均为独立编写&#xff0c;不包含热点产品或开源项目源码、品牌素材与官方截图。 问题与目标 核对访客会话、文件写入、剪贴板、下…

作者头像 李华
网站建设 2026/9/2 21:06:43

越华环保集团|河湖排污口云边协同数字化污水治理采集架构实现

美丽中国十五五规划推进&#xff0c;越华环保集团依托山东环保装备工程能力&#xff0c;落地美丽河湖保护与建设项目&#xff0c;解决户外站点数据丢包、脏数据干扰的技术痛点。 技术痛点/背景 沿河排污口污水站点处于户外高干扰工况&#xff0c;湿度大、污泥结垢、移动通信网络…

作者头像 李华
网站建设 2026/9/3 0:51:29

数组设计哲学:从C到Python、JavaScript的三种流派与实用指南

做开发的这些年&#xff0c;你会发现一个有意思的现象&#xff1a;很多人在字符串、对象、类上讨论得头头是道&#xff0c;但只要一碰到数组&#xff0c;各种匪夷所思的问题就冒出来了。同一个数组操作&#xff0c;在 C 里要自己管内存和长度&#xff0c;在 Python 里可能一行切…

作者头像 李华
网站建设 2026/9/3 1:39:37

英伟达5%营收或来自SpaceX:商业航天引爆GPU算力需求

这次我们看到一条很有意思的行业分析&#xff1a;市场估算英伟达季度营收中大约有 5% 可能来自 SpaceX。如果这个数字成立&#xff0c;意味着商业航天公司已经不只是 GPU 的尝鲜用户&#xff0c;而是能直接影响芯片大厂季度收入的关键客户。从纯技术视角看&#xff0c;这条消息…

作者头像 李华
网站建设 2026/9/6 1:21:48

Node.js后端环境搭建与nvm版本管理实战:从零构建RESTful API

最近在开发一个 Node.js 后端服务时&#xff0c;被版本兼容和依赖管理折腾了不少时间。刚好看到有个 Node.js 后端库发布了 1.0 稳定版本&#xff0c;这让我重新梳理了一遍从环境搭建、版本管理到后端开发的完整流程。网上相关的资料虽然多&#xff0c;但大多零散&#xff0c;有…

作者头像 李华