Files
deepseek-harness/website/zh-CN/design/composability.md
lintianle 6ce9f16030 website: wire the site into the repo gates; make every tutorial example compile
- website joins the pnpm workspace; root scripts website:dev/website:build;
  run-gates gains a website-build gate (ci-primary + ci-static) — the
  VitePress build doubles as the site's dead-link check; AGENTS.md documents
  the commands.
- doc-typecheck + verify-type-equiv now scan website/zh-CN/**/*.md; every
  ```typescript fence converted to ```ts and made standalone-compilable
  (55 compiled, 1 ignore-check). Phantom APIs the compiler caught are fixed:
  invented event names (agent/turn-end, tool/call, llm/pre-request, ready,
  dispose) replaced with real catalog events or per-plugin declare-module
  merges; presentCall/inject/Config claims corrected to the real shapes.
- guide/config.md entry-fields table completed against loader EntryOptions;
  its coding-agent example brought in line with examples/coding-agent.
2026-07-16 18:12:22 +08:00

78 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 可组合性与插件系统
## 组合
编程的本质就是组合。将小的构建块拼装为更大的系统,再将大系统作为块继续拼装——这是从函数到模块到微服务一脉相承的思想。
组合可以分为两种:
- **静态组合**:编译期确定的组合,例如函数调用、模块导入。
- **动态组合**:运行时确定的组合,例如热更新、插件加载/卸载。
静态组合是逻辑的组合;动态组合为可组合性引入了时间和空间两个新维度。
## 三种可组合性
| 维度 | 定义 | 对应问题 |
|------|------|----------|
| **逻辑可组合性** (Logical) | 功能能否被任意拆分和组装 | 接口设计是否正交 |
| **时间可组合性** (Temporal) | 能否灵活、安全地控制组合的运行时序 | 能否热加载/卸载而不泄漏 |
| **空间可组合性** (Spatial) | 能否灵活、安全地管理组合的依赖关系 | 依赖缺失时行为是否确定 |
一门编程语言或应用框架越多地使用组合范式,就称它的可组合性越好。
## 传统插件系统的问题
插件系统是动态组合的典型形式。浏览器扩展、IDE 插件、操作系统驱动,都是其实例。然而大多数插件系统并不可靠。
### 不可逆的插件化
以 VSCode 为例:
- 卸载或更新插件时需要重启整个系统。
- 无法在运行时追踪和回收副作用,导致内存泄漏和非预期的资源占用。
- 即便提供了 `deactivate` 钩子,也无法强制开发者正确实现清理逻辑。
**根本原因**:未做到时间可组合——系统不知道某个插件产生了哪些副作用、占用了哪些资源。
### 不完全的插件化
- 无法表达插件间的依赖关系,扩展能力受限。
- 只有外围功能被下放给插件,核心功能依然通过修改主体代码来实现。
**根本原因**:未做到空间可组合——系统缺乏对依赖关系的建模和管理。
## Cordis 的解法
Cordis 同时解决了上述两个问题:
1. **可逆作用** (Revertible Effects) 实现时间可组合性——所有注册自动追踪、自动回收。
2. **响应式余作用** (Reactive Coeffects) 实现空间可组合性——依赖声明驱动加载顺序。
两者通过**上下文模型** (Context Model) 统一为单一的编程范式:开发者只需通过 `ctx` 调用框架 API可逆性和依赖管理由框架保证。
## 在 Harness 中的体现
DeepSeek Harness 将 Cordis 的可组合性应用到 Agent 开发领域:
```ts
import type { Context } from 'cordis'
import { defineTool } from '@deepseek-ai/dsh-tools'
import type {} from '@deepseek-ai/dsh-llm'
// 一个 Harness 插件天然是可逆的
export const inject = ['tools', 'llm'] // 空间可组合:声明依赖
export function apply(ctx: Context) {
// 时间可组合:注册会被自动追踪和回收
ctx.tools.register(defineTool({
name: 'my-tool',
description: '...',
parameters: { /* ... */ },
async execute(args) { return [] },
}))
}
```
插件卸载时tool 自动注销、事件监听自动移除——无需手动清理。依赖的服务(如 `llm`)消失时,插件自动挂起;恢复时自动重新加载。