Files
deepseek-harness/website/zh-CN/design/composability.md
2026-07-09 16:07:58 +08:00

3.0 KiB
Raw Blame History

可组合性与插件系统

组合

编程的本质就是组合。将小的构建块拼装为更大的系统,再将大系统作为块继续拼装——这是从函数到模块到微服务一脉相承的思想。

组合可以分为两种:

  • 静态组合:编译期确定的组合,例如函数调用、模块导入。
  • 动态组合:运行时确定的组合,例如热更新、插件加载/卸载。

静态组合是逻辑的组合;动态组合为可组合性引入了时间和空间两个新维度。

三种可组合性

维度 定义 对应问题
逻辑可组合性 (Logical) 功能能否被任意拆分和组装 接口设计是否正交
时间可组合性 (Temporal) 能否灵活、安全地控制组合的运行时序 能否热加载/卸载而不泄漏
空间可组合性 (Spatial) 能否灵活、安全地管理组合的依赖关系 依赖缺失时行为是否确定

一门编程语言或应用框架越多地使用组合范式,就称它的可组合性越好。

传统插件系统的问题

插件系统是动态组合的典型形式。浏览器扩展、IDE 插件、操作系统驱动,都是其实例。然而大多数插件系统并不可靠。

不可逆的插件化

以 VSCode 为例:

  • 卸载或更新插件时需要重启整个系统。
  • 无法在运行时追踪和回收副作用,导致内存泄漏和非预期的资源占用。
  • 即便提供了 deactivate 钩子,也无法强制开发者正确实现清理逻辑。

根本原因:未做到时间可组合——系统不知道某个插件产生了哪些副作用、占用了哪些资源。

不完全的插件化

  • 无法表达插件间的依赖关系,扩展能力受限。
  • 只有外围功能被下放给插件,核心功能依然通过修改主体代码来实现。

根本原因:未做到空间可组合——系统缺乏对依赖关系的建模和管理。

Cordis 的解法

Cordis 同时解决了上述两个问题:

  1. 可逆作用 (Revertible Effects) 实现时间可组合性——所有注册自动追踪、自动回收。
  2. 响应式余作用 (Reactive Coeffects) 实现空间可组合性——依赖声明驱动加载顺序。

两者通过上下文模型 (Context Model) 统一为单一的编程范式:开发者只需通过 ctx 调用框架 API可逆性和依赖管理由框架保证。

在 Harness 中的体现

DeepSeek Harness 将 Cordis 的可组合性应用到 Agent 开发领域:

// 一个 Harness 插件天然是可逆的
export const inject = ['tools', 'llm'] // 空间可组合:声明依赖

export function apply(ctx: Context) {
  // 时间可组合:注册会被自动追踪和回收
  ctx.tools.register(defineTool('my-tool', {
    description: '...',
    parameters: { /* ... */ },
    async execute(args) { /* ... */ },
  }))
}

插件卸载时tool 自动注销、事件监听自动移除——无需手动清理。依赖的服务(如 llm)消失时,插件自动挂起;恢复时自动重新加载。