DeepSeek 官方开源 Agent 运行时 DeepSeek Harness(DSH)核心哲学是一切皆插件。
本文从底层 Cordis 内核讲透插件运行机制,结合开源项目
dsh‑workspace‑enhance文件列表增强插件,完整演示插件安装、源码解读、从零手写一个 DSH 插件的完整流程,适合想扩展 DSH 能力、自定义 Agent 工具链的开发者。
DeepSeek‑Harness 官方仓库
https://github.com/deepseek-ai/deepseek-harness
dsh-workspace-enhance
https://github.com/luis1232023/dsh-workspace-enhance
一、前言
DeepSeek Harness(简称 DSH)8 月 13 日正式开源,它不是大模型,而是Agent 运行时底座,公式:
Agent = 大模型 + HarnessDeepSeek。 不同于 Claude Code、Codex 这类成品应用,DSH 所有能力全部由插件提供:模型适配器、工具函数、会话存储、Agent 主循环、Web 界面全部是插件,可以热插拔替换,不需要修改框架源码。
默认 DSH 的 Web 端缺少直观的工作区文件树,Agent 只能通过工具调用扫描目录,模型反复遍历目录会消耗大量 token,
dsh‑workspace‑enhance就是解决该痛点的社区开源插件:给 DSH Web UI 增加可视化文件列表面板,同时向 Agent 注入结构化工作区上下文,减少不必要文件扫描,提升 VibeCoding 效率。
二、DeepSeek Harness 插件系统底层原理
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 美化插件 |
重点:很多新手踩坑,Host 插件不能操作 DOM;Client 插件不能直接访问本地文件系统,二者通过 DSH 内部事件总线通信。
2.3 插件加载流程
- dsh 启动读取 profile 配置,解析
bundles插件清单; - Cordis 内核解析每个插件
inject依赖,拓扑排序确定启动顺序; - 依次调用每个插件
apply(context),注册工具 / UI / 事件; - Agent‑loop 插件启动,大模型就可以调用插件注册的全部工具。
profile 配置存放目录:~/.dsh/profiles/web,插件实际安装到 profile 下面的 node_modules 中DeepS...。
三、实战 1:安装 dsh‑workspace‑enhance 插件
插件功能:给 DSH Web 页面新增侧边栏文件树,实时展示工作区文件结构;同时向 Agent 注入精简工作区摘要,减少模型重复调用 ls 扫描目录,降低 token 消耗。
前置条件
已经全局安装 dsh:
npm install -g @deepseek‑ai/dsh
安装命令(直接拉 GitHub 仓库安装)
# web profile 是我们网页端使用的配置集
dsh plugin --profile web add git+https://github.com/luis1232023/dsh‑workspace‑enhance
或者 直接 让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 服务
# 关闭旧进程,重新启动web服务
dsh web
访问 http://127.0.0.1:3080,侧边栏会多出Workspace Files标签,加载当前工作目录的文件树。

卸载插件
dsh plugin --profile web remove dsh‑workspace‑enhance
常见踩坑
- 安装插件之后没有效果:必须重启 dsh web,热重载不生效;
- 文件树空白:确认已经在 DSH 界面选择工作区文件夹;
- 报错 git not found:本地需要安装 git 环境,dsh 通过 git 协议拉取 github 插件源码。

四、dsh‑workspace‑enhance 源码深度解读
克隆源码到本地分析
git clone https://github.com/luis1232023/dsh‑workspace‑enhance
cd 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 后端,通过事件总线把数据推送到前端渲染。
架构优势:前后端分离,符合 DSH 设计规范,不会出现浏览器跨域、本地文件权限问题。
五、从零手写第一个 DSH 插件实战 demo
我们写一个极简插件:注册一个 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
typescript
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>`
}
})
}
步骤 4:编译 & 本地安装插件
pnpm run build
# 本地路径安装插件
dsh plugin --profile web add ./
重启 dsh web,Web 侧边栏出现 Demo 插件面板;对话中让模型调用demo_echo工具,即可执行我们自定义逻辑。
六、DSH 插件开发避坑清单
- 区分 Host 与 Client 环境 Host 插件(index.ts)运行 Node,可以读写文件;Client(client.ts)浏览器环境,不能 fs 读写,二者靠事件总线通信,不要混用 API。
- inject 一定要写全依赖 如果用到
tools、webview、systemPrompt,必须写进 inject 数组;否则插件启动的时候服务还未初始化,直接报错。 - 不要修改 DSH 源码 所有扩展全部通过插件完成,升级 DSH 版本不会丢失自定义能力。
- 插件卸载自动回收资源 定时器、事件监听,统一使用
ctx.effect(()=>{/*清理逻辑*/}),插件卸载自动执行清理,防止内存泄露。 - profile 隔离 web、headless 是两套独立配置,安装插件要指定
--profile web,headless 环境不会复用 web 的插件。
七、什么时候适合开发 DSH 插件?
- 需要给 Agent 新增自定义工具能力;
- 需要扩展 Web UI,增加侧边栏、自定义面板;
- 需要注入自定义 systemPrompt 片段,修改 Agent 行为;
- 需要监听 Agent 生命周期事件(会话开始、工具调用前后)。
如果只是简单提示词,直接对话写 prompt 即可;需要持久化能力、UI 扩展、工具注册,再开发插件。
八、总结
DeepSeek Harness 的一切皆插件不是营销口号,是落实在 Cordis 内核的架构设计。
dsh‑workspace‑enhance是非常好的入门样板插件,完整演示 Host‑Client 分离的开发范式:后端做业务逻辑,前端只负责渲染 UI。
DSH 生态刚刚爆发,大量第三方插件可以直接拿来扩展 Agent 能力;同时上手门槛并不高,掌握 Context、inject、apply 三个核心概念,就可以自定义属于自己的 AI Agent 工具链。




被折叠的 条评论
为什么被折叠?



