DeepSeek Harness的Cordis:AI Agent生命周期管理框架

近日,DeepSeek正式开源了自研的Agent框架DeepSeek Harness,不少开发者第一时间体验后都反馈框架使用流畅度极佳。部署过程十分简便,只需安装好Node环境,执行一条命令即可打开Web交互界面,选择工作目录并填入API密钥后,框架会自动生成专属开发工作台。有用户反馈默认仅支持本地运行,经过简单修改后就能支持局域网访问。截至目前,该项目的Star数已从50k+快速增长至接近100k,社区关注度极高。
DeepSeek Harness最核心的设计理念是「一切皆插件」,无论是大模型、工具、技能模块、会话管理、沙箱环境、文件系统还是Agent循环,甚至是Web界面,都可以通过插件灵活替换。
这种高度灵活的插件化设计听起来很诱人,但实际运行中会遇到一个关键问题:当一个Agent已经连续运行数小时,持有会话记录、工具执行结果和未完成的任务时,真的可以像浏览器扩展一样随意更换插件吗?卸载旧插件后残留的事件监听器、定时器和后台服务该如何清理?依赖该插件的其他组件又该按照什么顺序安全停止?
其实DeepSeek Harness的官方首页就暗藏了这个问题的答案,其核心依赖的是Cordis框架以及配套的技术论文。这篇长达88页的论文《A Programming Paradigm for Spatiotemporal Composability》由北京大学和DeepSeek-AI的团队联合撰写,正是这套框架的理论基础。仔细阅读这篇论文后,我们才能真正理解DeepSeek Harness「一切皆插件」理念的核心:插件不仅要能够顺利安装加载,更要能够被完全、干净地卸载。
什么是Agent Harness?
大模型本身更像是一个强大的大脑,它能够理解问题、编写代码、做出决策,但它无法自行访问项目目录、调用终端、操作浏览器,也不会自带会话记忆和权限管理能力。将这些外围能力连接到模型外部,让Agent可以持续完成任务的整套系统,就是Harness。
类似Claude Code、Codex以及刚开源的DeepSeek Harness,都在打造这样的系统。一次完整的Agent任务运行流程大致如下:系统将历史对话记录和可用工具清单提交给大模型;模型决定需要调用的工具;Harness执行对应的工具调用并将结果写入会话日志;模型查看结果后再决定下一步行动。这个循环可能会重复数十次,甚至跨越多个上下文窗口。
DeepSeek Harness的特别之处在于,就连这个循环本身都没有被固定死。今天可以使用DeepSeek模型搭配本地Shell工具,明天就能更换其他模型适配器、远程沙箱环境或者全新的Agent循环逻辑。通过不同的插件组合,同一套框架可以衍生出Web版、命令行版以及面向特定任务的专属Agent。
不过这种高自由度的设计也带来了更多运行时的挑战,而DeepSeek Harness的核心奥秘,就藏在Cordis这套内核框架中。
插件化的核心难题:卸载后的残局
我们可以举一个简单的例子:假设存在一个会话日志插件,启动时会订阅工具执行结果,并每隔一秒将缓冲区内容写入磁盘。
当插件代码停止运行时,并不代表它创建的所有资源都会自动消失。事件监听器可能仍然挂在事件总线上,定时器也可能继续触发执行。如果重新加载一次插件,新的监听器会再次注册,导致后续每次工具调用都会被重复记录多次。
在普通的Web开发中,这类问题顶多只会导致页面行为异常,但在Agent场景中,残留的可能是旧的权限配置、失效的模型连接、后台僵尸进程,或者已经无法正常工作的工具实现。Agent运行的时间越长,这种混乱的现场就越难清理。
最直接的解决办法当然是重启整个进程,VS Code的扩展系统就是采用这种方式:根据论文中的统计,在安装量前100的VS Code扩展中,有87个包含可执行代码,移除这类扩展时必须重启Extension Host进程。
不过重启编辑器还可以接受,但如果Agent正在执行一项长任务时重启,内存中的连接、缓存和中间状态都会丢失。为了更换一个插件就彻底重启整个系统,代价未免太大。Cordis框架正是为了解决这个问题而生的。
Cordis的第一招:可撤销的副作用
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`,它记录了组件当前的状态(等待、加载、运行、卸载)、依赖的服务以及留下的所有清理动作。当依赖出现时,组件会自动启动;当依赖消失时,组件会按照顺序安全停止;如果新版本加载失败,已经完成的一半修改也会被全部回滚。
这套机制还有一个非常实用的特性:当一次配置更新涉及多个插件时,系统不会出现只替换了一部分插件的情况。要么所有插件都成功更新到新的组合,要么回退到之前可以正常工作的状态。
并非专为Harness而生的成熟方案
其实Cordis框架在DeepSeek Harness出现之前就已经存在,最早的大规模应用场景是聊天机器人框架Koishi。
聊天机器人和Agent有很多相似之处:进程需要长期运行,插件数量众多,配置经常变化。今天可能需要接入QQ聊天渠道,明天又要添加Discord支持;有的用户需要安装命令插件,有的用户则希望更换数据库和权限管理模块。根据论文记录,Koishi的社区生态在四年时间里积累了超过4000个社区开发的插件。
如何安装、卸载插件,如何管理插件之间的依赖关系,Cordis已经在Koishi的实际运行中处理过无数次这样的场景。当前Koishi使用的是Cordis v3版本,而论文整理的是v4版本,两者并不完全兼容,但这段长期的工程实践证明,Cordis面对的并不是纸面上的理论问题,而是真实的工程挑战。
DeepSeek团队也并非只是在`package.json`中添加一行依赖即可。Harness仓库直接内置了Cordis的源码,并锁定在4.0.1版本,当前的`vendor`目录中列出了18组本地修改。这些修改大多针对长期运行的场景:允许生命周期重入,加固销毁过程,将多份配置更新作为原子事务处理,要么全部成功,要么全部回滚。DeepSeek真正关注的,是当Agent多次更换模型、工具和配置后,系统仍然能够保持稳定运行,不会出现混乱。
面向自我进化Agent的设计愿景
论文开篇就将打造「自我进化的Agent Harness」列为主要动机之一。想象这样的场景:Agent发现自己缺少某种能力,于是编写了一个新的工具插件,并希望将其安装到正在运行的系统中;如果效果不佳,还想要快速更换为新版本。如果每次更新都需要重启系统,当前正在执行的任务就会被反复打断。更麻烦的是,如果Agent编写的插件存在问题,可能会破坏宿主系统,甚至连负责恢复的进程都无法运行。
Cordis希望提供的底层能力是:新组件可以顺利接入,有问题的组件也可以安全退出;依赖关系变化时,相关模块会收到通知,而已发生的会话事件会保留在追加式日志中。Agent可以像更换零件一样更新组件,而不需要清空正在进行的任务。DeepSeek Harness的Creator模式和全插件结构,已经为这种自我进化的Agent设计预留了空间。
Cordis的边界与局限
Cordis能够清理的,只是通过Context登记过的资源。插件写入外部磁盘的文件、已经发送出去的网络请求、调用API产生的费用,并不会因为执行一次`dispose`函数就自动恢复。这些操作需要通过幂等设计、补偿操作或者单独的事务机制来处理。
另外,`inject`机制只是管理组件可以获取哪些服务,并不是安全沙箱。来路不明的插件仍然需要通过进程隔离、运行时隔离或者容器隔离来保障系统安全。Koishi的4000多个插件提供了长期的工程经验,但论文并没有给出受控实验来量化Cordis相比其他方案减少了多少故障,或者节省了多少开发时间。
结语
回过头来看DeepSeek Harness,大模型的选择其实只是表面的一层。大模型决定了Agent能够思考的上限;而Cordis负责的是,当Agent连续运行数小时、多次更换组件后,是否会将工具、连接和旧状态散落一地。
Agent能够跑起来,依靠的是大模型的能力;但能够稳定长期运行下去,关键还是看外部这套系统能否妥善清理运行现场。这也正是为什么Cordis会被称为DeepSeek Harness的灵魂。
相关参考资料
- 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依赖修改说明:https://github.com/deepseek-ai/deepseek-harness/blob/master/vendor/README.md
- Cordis论文与源码:https://github.com/cordiverse/paper
- Cordis项目仓库:https://github.com/cordiverse/cordis

