乐于分享
好东西不私藏

DeepSeek Harness 的插件,到底该怎么用?

DeepSeek Harness 的插件,到底该怎么用?
   

DeepSeek Harness 发布不到两天,GitHub Star 就逼近了 10 万。⭐

   

一个 Agent Harness 能获得这么高的关注度,我自然也想看看它到底有什么不同。

   

它有一句很醒目的设计宣言:

   
     

Everything is a plugin.

     

一切皆插件。

   
   

这里的“一切”不只是我们熟悉的工具和扩展。

   

模型是插件,会话是插件,Agent 是插件,定时器也是插件。

   

模型和会话显然不是可有可无的附加功能。如果连这些组成 Agent 的基础模块都叫插件,那么它的主程序到底还剩下什么?

   

本地安装启动后,进入「设置 → 插件 → 插件列表」,里面可以看到 llmsessionagenttimerapi-gateway 等一大批已经启用的插件。

   
         
   

但回到对话框,我既找不到一个统一的“插件入口”,也不能直接告诉模型“请调用 session 插件”。有些能力会出现在工具调用记录里,有些会改变页面,还有一些从头到尾都看不到,却一直在后台工作。

   

这和 Chrome 插件商店完全不是一回事,也不像我们平时说的 Tool、Skill 或 MCP。

   

那么,这些显示“已启用”的插件,用户到底要怎么体验?

   
     

01 有哪些插件?

               
   

除了这些内置插件,社区里也已经出现了大量 DSH 扩展。在 GitHub 的 dsh-plugin Topic 下,已经聚集了 4k 多个相关仓库。

   
         
   

Awesome DSH Plugin 也整理了不少可以直接安装的插件。不过,这是社区维护的插件索引,不等于官方推荐,安装前还是要留意源码、依赖和权限。

   

虽然它们都叫插件,但安装后带来的变化并不相同。按照插件向 DSH 登记的主要能力,大致可以从下面几个方向理解:

   
     

Tool
给模型增加 CSV、JSON、正则、图片理解、电脑操作等新动作。

     

UI / Web Client
给 Web 页面增加任务看板、Git 图谱、文件面板、主题和统计信息。

     

Service / Provider
为模型、搜索、文件系统、Shell 或沙箱提供新的底层实现。

     

Command
增加可以由用户直接执行的命令,不需要模型判断是否调用。

   
   

除此之外,还有一些插件会提供新的应用入口,或者把多种能力组合成一个完整场景。例如,dsh-TUI 提供终端界面;DSH Automation 把定时任务、会话与管理页面组合在一起;dsh-minigames 则把小游戏放进 Web UI。

   

这些名称描述的是插件主要提供了什么能力,并不是互斥的固定类型。一个插件可以同时包含 Tool、UI 和 Service。

   

我们看几个热度比较高的插件,就能直观理解插件最终怎样被用户体验。

   

DSH Web UI

   

DSH Web UI 与其说是一个插件,不如说是一组围绕 DSH Web 版开发的扩展合集。

   

它是在 DSH 原有页面上增加新的界面和功能,例如任务看板、Git 图谱、文件预览、实时 Token 统计、主题皮肤和桌面宠物等。其中的远程连接和 SSH 插件,还可以把 DSH 的使用范围扩展到其他设备或机器。

   
         
   

从图中可以直接看到几处变化:左侧增加了任务看板和会话工作区;中间的会话页面换上了新的皮肤,并显示了桌面宠物;输入框下方还增加了 TPS、模型耗时、上下文占用和 Token 数量等实时信息。

   

这就是 UI 插件和 Tool 插件最直观的区别。

   

UI 插件扩展的是 DSH 的网页界面,并不会给模型增加一个名为 dsh-web-ui 的工具。安装并启用以后,用户直接在页面上点击新增的入口,或者查看它展示的信息,不需要在对话框里告诉模型“调用 DSH Web UI”。

   

如果只想观察一个小变化,可以单独安装实时统计插件:

   
     

安装命令

     

npx @deepseek-ai/dsh plugin --profile web add @linxin666/dsh-live-stats

   
   

安装完成后,重新启动:

   
     

启动命令

     

npx @deepseek-ai/dsh web

   
   

随便发起一次对话,如果输入框下方出现 TPS、模型耗时、上下文占用和 Token 数量等信息,就说明插件已经生效。至于它是如何进入 web Profile,又是如何把界面挂到原有页面上的,后面的原理部分再通过 Bundle 和 Web Client 入口解释。

   
     

⚠️ 这里不建议默认安装整套 UI 插件。集合中还包含 SSH、移动端远程和公网隧道等能力,权限与依赖范围明显更大,可以根据需要选择单个插件。

   
   

ModLens

   

ModLens 是当前社区里热度较高的非 UI 插件之一。它解决的问题很直接:给纯文本模型补上图片理解能力。

   
         
   

用户可以粘贴一张报错截图,然后直接提问:

   
     

请读一下这张截图,告诉我报错内容和最可能的原因。

   
   

用户不需要记住 Tool 名称。ModLens 会向 DSH 注册 modlens_read_image,模型判断需要读取图片时,就会调用这个工具。

   

不过,这并不代表纯文本模型突然获得了原生视觉能力。图片会先交给 ModLens 配置的视觉引擎,得到 OCR、页面布局和语义等结构化证据,再把结果交回原来的文本模型继续分析。视觉引擎可以是单独配置的 API,也可以在用户授权后复用本机已有的 Agent CLI。

   
     

🔐 截图可能会被发送给对应的视觉服务,不要上传包含 API Key、账号或客户数据的敏感图片。

   
   

把这两个例子放在一起看,开头那个问题就有答案了:

   
     

DSH Web UI 注册的是页面和客户端能力,安装后直接在界面里使用。

     

ModLens 注册了图片读取工具和对应的 Web Client 能力,用户粘贴图片并正常提问,模型会在需要时调用它。

     

sessiontimer 一类基础插件主要在后台工作,用户可能根本看不到入口。

   
   

插件列表只是告诉你:这次启动的 DSH 加载了哪些组件。它不是一张等着你逐个点击的功能菜单。想知道一个插件怎么用,要看它把能力放在了哪里。

   
     

02 「一切皆插件」是怎么实现的?

               
   

DSH Web UI 改变的是页面,ModLens 增加的是图片理解能力。它们功能不同,却使用相同的方式进入 DSH。区别不在于它们属于哪一种固定插件类型,而在于加载后向系统登记了什么能力。

   

插件安装后,发生了什么?

   

执行安装命令以后,DSH 先把插件的 npm 包下载到指定的 web Profile。npm 包只是代码和配置文件的载体,真正决定它如何进入 DSH 的,是包内声明的 Bundle。

   

一个普通 npm 包即使下载成功,也不会自动变成 DSH 插件。只有它通过 dsh.bundle 告诉 DSH 从哪里读取配置,安装工具才知道怎样把它接入当前 Profile。

   

Bundle 可以理解为这个包贡献的一层配置。它通过 npm 包 package.json 中的 dsh.bundle 声明,告诉 DSH 应该把哪些 Plugin 加入配置树。安装工具识别到这项声明后,会把这个 Bundle 追加到 web Profile 的 Bundle 列表中。

   

这里的 Profile,代表本次启动要组合哪些 Bundle。它可以包含 DSH 的基础能力、Web 应用,也可以加入 ModLens 这样的第三方插件。启动时,DSH 按顺序应用这些 Bundle 的配置,最终得到一棵真正要加载的插件树。

   

接下来才轮到 Plugin。Plugin 是真正被加载并提供功能的模块。Cordis 是 DSH 的插件运行底座,负责按照配置加载插件、处理依赖和管理插件生命周期。插件卸载时,通过 Cordis 登记的工具、服务和事件会一起撤销;插件自己创建的定时器或连接,则需要提供对应的清理逻辑。

   

四个容易混淆的概念,也在这条链路上各有位置:

   
     

npm 包
代码和配置文件的载体。

     

Bundle
告诉 DSH 这个包贡献哪一层配置。

     

Profile
记录本次启动要组合哪些 Bundle。

     

Plugin
真正被加载并提供功能的模块。

   
   
         
   

登记的能力,决定插件从哪里被用户看到

   

Plugin 被加载以后,可以向运行时登记不同能力:

   
     

Web Client
页面出现面板、按钮或统计信息。

     

Tool
模型可以根据任务发起工具调用。

     

Service
供其他插件使用,用户可能看不到直接入口。

     

Command
用户可以直接执行命令,不需要模型判断。

   
   

这些不是四种互斥的插件类型,而是几种常见的扩展位置。一个 Plugin 可以同时登记多种能力,ModLens 就同时包含 Web Client 和 Tool。

   

因此,DSH Web UI 安装后主要表现为页面发生变化;ModLens 则既要接收用户粘贴的图片,又要把 modlens_read_image 提供给模型。它们进入 DSH 的方式相同,最终的使用入口却不同。

   

Preset 不属于插件安装链

   
     

Tool 注册到 DSH 运行时后,模型能否在当前会话中看到它,还取决于这个 Agent 获得了哪些能力。官方架构文档把 Agent Preset 描述为组装不同会话能力集合的一种方式,可以组合某个 Agent 使用的工具、Skill 和规则。

     

所以,Preset 不应该放在 npm 包、Bundle、Profile 和 Plugin 的安装主链中。它更像安装完成后的能力组合:插件先把 Tool 登记到运行时,具体会话再根据自己的能力配置使用它。

   
   

这也解释了为什么插件列表显示“已启用”,不一定等于当前对话中的模型已经能够调用它。

   

以 ModLens 为例,一次读图是怎么发生的?

   

用户在 Web 页面粘贴一张报错截图并提问,Web Client 接收图片,把图片路径和问题交给 DSH Agent。DSH 会把当前问题和可用工具交给文本模型;当模型判断需要读取图片时,就会调用 modlens_read_image

   

ModLens 再把图片交给已经配置好的视觉引擎,获取 OCR、页面布局和语义等结构化证据。证据返回 DSH Agent 后,原来的文本模型继续分析,并组织出最终回答。

   
         
   

现在再回头看 llmsessiontimer、DSH Web UI 和 ModLens,功能虽然完全不同,共同点却是:都通过 Cordis 被加载,向运行时登记能力,与其他组件协作,并按各自的生命周期退出。

   

“一切皆插件”描述的是 DSH 的组装方式。它不是说所有插件都有按钮,也不是说所有插件都能在聊天框里点名调用。

   
     

03 借助 AI,把一个真实需求做成 TaskDeck 插件

               
   

理解 DSH 的插件机制以后,我想每个人都可以借助 AI 开发自己的插件。

   

碰巧,我正好有个痛点:我同时运行多个开发和调研任务时,经常需要在不同会话之间来回切换,才能确认哪个任务还在运行、哪个正在等待回复、哪个已经失败。任务数量一多,注意力就花在了反复检查状态上。

   

所以我想做一个 TaskDeck。它不是一套完整的项目管理系统,而是一个放在 DSH Web 页面里的任务态势面板:把正在执行、等待用户、可能阻塞、已经完成和失败的任务集中展示出来,需要处理哪个任务,打开页面就能看到。

   
         
   

目前这版 TaskDeck 已经可以从侧边栏打开,按照项目筛选任务,并用「待规划、待办、进行中、已完成、已失败」五列展示任务。任务可以关联 DSH 工作区,从看板发起执行,并根据对应会话的事件更新生成中、工具执行、等待用户、完成和失败等状态。

   

顶部的态势区域会汇总进行中、等待处理、可能阻塞、失败和今日完成的数量。任务记录暂时保存在浏览器本地。需求文档中规划的 ETA、分级通知、等待期建议和智能优先级,还没有全部进入当前版本。

   

先确认需求,再让 AI 实现

   

开发一个插件并不是一句「帮我做一个任务看板」就能描述清楚。任务如何定义、状态从哪里来、什么叫阻塞、插件需要读取哪些会话事件,这些问题没有确认,AI 很容易做出一个只有静态卡片的普通看板。

   

因此,在开始编码前,我先和 AI 反复确认需求,并整理成一份 requirement.md。你也可以采用相同方式:先让 AI 通过提问把使用场景、MVP、数据来源、权限边界和验收标准写清楚,确认需求文档后,再把它交给 Codex、Claude Code 等可以读取本地项目的编码 Agent。

   

下面这份提示词不限定插件必须是 TaskDeck。只需要替换需求文档、DSH 源码、插件目录和目标 Profile 的路径,就可以用来开发自己的插件。

   
     

交给编码 Agent 的提示词

     

请根据需求文档和本地 DeepSeek Harness 源码,实现一个可安装、
可验证、可卸载的插件。

需求文档:<requirement.md 绝对路径>
DSH 源码:<deepseek-harness 绝对路径>
插件目录:<输出目录绝对路径>
目标 Profile:<例如 web>

要求:

- 只实现需求文档确认的 MVP。
- 先读取当前 DSH 的文档、示例、类型和源码,不要凭记忆猜 API。
- 开发阶段只修改插件目录,不修改 DSH 源码,也不要直接编辑 node_modules。
- 只有收到“确认安装”后,才能修改指定的测试 Profile;不要影响其他 Profile 和现有配置。
- 遇到需求歧义或缺少扩展点时,停止并向我确认。
- 没有测试结果,不要声称功能可用。

按三个阶段执行:

1. 分析
确认所需的 Plugin、Web Client、Tool、Service 或 Command,列出真实 API、文件计划、权限风险和验证方法。不要写代码,等待我回复“确认开发”。

2. 开发
收到“确认开发”后实现插件,逐步运行类型检查、测试和构建,补齐 Bundle、客户端声明和卸载清理逻辑。构建完成后汇报结果与所需权限,不要安装,等待我回复“确认安装”。

3. 验证
收到“确认安装”后,安装到测试 Profile,使用 --dump-config 检查配置,启动 DSH 并按需求文档验收。最后给出使用方法、真实测试结果、已知限制和卸载命令。

   
   

以 TaskDeck 为例,最终生成的 npm 包同时声明了 Bundle 和 Web Client。Bundle 让它进入 web Profile,Web Client 则把侧边栏入口、任务看板和状态信息加入页面。因此,用户看到的是一块新的 UI,而不是在聊天框里调用一个名为 TaskDeck 的 Tool。

   

TaskDeck 当前只实现了任务执行、状态识别和集中展示。ETA、系统通知和等待建议仍是后续规划。DSH 也还在快速迭代,开发时应读取本地版本的源码和类型,并优先安装到独立测试 Profile。

   

插件列表不是应用商店,也不是 Tool 菜单。看清插件如何进入 Profile、登记了什么能力,以及用户最终从哪里使用它,「一切皆插件」就不再只是一句设计口号。

   

希望能帮助到大家,对大家有用。
谢谢你愿意认真看到这里。
愿你始终对世界保持好奇。