免费POC, 零成本试错
AI知识库

AI知识库

学习大模型的前沿技术与行业落地应用


收藏

DeepSeek Harness 背后的 Cordis:一套“时空可组合”的插件框架

发布日期:2026-08-14 17:34:19 浏览次数: 2226
作者:Coggle数据科学

微信搜一搜,关注“Coggle数据科学”

推荐语

DeepSeek Harness“一切皆插件”架构突破传统,Cordis元框架支撑“时空可组合”,详解插件系统设计。
核心内容:
1. DeepSeek Harness的“一切皆插件”架构及组件扩展方式;
2. Cordis元框架的“时空可组合”特性与定位;
3. 传统插件系统的核心问题及Cordis的解决方案。

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

DeepSeek Harness,简称 dsh,是 DeepSeek AI 开源的一套 Agent Harness。

和很多 Coding Agent 或 Agent Runtime 一样,它需要负责模型调用、工具注册、Session、上下文、Agent Loop、权限控制以及不同执行能力之间的协调。

但 dsh 在底层架构上做了一个很有意思的选择:它没有把这些能力全部写死在一个固定的 Runtime 内核里,而是尽可能采用“一切皆插件”的方式组织整个系统。

https://deepseek-harness.github.io/deepseek-harness/reference/

也就是说,在 dsh 中,Tool、LLM、Session、Agent、Prompt、Provider 以及很多运行时行为都可以通过插件参与系统,而不是只能修改 Harness 核心代码才能扩展。真正支撑这种设计的,并不是 dsh 自己重新实现的一套简单 Plugin Manager,而是它底层 vendor 引入的 Cordis。

Cordis 介绍

Cordis 官方把自己称为一个 Meta-Framework of Spatiotemporal Composability,直译就是“时空可组合性的元框架”。

dsh 想做的不只是“允许开发者安装插件”,而是希望整个 Agent Harness 在运行过程中都可以持续增加、移除、替换和重新组合不同组件。插件可能提供新的 Tool,可能替换 LLM Provider,可能改变 Prompt,也可能插入一个新的 Permission Policy;未来甚至可能出现 Agent 自己生成新的 Tool、修改自己的 Harness Component 并重新加载的情况。

这样一来,普通插件系统只解决“怎么把一个组件装进来”就远远不够了,还必须进一步解决两个非常现实的问题:一个组件被移除以后,它之前对系统造成的所有影响能不能被完整撤销;一个组件依赖的其他组件发生变化以后,它能不能自动调整自己的生命周期。 Cordis 论文把前者称为 Temporal Composability,把后者称为 Spatial Composability。

长期运行的 Agent Harness

传统插件系统的思路并不复杂。Host 启动以后依次加载 Plugin A、Plugin B、Plugin C,插件在 activate() 中注册命令、监听事件、创建连接或者增加某些能力,需要卸载时再调用 dispose() 或 deactivate()。

插件启动时注册了五个 Listener,那么卸载时就必须准确注销这五个 Listener;启动了一个 Timer,就要记得清理 Timer;向 Tool Registry 注册了一个 Tool,就要知道以后怎么把这个 Tool 移除;如果同时注册了 Prompt、Provider、Hook 和缓存资源,那么这些东西也都需要一一恢复。

问题并不是开发者不知道应该清理,而是随着系统越来越复杂,这种“靠插件作者自己记住所有副作用”的模式非常容易失效。 一个长期运行的 Agent Harness 比普通插件宿主更加容易暴露这个问题,因为 Agent Runtime 本身就是一个持续变化的环境。

系统运行时间越长,就越容易残留旧 Listener、旧 Tool、旧 Prompt 或旧 Provider。最简单的解决办法当然是重启整个进程,但这对于 Agent Harness 并不理想,因为一次完整重启意味着 Session、本地状态、缓存、Connection 甚至正在执行的任务都可能受到影响。Cordis 正是把这种问题视为动态组合系统的核心限制:现代系统中的组件需要在 Runtime 中不断加入、离开和重新配置,而依赖整体重启的粗粒度恢复方式会丢弃进程内部已经积累的状态。

Cordis 因此没有把“卸载”单纯设计成一个额外生命周期回调,而是从更底层改变了插件产生副作用的方式。它要求系统能够知道一个插件到底对当前 Context 做过什么,并且这些修改都应该带有对应的恢复操作。这样,插件的卸载就不再依赖作者之后重新回忆“我当初注册了哪些东西”,而是在副作用发生时就同步记录“这个操作以后应该怎样撤销”。

插件做的每件事都应该能够撤回来

Cordis 把一个组件对运行环境产生的修改称为 Effect。比如一个插件向 Tool Registry 增加一个 Tool,这是 Effect;向 Prompt 系统增加一段 System Prompt,这是 Effect;注册一个 Listener,也是 Effect;提供一个新的 Service,本质上仍然是在修改当前运行时环境。传统系统通常只记录“做了什么”,Cordis 更进一步要求每一个重要 Effect 都携带与它对应的 inverse,也就是撤销这个 Effect 的方式。

这就是 Cordis 中非常重要的 Revertible Effect。论文的核心思想是,每一次对 Context 的转换都不只是得到一个新的 Context 状态,同时还要让 Runtime 获得一个能够把这个变化撤销的函数。Runtime 会持续追踪这些 inverse,当组件被移除时,再按照正确的顺序把这些 Effect 逐步恢复,从而让环境尽可能回到该组件加载之前的状态。论文把这种能力称为 Temporal Composability,也就是一个组件可以在“时间维度”上被安全加入和撤销,而不要求整个应用跟着一起重启。

例如一个 dsh 插件可能在启动时注册一个工具、增加一段 Prompt,并监听 Tool Execution 事件。在传统架构中,这三个行为通常由三个不同子系统管理,插件卸载时开发者还需要分别调用 unregisterTool()、removePrompt() 和 off()。Cordis 更希望这些修改都遵循同一种 Effect 生命周期,因此逻辑可以抽象成:

Plugin Activate
      ↓
register Tool
      ↓
record undo Tool
      ↓
register Prompt
      ↓
record undo Prompt
      ↓
register Listener
      ↓
record undo Listener

当 Plugin 被卸载时,Runtime 再按照相反方向恢复:

Plugin Dispose
      ↓
remove Listener
      ↓
remove Prompt
      ↓
remove Tool

插件不仅要知道自己做了什么,还要知道自己依赖什么

仅仅解决 Effect 还不够,因为 Agent Harness 中另一个非常常见的问题是依赖关系。假设一个 Agent Loop 插件依赖 ctx.llm、ctx.tools 和 ctx.sessions,传统实现很容易写成某个固定启动顺序:

start sessions
↓
start llm
↓
start tools
↓
start agent loop

这种方式在启动阶段似乎没有问题,但一旦系统进入运行时,麻烦就开始了。如果 ctx.llm 对应的 Provider 被动态卸载,Agent Loop 是继续拿着旧对象运行,还是暂停?如果过一会儿新的 LLM Provider 加载进来,Agent Loop 需不需要重新初始化?如果某个插件依赖 ctx.tools,但 Tool Service 还没有启动,那么插件是在加载时直接报错,还是应该等待依赖出现?

Cordis 的答案是:组件不应该自己不断判断“我依赖的东西现在有没有”,而应该直接声明自己依赖什么。这个声明就是 inject。例如从概念上看,一个插件可以声明自己需要:

inject = ["llm", "tools", "sessions"]

Cordis 根据当前 Context 中这些 Service 是否已经可用,决定这个 Component 当前是不是应该进入 Active 状态。当三个依赖都存在时,插件可以运行;如果其中一个依赖消失,那么 Cordis 可以触发组件停用;等依赖重新出现以后,组件又可以重新激活。于是启动顺序不再需要由一个巨大的 Bootstrap 文件手工编排,而是通过依赖本身自然推导出来。

Context 是 Cordis 中真正的中心

理解 Effect 和 Coeffect 以后,就会发现 Cordis 中大量 API 为什么都围绕 ctx 展开。dsh 中常见的能力会占据稳定的 Context Key,例如:

ctx.tools
ctx.llm
ctx.sessions
ctx.agents

插件之间不是直接 import 某一个具体实现,而是通过 Context 获得对应 Service。这样,依赖者只知道自己需要 ctx.llm,却不需要知道当前背后究竟是 DeepSeek Provider、OpenAI Provider、Mock Provider 还是其他实现。Provider 可以替换,Consumer 基本不需要跟着修改。

但 Cordis 的 Context 又远远不只是一个 Dependency Injection Container。普通 DI Container 的核心职责通常是:

key
↓
resolve
↓
object

Cordis 的 Context 同时承担了更多运行时信息。它需要知道谁提供了 Service,谁声明依赖这个 Service,谁向 Context 注册了 Listener,某个 Effect 属于哪个 Component,一个 Provider 消失以后哪些 Component 会受到影响,以及一个 Component 被移除时哪些修改必须一起撤销。因此它更像是 Dependency Container、Service Registry、Effect Tracker、Lifecycle Boundary 和 Event Bus 的统一载体。

论文的实现中,Context 甚至通过 Proxy 对属性访问进行调解。一个插件可以像访问普通对象属性一样访问 ctx[key],但这个访问实际上会经过 Cordis 的 Context Resolution。Runtime 会检查当前组件是否声明了这个依赖、对应 Provider 是否已经处于可用状态,然后才真正返回 Service。如果一个组件访问了自己从未声明过的 Service,Context 可以直接拒绝,而不是让所有 Service 默认对所有插件开放。

一个插件被加载以后,真正运行的是它的实例

Cordis 进一步区分了 Component 和 Component 的运行实例。一个插件定义本身更像模板,而当它通过:

ctx.use(component, config)

真正挂载到某个 Context 中以后,Cordis 会创建一个对应的 Fiber。Fiber 保存这个 Component 当前的运行状态、Parent Context、依赖解析结果以及正在进行的异步生命周期转换。论文实现部分把 Component 描述成 component.inject + component.apply 的组合:inject 描述它需要哪些 Coeffect,apply 则描述它真正启动以后会产生哪些 Effect。Cordis 根据依赖是否满足决定什么时候执行 apply,同时在组件退出时恢复 apply 产生的 Effect。

这个设计很适合 Harness,因为真实 Agent 系统并不是所有组件都处于同一个扁平层级。例如一个 Agent Component 可能动态创建自己的 Tool Component,一个 Group Plugin 可能进一步加载一组子插件,不同 Profile 也可能构成不同插件树。因此 Cordis 中的 Fiber 是有 Parent-Child 关系的。当父组件退出时,它创建的子组件也可以沿着生命周期一起撤销,这样 Runtime 能够自然表达“谁拥有谁”。

为什么 dsh 中很多行为适合通过事件扩展

如果所有插件之间都只能通过 Service Method 直接调用,那么虽然 Service 已经解耦了具体实现,但 Agent Loop 仍然很容易重新膨胀成一个中心化的大模块。例如每执行一次 Tool Call,Agent Loop 如果直接知道 Logger、Telemetry、Approval、Permission、UI、Trace 和 Session,那么它可能逐渐变成:

Agent Loop
   ↓
Permission
   ↓
Approval
   ↓
Logger
   ↓
Telemetry
   ↓
Tool
   ↓
Session
   ↓
UI

Cordis 因此提供了 Type-safe Event 机制,让很多横切行为不需要硬编码进核心流程。DeepSeek Harness 的 Cordis Primer 中把事件分成 emit、waterfall、parallel 和 serial 等分发模式,它们不是单纯不同名字的 EventEmitter,而是表达了不同的协作语义。普通 emit 更像广播观察,多个监听者看到事件但不改变主流程;parallel 适合需要等待多个监听器并行完成的场景;serial 适合按顺序执行一组处理逻辑;而 waterfall 最有意思,它更接近 around middleware,每个 Listener 都可以调用 next() 把控制权交给下一层,也可以直接返回结果并短路后面的逻辑。

这特别适合 Agent Harness。Tool Execution 就可以天然形成一条可扩展 Pipeline:

Tool Call
   ↓
Policy
   ↓
Permission
   ↓
Approval
   ↓
Executor

如果这些逻辑全部直接写进 Tool Executor,那么每增加一种 Policy 都需要修改核心代码;如果使用 Waterfall Event,就可以让 Policy、Permission 和 Approval 分别作为独立插件挂到同一条执行链上。插件可以修改 Request,可以观察结果,也可以在自己拥有最终决策权时直接停止后续执行。这种结构使得 dsh 的核心 Runtime 不需要预先知道以后会出现哪些扩展能力。

因此可以把 Cordis 中的 Service 和 Event 简单理解成两种不同的通信方式:

Service
解决“我要调用一种能力”

Event
解决“我想介入一个过程”

例如调用 LLM 更适合:

ctx.llm

而在 Tool 调用之前插入一层安全检查,就更适合 Event 或 Waterfall Middleware。两者配合以后,Agent Harness 中很多传统上会堆积在 Agent Loop 里的横切逻辑都可以被拆成插件。

连“系统由哪些插件组成”也可以变成动态配置

Cordis 再往前做了一层,把 Component 的组合本身也交给 Loader 管理。如果所有插件依旧需要在入口文件中手动:

ctx.use(A)
ctx.use(B)
ctx.use(C)

那么虽然 Plugin 已经动态化,但系统结构本身仍然写死在程序代码中。Cordis 的 Component Loader 因此引入 Declarative Configuration:运行时应该存在什么 Component、使用什么 Config、是否 Disabled、使用什么 Isolation 和 Interception,都可以作为配置描述,Loader 再负责把这个“期望中的系统结构”转换成真正运行的 Fiber Tree。论文把配置描述成持久化的 Entry Tree,每一个 Entry 对应一个 Fiber,Loader 持续让实际运行状态与配置保持一致。

这意味着 Harness 的结构可以进一步变成:

Configuration
      ↓
Loader
      ↓
Component Tree
      ↓
Fiber Tree
      ↓
Running Harness

所以改变 dsh 的某种运行模式时,并不一定要修改 Agent Loop 或 Runtime Core,很多时候只是修改插件组合。对于 Agent Harness 来说,这是一个很有价值的能力,因为不同 Profile 可能只是选择不同的 Model Adapter、Tool Bundle、Prompt、Policy 或 Session Provider,本质上仍然是在重新描述“这次 Harness 应该由哪些 Component 组成”。

Cordis 适合 Hot Reload 和动态 Agent Runtime

当一个系统同时具备可撤销 Effect、动态依赖和明确的 Component Lifecycle 以后,Hot Module Replacement 就不再只是简单重新 import 一份代码。普通 HMR 最难处理的问题通常不是加载新版代码,而是旧代码留下的 Listener、Service、State 和依赖怎么办。如果只替换代码对象却不处理这些副作用,那么新旧版本很容易同时残留在 Runtime 里。

Cordis 的逻辑更接近:

识别旧 Component
↓
撤销旧 Fiber Effect
↓
加载新 Component
↓
重新解析 Coeffect
↓
重新激活受影响 Fiber

论文中的 Loader 甚至设计了事务式 Hot Module Replacement。如果新模块导入失败,例如存在语法错误,Cordis 可以恢复旧 Module Cache 和旧 Fiber,避免系统进入“有些插件已经换成新版,有些还停留在旧版”的半更新状态。

Cordis 在 Koishi 上的案例也说明了这种设计的实际价值。Koishi 可以在运行中停用插件,并撤销这个插件通过 Context 产生的 Effect;开发阶段修改插件代码以后,也可以重新加载插件,同时保留系统其他部分已有的缓存和连接。论文特别强调,因为 Context-mediated Effect 会被 Cordis 自动追踪,插件作者不需要为每一个副作用手工维护一套独立卸载路径。

把这个能力放回 dsh,就能看出它的长期意义。未来的 Agent Harness 很可能不是启动以后保持不变,而是不断更新 Tool、替换 Model、加载新的 Skill、修改 Policy,甚至让 Agent 自己生成新的组件。如果每一次修改 Harness 都必须完整重启 Agent Runtime,那么这种“自演化”能力会受到很大限制。Cordis 论文因此专门把 Self-Evolving Agent Harness 作为动态组合的典型场景:如果缺少 Temporal Composability,每次修改都可能要求整体重启;如果缺少 Spatial Composability,每一个模块又必须自己处理依赖出现、消失和替换的问题。

理解 dsh 的“一切皆插件”

到这里再看 DeepSeek Harness 的 Everything is a Plugin,就会发现它其实比普通插件架构激进很多。普通框架中的插件往往只是给一个固定核心增加额外能力,比如多一个 Tool、多一个 Adapter 或多一个 Hook,而 dsh 更倾向于把 Runtime 本身也拆成可以被替换、组合和重新加载的 Component。这样做的前提就是底层必须存在一套足够可靠的 Component Runtime,否则系统越插件化,生命周期和依赖管理反而会越混乱。

Cordis 恰好提供了这层基础。Context 负责承载 Service 和依赖边界,Revertible Effect 负责追踪组件对环境的修改,Reactive Coeffect 负责描述和响应组件依赖,Fiber 负责实例生命周期,Typed Event 提供可插拔的执行扩展点,Loader 则负责根据配置动态构造整个 Component Tree。这些机制最终组合成 Cordis 所说的 Spatiotemporal Composability:

                    Cordis

                      │
        ┌─────────────┴─────────────┐
        │                           │
Temporal Composability      Spatial Composability
        │                           │
组件做过什么可以撤销         组件依赖变化可以响应
        │                           │
Revertible Effect          Reactive Coeffect
        │                           │
        └─────────────┬─────────────┘
                      │
                   Context
                      │
                    Fiber
                      │
              Component Lifecycle
                      │
                Loader / HMR
                      │
                      ▼
            Dynamically Composable
               Agent Harness

所以 Cordis 最值得关注的地方其实并不是“DeepSeek 又设计了一套插件系统”,而是它试图给动态 Agent Runtime 建立一套统一的生命周期模型。传统插件框架主要回答“怎么把插件装进来”,Cordis 更关心的是“插件装进来以后改了什么、依赖什么、什么时候应该运行、什么时候应该停止、退出以后能不能恢复干净,以及其他组件是否能够正确响应这些变化”。

从这个角度理解,dsh 使用 Cordis 就非常自然了。DeepSeek Harness 想要的不是一个静态 Agent 程序,而是一套可以长期运行、不断重新组合的 Harness。Tool 可以换,Model 可以换,Provider 可以换,Prompt 可以换,Policy 可以换,甚至未来 Agent Loop 本身也可以换,但这些变化不能让整个 Runtime 越运行越混乱。 因此 Cordis 真正提供给 dsh 的,并不是几个方便的 ctx.xxx API,而是一条更加底层的原则。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅