2026 年 8 月 13 日,DeepSeek 开源了一个叫 DeepSeek Harness(命令行叫 dsh)的 Agent 运行时,MIT 协议,一天之内 star 数冲到几万。它常被拿来和 Claude Code 对标,但内核思路完全不同。
一句话概括它:一切皆插件——模型、工具、会话、沙箱、权限、Agent 循环,甚至连 UI 本身,都是可以动态替换的插件。
这篇文章分两部分:先讲 dsh 本身怎么用、为什么"一切皆插件"是个大招;再往下拆它的底层引擎 Cordis——一个把"插件热插拔"做成数学保证的元框架。
一、dsh 是什么:一条命令跑起来
环境要求 Node.js 22.19+,一条命令就能启动 Web UI:
npx @deepseek-ai/dsh web
浏览器打开 http://127.0.0.1:3080,配个 API Key、选个工作区,就能像用 Claude Code 一样让它读代码、跑命令、改文件。
它内置四种运行模式:
| 模式 | 说明 |
|---|---|
| Standard | 完整编码 Agent(文件编辑、Shell、搜索、规划、子 Agent) |
| Code | 工具通过 Code Mode SDK 暴露,模型可把多步操作组合成一段代码 |
| Minimal | 只有持久 bash + 编辑器,专为 benchmark 评测设计 |
| Creator | 标准模式 + 运行时自省,支持动态挂载/卸载临时插件 |
关键点:这四个模式不是写死的分支,而是不同的"插件组合"。切模式 = 换一套插件集。
二、为什么"一切皆插件"是个大招
传统 Agent 框架(包括很多你用过的)都有一个特权核心:模型路由、工具执行、会话管理、沙箱是框架内置的,想扩展只能在外围打补丁。
dsh 反过来了。它的论文原话是"没有需要打补丁的特权核心"。所有能力通过 Cordis 的"服务接口"(context key)暴露,比如:
ctx.llm→ 模型适配器ctx.tools→ 工具注册表ctx.sessions→ 会话日志ctx.agentLoop→ Agent 驱动循环
消费者不直接 import 某个 provider,而是依赖这个稳定接口。于是换一个 provider 就能全局传播:把 filesystem provider 从本地换成远程沙箱,Bash、PTY、LSP 自动跟着迁移,无需改任何一处。
三、底层引擎 Cordis 拆解
dsh 的地基是一个叫 Cordis 的元框架(meta-framework)。它来自 Koishi 聊天机器人框架(作者 Shigma),已经在生产环境跑了 4 年、4000+ 社区插件验证过。DeepSeek 把它 vendored 进 harness,作为一切插件的运行时。
Cordis 自己的定位很拗口:Spatiotemporal Composability(时空可组合性)的元框架。翻译成人话:它解决的是"组件在运行时被加载、卸载、重配,且不出乱子"这件事。
3.1 它解决的真实痛点
现代软件越来越需要动态组合:插件运行时加载/卸载。但传统组合是静态的——函数调用、模块导入、类继承都在编译期锁死。
最经典的案例是 VSCode:论文统计,VSCode Marketplace 前 100 个扩展里,87 个含可执行代码,一旦激活就无法在运行时单独卸载,禁用后必须重启整个扩展宿主。
"插"件,实际上插上去就拔不下来。
Agent 场景里这更致命:一个 Agent 运行时塞满工具、沙箱、权限、记忆、会话状态,本就复杂;如果每次自我修改都要重启,累积的上下文和缓存全丢。
3.2 数学根基:Effect 与 Coeffect
Cordis 的理论支点来自编程语言理论的两个经典概念,并把它们从编译期静态标注提升为运行时机制:
- Effect(效应):程序对环境的修改(写文件、发请求、改状态)
- Coeffect(余效应):程序对环境的依赖(读配置、调服务、访问资源)
3.3 两大核心机制
① Revertible Effect(可逆运行时效应)
每一个副作用都必须同时返回它的"逆操作"。运行时把这些逆操作按 LIFO(后进先出) 累积,卸载时反向执行,自动把环境恢复到组件加载前的状态。
ctx.effect(() => {
const server = listen(port)
return () => server.close() // 交出逆操作,卸载时自动执行
})
开发者再也不用肉眼记住"该释放什么"——清理成了框架的默认能力。
② Reactive Coeffect(反应式上下文依赖)
组件声明它需要什么依赖(key),当这个 key 的值变化时,框架自动通知依赖它的组件重启或重算。
于是:替换一个服务,依赖它的插件自动重启;依赖暂时不可用,插件安静等着,等依赖出现再自动启动。无需手写拓扑排序。
3.4 生命周期与"时空可组合性"
每个组件实例是一个 Fiber,有 INACTIVE → LOADING → ACTIVE → UNLOADING 的状态机。卸载时按 LIFO 深度优先(父卸载前先卸子),且保证 provider 必须比 consumer 活得久。
这带来两个进阶能力:
- 时间可组合性:声明式配置 + HMR,改配置文件只重载受影响的组件,不停服、不丢状态
- 空间可组合性:coeffect isolation(多租户/沙箱隔离)、coeffect interception(不改 provider 动态加权限)
3.5 五条元理论定理
论文还给了动态组合演算,并证明五条定理(翻译成人话):
| 定理 | 人话 |
|---|---|
| 保持性 | 无论怎么组合,系统结构不会被搞坏 |
| 恢复精确性 | 组件拆掉后,世界恢复到它来之前的样子 |
| 排序 | 依赖解析确定,provider 一定比 consumer 活得久 |
| 进展 | 无死锁,一定会到达静止态 |
| 合流性 | 加载顺序不影响终态——所以 loader 敢做增量协调 |
四、在 dsh 中怎么落地:Creator 模式
第四档 Creator 模式是一组自指的 Cordis 工具:Agent 能检查当前运行时的插件树,动态挂载/卸载临时插件——临时写个事件监听器、注册个新工具、提供一个服务,任务完成后自动卸掉。
这相当于"让汽车在高速公路上给自己换发动机"。项目因此默认不开启,信任等级等同于 shell 访问;临时插件只存进程内存,重启即消失。
这正是"自进化 Agent"的雏形:Agent 发现手头工具不够,自己造一个、用完了再卸掉,全程不停服。
五、对开发者的启示
如果你正在做 Agent 工程化(异步、重试、热更新、依赖管理),Cordis 几乎是一份参考答案:
- 把"清理"变成一等公民:每个操作登记逆操作,失败/超时自动回滚,不用人肉释放资源——直接解决"重试/回滚"痛点
- 声明式 > 命令式:用声明式配置描述"要什么",让 loader 去协调,降级和回滚都变简单
- 无特权核心:你的 Agent 循环、记忆、工具都应该是可替换插件,而非硬编码核心——这样能从 1 个 Agent 平滑演进到多 Agent
最值得偷师的不是某个 API,而是那个核心哲学:让清理、回滚、依赖、热更新成为框架的默认能力,而不是开发者的负担。
结语
dsh 不是又一个套壳 Agent。它把"插件热插拔"从开发者的小心翼翼,变成了有完整演算和五条定理保证的工程现实。而 Cordis 这块地基——不关心你跑的是聊天机器人还是 coding agent,只保证楼能热替换、不塌、不互相污染。
对正在自研 Agent 平台的团队来说,这才是真正该抄的作业。
夜雨聆风