- Published on
一切皆插件:DeepSeek Harness 想重新定义 Agent 的“骨架”
- Authors

- Name
- Stone
参考资料
前言

大家都有插件,为什么 DeepSeek 还要强调「Everything is a Plugin」?
在我看见这个README 的时候就产生了一个疑问🤔,这有什么特别的?Claude Code 不也有 Plugin、Skill、Hook、MCP 吗?但实际上他们的差别是非常巨大的,你可以这么理解,Claude Code、Codex 是给房子添家具;DeepSeek 是连墙、门、厨房甚至户型本身都做成了可替换模块“
Claude Code / Codex
┌─────────────────────┐
│ Plugins │ ← Skills / MCP / Connectors...
├─────────────────────┤
│ Agent Core │ ← Loop / Runtime / 内置能力
├─────────────────────┤
│ Model │
└─────────────────────┘
而DeepSeek 走了一个完全不一样的路:
DeepSeek Harness
┌──────────────────────────────────┐
│ Cordis Core │
│ Service / Event / DI │
├──────────────────────────────────┤
│ Model Plugin Tool Plugin │
│ Skill Plugin Session Plugin │
│ Sandbox Plugin Storage Plugin │
│ Loop Plugin Scheduler │
│ UI Plugin ... │
└──────────────────────────────────┘
这个实现思路就和之前的完全不一样了,在 DeepSeek 的理解中,Harness 不应该是一套固定的 Agent 实现,而应该是一套组装 Agent 的框架 回到我们的疑惑,为什么 DeepSeek 要把一切都给插件化,为了解决什么问题?在我看来 DeepSeek Harness 是一个潜力非常大的产品,他将一切可插件化也就意味着他把可扩展性都交给用户,为什么现在 Agent 迭代这么快?为什么都没有一个统一的方案?各家都有各家的产品的实现思路? 实际上,现在大家都还在摸索阶段,对于 Agent 的开发并没有一个统一的标准,这一点在我之前和某大厂面试官交流的时候也能感受到 **那么在我看来,DeepSeek 将一切插件化,想解决的其实是 Harness 迭代速度跟不上模型迭代速度的问题。**现在 Agent 变化太快了。今天大家觉得 ReAct 好用,明天可能换成 plan-execute;今天用本地 shell,明天可能换 sandbox;不同模型甚至可能适合完全不同的 context 管理、tool calling、agent loop 如果这些东西全部写死在 Harness 里面,每做一次实验都得:
改核心代码
→ 测试
→ 处理耦合
→ 重新发布
而 DeepSeek 的思路是:
换一个 Plugin
→ 改配置
→ 重新组合
所以 Everything is a Plugin 最重要的价值其实不是“扩展性”,而是“可实验性”,与其说现在的 DeepSeek Harness 是一款产品,倒不如说是DeepSeek 相当于把 Harness 从一个产品,变成了一个实验台
体验 DeepSeek Harness:既然是实验台,那我们就做一个有点离谱的实验

先把 DeepSeek Harness 跑起来
目前最简单的体验方式是直接运行:
npm config set registry https://registry.npmjs.org/
npx @deepseek-ai/dsh web
终端里出现:
dsh web: http://127.0.0.1:3080
第一次打开时,它会提醒你这还是开发者预览版,并让你配置 DeepSeek API Key。这个阶段的 Harness 很明显还不是一个“下载完就能直接干活”的成熟产品,它更像是一套正在快速生长的开发框架
打开插件列表,我开始理解「Everything is a Plugin」了
llm、session、sandbox-local、agent-loop、tool-bash、compaction、storage,甚至 ui-layout 本身都是插件 给 Harness 装一个「拍桌中断器」
这个实验的目标可以拆成下面几步:
拍桌 / 敲击桌面
→ Web Audio API 检测瞬时声音峰值
→ 播放“我有异议”
→ 调用当前 Session 的 cancel()
→ AbortSignal 传到命令执行器
→ 终止正在运行的进程树
ui-objection 插件本身并不复杂,它是一个纯 Web 客户端插件,挂载之后会在 Harness 右上角多出一个「拍桌中断器」。为了避免直接使用游戏原声,我没有复制《逆转裁判》的音频,而是让浏览器通过 SpeechSynthesis 合成一句原创的“我有异议”,保留一点戏剧感就够了 analyser.getByteTimeDomainData(samples)
let peak = 0
for (const value of samples) {
peak = Math.max(peak, Math.abs(value - 128) / 128)
}
if (peak >= Number(threshold.value)) {
void object()
}
真正关键的代码反而只有几行:
const current = ctx.sessions.list.getSnapshot().current
const session = ctx.sessions.binding(current)?.session
const result = await session.cancel()
return result.ok
这里最能体现 Harness 的地方是:这个插件不需要让模型先“听懂”我在拍桌子,也不需要在 Prompt 里教模型什么时候停止。 它直接拿到了 Session 服务,在声音触发后调用 cancel()。取消信号会继续传给 Agent 和命令执行器,正在执行的 Bash 进程树也会被终止 换句话说,这不是“建议模型停下来”,而是在 Harness 的控制层直接踩下急刹车
拍一下桌子,会发生什么?
模拟拍桌触发后的状态这和给 Agent 写一个 Skill 有什么区别?
做到这里之后,我才真正理解 DeepSeek 为什么要强调 Everything is a Plugin 如果这是一个 Skill,我们能做的通常是告诉模型:
当用户拍桌子时,请停止当前任务 问题是模型根本听不到拍桌子,而且即使它“理解”了,正在运行的命令也不一定会立刻停止 但插件可以直接接触 Harness 的运行时服务。它可以监听浏览器事件、替换 UI、读取 Session、调用取消接口,甚至继续往下换掉 Sandbox 或 Agent Loop 所以 Skill 更像是教 Agent 一套新的做事方法,而 Harness Plugin 是在改造 Agent 的身体结构
实际体验之后,我怎么看 DeepSeek Harness?
ui-objection,也可以看到它已经被 Harness 正常挂载: ui-objection,可以单独看到它的挂载状态: 