拆完这篇 88 页论文,我终于看懂了 DeepSeek Harness

前天晚上,DeepSeek 把自己的 Agent 框架 DeepSeek Harness 开源了。
装好 Node,一条命令打开 Web UI,选择工作目录和填了 API Key,先让它给我更新了一个专属工作台,后来看到有朋友留言说只能本地跑,我试着让它自己修改了一下,支持本地局域网访问。昨天写文章时这个项目还是 50k+ Star,现在即将 100k 了!!!

DeepSeek Harness 的灵魂:一切皆插件。
模型、工具、Skills、会话、沙箱、文件系统、Agent Loop,甚至网页界面,全都可以换。
这句话很容易让人兴奋,也很容易被一句“插件化架构”带过去。可一个 Agent 已经连续工作两三个小时,手里攥着会话记录、工具结果和没跑完的任务时,插件还能像浏览器扩展那样说换就换吗?旧插件留下的监听器、定时器和服务,谁来收拾?依赖它的其他组件,又该按什么顺序停下来?

DeepSeek Harness 官方首页里就藏着这个秘密:Cordis以及Cordis 论文。我顺着这个链接翻到了这篇 88 页的论文:《A Programming Paradigm for Spatiotemporal Composability》,作者来自北京大学和 DeepSeek-AI。

读完之后,DeepSeek Harness 那句“一切皆插件”才算有了着落:插件不仅要装得上,还得拆得干净。
Agent = Model + Harness
大模型本身更像一颗大脑。它能理解问题、写代码、做判断,但它不会自己打开项目目录,也不会凭空拥有终端、浏览器、会话记忆和权限规则。
把这些东西接到模型外面,让它可以连续干活的那套系统,就是 Harness。

Claude Code、Codex,以及刚开源的 DeepSeek Harness,都在做这件事。一次 Agent 任务大致会这样跑:系统把历史消息和工具清单交给模型;模型决定调用哪个工具;Harness 执行命令,把结果记进会话;模型看完结果,再决定下一步。这个循环可能转几十次,也可能跨过多个上下文窗口。
DeepSeek Harness 的特别之处,是连这条循环本身都没有焊死。今天用 DeepSeek 模型和本地 Shell,明天可以换另一套模型适配器、远程沙箱或者新的 Agent Loop。同一套框架,也能用不同的插件组合拼出 Web 版、命令行版和面向特定任务的 Agent。
自由度上去了,运行时要处理的麻烦也跟着上来了。DeepSeek Harness 的奥秘就藏在这套 Cordis 内核里。

装插件不难,难的是拔掉以后
假设有一个会话日志插件。启动时,它订阅工具执行结果,每隔一秒把缓冲区写进磁盘。

插件代码退出,并不代表这两件事自动消失。事件监听器可能还挂在总线上,定时器也可能继续醒来。重新加载一次插件,新的监听器又注册一遍,往后每次工具调用可能被记两遍、三遍。
开发 Web 应用时,这类问题顶多让页面行为变怪。放到 Agent 里,残留的可能是旧权限、旧模型连接、后台进程,或者已经失效的工具实现。Agent 跑得越久,现场越难收拾。
最省事的办法当然是重启整个进程。VS Code 的扩展系统就是论文里的例子:作者检查了安装量前 100 的扩展,其中 87 个包含可执行代码;移除这类扩展时,需要重启 Extension Host。
重启编辑器还能忍。Agent 正在跑一项长任务时重启,内存里的连接、缓存和中间状态也会一起丢掉。为了换一个零件,把整台机器关掉再开,代价有点大。
Cordis 先解决的就是这个问题。
它要求插件每制造一个“副作用”,同时留下撤销办法:
ctx.effect(() => {
const stop = registerTool(...)
return stop
})
这里注册了一个工具,返回的 stop 负责把它撤掉。订阅事件就留下退订函数,启动定时器就留下 clearInterval,打开一个服务也要留下关闭方式。
这些清理函数会被 Cordis 记下来。插件卸载时,最后注册的先撤,最早注册的最后撤,像收工时按相反顺序把刚才搭起来的东西一件件拆掉。
论文给它起的名字是 Revertible Effects,可撤销副作用。名词有点硬,规矩其实很好懂:动过哪里,就把回去的路一起记下来。
这也解释了 Cordis 为什么不把启动和清理分散在两个文件里。注册监听器的代码旁边就是退订逻辑,创建资源的人当场说明怎么归还,隔半年再看也不必满项目找 onStop。
做过前端的朋友可能会想到 React 的 useEffect:回调里订阅,返回函数里清理。Cordis 的用途更广,服务、插件、定时器和事件都走同一条回收路径。
上游要走,先让下游松手
把自己留下的东西清掉,只解决了一半。插件之间还会互相依赖。

比如 Agent Loop 正在通过某个模型适配器发请求。此时直接卸载适配器,Agent Loop 手里可能还握着旧引用,下一步照样往一个已经退出的服务发消息。
Cordis 让组件用 inject 把依赖写明白。模型适配器准备好以后,Agent Loop 才启动;适配器准备退出时,Cordis 先把它标成不可用,通知依赖它的组件停下来。等下游松手以后,再回收上游服务。
论文把这部分叫 Reactive Coeffects,响应式协同效应。正文里的公式可以先放过,记住一个顺序就够了:拆承重墙以前,先把靠在墙上的东西挪开。
Cordis 里每个运行中的组件实例叫 fiber。它记录组件现在是等待、加载、运行还是卸载,依赖哪些服务,又留下了哪些清理动作。依赖出现,组件自动启动;依赖消失,组件按顺序停下;新版本加载失败,已经做了一半的修改也要撤回来。
这套机制还有一个很实用的结果:一次配置更新牵动多个插件时,系统不会只换成功一半。要么新组合完整起来,要么回到刚才还能工作的状态。
Cordis 也不是为 Harness 临时写的
Cordis 在 DeepSeek Harness 出现以前就存在,最早的大规模使用场景是聊天机器人框架 Koishi。

聊天机器人和 Agent 有个很像的地方:进程会长期运行,插件很多,配置经常变化。今天接 QQ,明天加 Discord;有人装命令插件,有人换数据库和权限模块。论文记录的 Koishi 生态在四年里积累了 4000 多个社区插件。
这些插件怎样装、怎样卸、谁依赖谁,Cordis 已经在这个现场里处理过很多年。Koishi 当前使用的是 Cordis v3,论文整理的是 v4,两者不能直接画等号;但这段经历说明,它面对的并不是纸面上才有的问题。
DeepSeek 也没有只在 package.json 里加一行依赖。Harness 仓库直接收进了 Cordis 源码,锁定到 4.0.1,当前 vendor 列出了 18 组本地修改。

其中不少改动都盯着长时间运行:生命周期允许重入,销毁过程继续加固,多份配置要像一次事务那样一起成功或一起回退。DeepSeek 真正在意的,是 Agent 换过几轮模型、工具和配置以后,系统还能不能保持清醒。
论文为什么会写到“自我进化”

论文开头把未来的“自我进化 Agent Harness”列成了主要动机之一。
想象一下,Agent 发现自己缺一种能力,于是写了一个新工具,当场装进运行中的系统;发现效果不好,再换一个版本。这个过程如果每次都要重启,当前任务会被反复打断。更麻烦的是,Agent 写出的坏插件可能把宿主一起弄坏,连负责恢复的进程都没了。

Cordis 想提供的底座是:新组件可以进来,坏组件也有路退出;依赖变化会通知相关模块,已经发生的会话事件仍留在追加式日志里。Agent 可以换零件,正在进行的工作不必跟着清空。
DeepSeek Harness 的 Creator 模式和全插件结构已经给这个方向留出了位置。
有些东西,撤不回来
Cordis 能收拾的,是通过 Context 登记过的东西。
插件写进外部磁盘的文件、已经发出去的网络请求、调用 API 花掉的钱,不会因为执行一次 dispose 自动复原。它们需要幂等设计、补偿操作或单独的事务机制。
inject 也只是管理组件能拿到哪些服务,不是安全沙箱。来路不明的插件仍然需要进程、运行时或容器隔离。
Koishi 的 4000 多个插件提供了长期工程经验,但论文没有给出一套受控实验,去量化 Cordis 比其他方案少了多少故障、节省了多少开发时间。
再回头看 DeepSeek Harness,模型选择反而只是表面的一层。
模型决定 Agent 能想到什么;Cordis 管的是它连续干了几个小时、换过几轮零件以后,会不会把工具、连接和旧状态散落一地。
Agent 能跑起来,靠的是模型;能一直跑下去,还得看外面这套系统会不会收拾现场。



参考链接
DeepSeek Harness:https://github.com/deepseek-ai/deepseek-harness DeepSeek Harness 架构文档:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md DeepSeek Harness Agent 生命周期:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/agent-lifecycle.md Cordis 入门文档:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/cordis-primer.md DeepSeek Harness vendored 依赖说明:https://github.com/deepseek-ai/deepseek-harness/blob/master/vendor/README.md Cordis 论文与 PDF:https://github.com/cordiverse/paper Cordis 项目:https://github.com/cordiverse/cordis DeepSeek Harness 拆解:一套能拼装的 Agent 架构(chino)
