乐于分享
好东西不私藏

DeepSeek Harness 插件系统Cordis全解析——实战安装侧边栏带你深入了解、安装、卸载和制作!

DeepSeek Harness 插件系统Cordis全解析——实战安装侧边栏带你深入了解、安装、卸载和制作!

大家好,我是【考拉搞AI】,我又来啦!

这几天AI 圈子爆火的莫过于 DeepSeek Harness了,从8月13日到今天才4天,Github 都暴增到15万星了,恐怖如斯。

更让人惊叹的是:已经有人搓了客户端,并且插件也呈现疯狂生长趋势。这波潮流让我想起了最开始 AI 兴起,SKILL 爆火的时代。

之前的文章大致介绍了一下安装与使用,相信小伙伴们也有所了解。

作为一名AI圈子的博主,这波流量,阿不,这波最新技术,咱必须不能落后,必须好好体验一波,这不,最近几天好好研究了一番,并且将一些 VibeCoding 项目移动了上去,用起来感觉很顺手,下面两点是Claude Code、Codex 等 无可比拟的:

  • 1、web端打开,不用下载客户端
  • 2、可以自由切换模型,可以自由搭配插件、甚至可以配置loop Agent,完全可自定义自己的Agent,这是最吸引我的地方,未来肯定是各种插件满天飞,自由搭建自己智能体的时代即将开启
将个人VibeCoding 项目移动进来,使用效果嘎嘎的:

于是,博主研究决定从其插件系统入手,这也是这个技术的核心。

废话不多说,下面详细介绍插件系统,并安装一个 侧边栏插件【这几天用下来,发现缺失的东西有点多,用起来还是不够丝滑,比如左侧菜单没有文件和git等】,让小伙伴理解插件,同时也能更好的使用web agent。

二、插件底层内核:Cordis

2.1  Cordis

DSH 插件完全基于自研 Cordis 元框架,三个核心概念:

  • Context 上下文
  • inject 依赖注入
  • apply 插件入口

Context:全局共享上下文对象,所有服务(tools、systemPrompt、webview 等)挂载在这里。插件之间不直接互相 import,全部通过 Context 获取服务。

inject 数组:声明当前插件依赖哪些服务,框架等待依赖全部就绪,才执行插件逻辑。

apply(ctx):插件唯一入口函数,Cordis 内核自动调用,传入上下文。插件在这里注册工具、注册 web 插槽、监听事件、注册配置项。

副作用自动回收:插件卸载时,ctx.effect()注册的所有监听、工具注册会自动清理,避免内存泄漏。

2.2 DSH 插件两大分类

类型
运行位置
能力范围
典型例子
Host 插件(Node 侧)
后端 Node 运行时
注册工具函数、文件读写、命令执行、系统 Prompt 注入
自定义文件工具、git 操作插件
Client 插件(Web 侧)
浏览器前端
扩展 Web UI、新增侧边栏 Tab、增加弹窗、页面组件
dsh‑workspace‑enhance、各类 UI 美化插件

2.3 插件加载流程

  • dsh 启动读取 profile 配置,解析bundles插件清单; profile 配置存放目录:~/.dsh/profiles/web,插件实际安装到 profile 下面的 node_modules 中DeepS...。
  • Cordis 内核解析每个插件inject依赖,拓扑排序确定启动顺序;
  • 依次调用每个插件apply(context),注册工具 / UI / 事件;
  • Agent‑loop 插件启动,大模型就可以调用插件注册的全部工具。

三、安装 dsh‑workspace‑enhance 插件

前置条件 已经全局安装 dsh:

npm install -g @deepseek‑ai/dsh

DeepSeek Harness + H5 射击塔防小游戏有没有搞头? 从 下载安装 到 项目实战 全程跑通 DeepSeek 官方 web Agent 框架

直接 让deepseek 帮我们安装:

帮我安装插件 https://github.com/luis1232023/dsh‑workspace‑enhance

安装成功提示输出类似:

plugin dsh‑workspace‑enhance installed into profile web
Please restart dsh web service to load new plugin

重启 dsh 服务访问 http://127.0.0.1:3080

可以看到左侧有了菜单 和git,一个插件搞定,再也不用担心各大Agent 页面固定无法自定义了:

卸载插件

dsh plugin --profile web remove dsh‑workspace‑enhance
查看插件,可以搜索 dsh-workspace-enhance:

四、dsh‑workspace‑enhance 源码深度解读

我们来研究下 这个插件,触类旁通,然后就可以编写我们自己的插件。

目录结构

dsh‑workspace‑enhance
├── package.json          # dsh插件标识,dsh字段声明插件元信息
├── src
│   ├── index.ts          # Host侧插件入口 apply(ctx)
│   └── client.ts         # Client浏览器侧UI插件入口
└── tsconfig.json

4.1 package.json 关键片段(DSH 插件识别标记)

{
  "name": "dsh‑workspace‑enhance",
  "dsh": {
    "bundles": {
      "host": "./lib/index.js",
      "client": "./lib/client.js"
    }
  }
}

dsh.bundles是 DSH 识别插件的核心标记:

  • host:Node 后端插件编译产物
  • client:浏览器 Web 前端插件编译产物

4.2 Host 侧 src/index.ts 核心逻辑

import type { Context } from '@deepseek‑ai/cordis'
// 声明依赖,需要systemPrompt服务,用于注入系统提示词片段
export const inject = ['systemPrompt','workspace']

export function apply(ctx: Context) {
  // 监听工作区变更事件
  ctx.on('workspace:change', async (workspacePath)=>{
    // 读取目录结构,生成精简的文件树摘要
    const fileTree = await scanDirectory(workspacePath)
    // 将文件树摘要注入系统Prompt,模型自动感知当前项目结构
    ctx.systemPrompt.section('workspace‑context',`
【当前工作区文件摘要】
${JSON.stringify(fileTree,null,2)}
不要反复调用ls扫描目录,优先使用上面给出的文件列表
    `)
  })
}

async function scanDirectory(path:string){
  // 递归扫描本地目录,过滤node_modules、.git等忽略目录
}

Host 插件做两件事:

  • 监听workspace:change事件,工作区切换时扫描本地目录;
  • 将精简文件树注入systemPrompt,给大模型直接提供项目概览,减少工具调用次数。

4.3 Client 侧 src/client.ts 前端 UI 逻辑

import type { Context } from '@deepseek‑ai/cordis/client'
// 前端依赖webview服务,用于注册侧边栏tab
export const inject = ['webview']

export function apply(ctx: Context) {
  // 向DSH Web侧边栏注册新Tab标签页
  ctx.webview.registerSidebarTab({
    id:"workspace‑files",
    label:"Workspace Files",
    async render(el){
      // el是DOM容器,在这里渲染文件树组件
      el.innerHTML = `<div id="file‑tree"></div>`
      // 监听后端推送过来的文件树数据,渲染到页面
      ctx.events.on('workspace‑enhance:file‑tree',(tree)=>{
        renderFileTree(el.querySelector('#file‑tree'),tree)
      })
    }
  })
}

Client 插件只负责 UI 展示,不直接读取本地磁盘;文件扫描全部交给 Host 后端,通过事件总线把数据推送到前端渲染。

五、手写极简插件

接下来,我们可以写一个极简插件:注册一个 host 工具demo_echo,同时在 web 侧边栏新增一个简单 tab。

步骤 1:初始化插件项目

mkdir dsh‑plugin‑demo
cd dsh‑plugin‑demo
pnpm init
pnpm add @deepseek‑ai/cordis @deepseek‑ai/dsh‑tools typescript
tsconfig.json

{
  "compilerOptions": {
    "target":"ES2022",
    "module":"CommonJS",
    "outDir":"./lib",
    "strict":true
  },
  "include":["src/**/*"]
}
package.json 核心配置

{
  "name":"dsh‑plugin‑demo",
  "scripts":{"build":"tsc"},
  "dsh":{
    "bundles":{
      "host":"./lib/index.js",
      "client":"./lib/client.js"
    }
  }
}

步骤 2:编写 Host 插件 src/index.ts

import type { Context } from '@deepseek‑ai/cordis'
import { defineTool } from '@deepseek‑ai/dsh‑tools'
import z from 'schemastery'

// 声明依赖:需要tools工具注册服务
export const inject = ['tools']

export function apply(ctx: Context) {
  // 注册工具给大模型调用
  ctx.tools.register(defineTool({
    name:"demo_echo",
    description:"测试回显工具,把输入内容原样返回",
    schema: z.object({
      msg:z.string().describe("输入消息")
    }),
    async invoke({msg}){
      return { result:`demo插件收到消息:${msg}` }
    }
  }))
}

步骤 3:编写 Client 前端插件 src/client.ts

import type { Context } from '@deepseek‑ai/cordis/client'
export const inject = ['webview']

export function apply(ctx: Context){
  ctx.webview.registerSidebarTab({
    id:"demo‑tab",
    label:"Demo插件面板",
    render(el){
      el.innerHTML = `<h3>我的第一个DSH插件</h3>`
    }
  })
}

当然,我们直接让DeepSeek 帮我们写:

帮我写一个DeepSeek Harness 插件,主要功能是:
1、给右侧项目文件添加右键菜单;
2、右键菜单包含本地打开、浏览器打开、删除以及重命名等

八、总结

Deepseek Harness 地址:

https://github.com/deepseek-ai/deepseek-harness

插件地址:

https://github.com/luis1232023/dsh-workspace-enhance

博主认为接下来一段时间,这种 自定义插件式Agent 将会是一种AI Agent 规范和潮流,AI 大厂 如腾讯、阿里等都会相继推出的自己的 Harness 系统,直接对标ClaudeCodex

作为我们个体 VibeCoder 来说,利用好这些开源资源完成好我们自己的任务才是重中之重。

其次要好好研究插件,编写或者安装更多更好用的插件,让自己的 Harness 用起来更加丝滑即可。

比如,现在还欠缺这些插件:

  • 皮肤插件,必须整上花里胡哨
  • 上下文监控插件;
  • SKILL 仓库插件;
  • 右键菜单;

今天的分享到这里,接下来会继续分析更多VibeCoding实战技能和经验,欢迎点赞和关注!

更多内容,欢迎加入: