深入DeepSeek Harness系列(四):Cordis工作原理解析
从码农到工匠 · 软件开发
原创 从码农到工匠 2026-09-05 11:33 浙江 前面几篇我们介绍了一切皆插件的 相关理论知识 ,理论还要联系实际,接下来,我们看看理论背后的实现是如何做的。 我们先从 Cordis 是一个元框架 (Meta-Framework) 开始。 Cordis是一个用于构建框架的框架。它的核心价值在于为解决软件“动态组合”问题提供了一套通用的、形式化的解决方案。你可以把它理解为一个极其灵活的“乐高底板”,让系统的各个部件能安全地即插即用。 其设计哲学建立在同名论文《A Programming Paradigm for Spatiotemporal Composability》提出的理论基础之上。它将复杂的动态组合问题拆解为两个正交的维度: 时间可组合性 (Temporal Composability) :确保当一个组件被卸载时,它对系统产生的所有副作用(如注册事件、修改状态等)都能被 完整、安全地撤销 。这解决了传统系统中组件难以“干净”卸载,导致内存泄漏和状态污染的问题。 空间可组合性 (Spatial Composability) :让组件能够声明自己依赖什么服务,而无需关心这些服务具体由谁提供、何时出现。框架会响应式地管理这些依赖关系,在依赖变化时自动调整组件状态。 为了实现上述理念,Cordis 通过以下机制将理论落地: 可逆副作用 (Revertible Effects) :所有对系统的修改操作(如 ctx.on() 注册事件)都必须返回一个撤销函数 ( disposer )。Cordis 内部维护一个副作用栈,当插件被卸载时,会自动逆序调用所有撤销函数,实现副作用的完整回滚。 响应式余效应 (Reactive Coeffects) :插件通过 inject 关键字声明其服务依赖。Cordis 运行时负责监控上下文变化,自动解析并注入这些依赖。当依赖的服务提供方发生变化时,依赖它的插件会被自动停用和重新激活。 上下文 (Context) 作为核心容器 :在 Cordis 中, Context 是一切的核心。它是一个服务容器,所有服务(如 ctx.tools 、 ctx.llm )都注册在上面。插件通过 apply(ctx) 函数获得其独立的上下文,并通过这个上下文与外界交互。 类型化事件 (Typed Events) 用于通信 :服务之间通过类型安全的事件进行通信,支持 emit (观察)、 waterfall (瀑布式包装)、 parallel (并行)等多种分发模式。 在上一篇中,我们已经介绍了时空可组合性论文的主要内容,这里我们会通过一个示例,介绍 Cordis 是如何践行论文的理论知识,并实现动态的插件生命周期管理的。 1. 一个完整的 Cordis 示例 这个例子将展示如何创建和消费一个服务,并理解 Cordis 如何管理插件的生命周期。这个示例参考了DSH官方plugin教程文档 1.1 提供服务 (Provider) 首先,我们创建一个提供“问候”服务的插件 greeter.ts : // greeter.ts import { Service , type Context } from '@deepseek-ai/cordis' // 1. 通过模块扩展,为 Context 添加类型提示 declare module '@deepseek-ai/cordis' { interface Context { greeter : GreeterService } } // 2. 定义服务类,继承自 Service export class GreeterService extends Service { constructor ( ctx : Context ) { super (ctx, 'greeter' ) // 'greeter' 是这个服务的唯一标识符 } greet ( who : string ) { return `Hello, ${who} !` } } // 3. 插件的入口函数 export const name = 'greeter' export function apply ( ctx : Context ) { // 将 GreeterService 作为一个子插件挂载到当前上下文 // 这样,'greeter' 服务就被注册到了 ctx 上 ctx. plugin ( GreeterService ) } 1.2 消费服务 (Consumer) 接着,我们创建另一个插件来使用这个服务。在 consumer.ts 文件中: // consumer.ts import type { Context } from '@deepseek-ai/cordis' export cons