Files
deepseek-harness/website/zh-CN/design/effects-coeffects.md
2026-07-19 22:52:03 +08:00

70 lines
3.1 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.
# 作用与余作用
## 作用 (Effects)
Effects 是程序中对系统状态或外部环境产生影响的操作:I/O、状态修改、资源占用等。
学术界对作用有两种主要建模方式:
### 单子作用 (Monadic Effects)
- 通过单子 (monad) 将副作用封装为类型安全的计算链。
- 提供 `return`(纯值注入)和 `bind`(链式组合)两个基本操作。
- 以纯函数式的方式处理带有副作用的计算。(Moggi 1991, Wadler 1992)
- 代表语言:Haskell (IO Monad)、Rust (Result/Option)
### 代数作用 (Algebraic Effects)
- 允许在函数中"抛出"一个 effect,在调用栈的更高层次"捕获"并处理。
- 类似异常处理,但更通用——处理后可以恢复执行。
- 代表语言:Koka、Eff、OCaml 5+ (Kiselyov 2018, Kawahara 2020)
## 余作用 (Coeffects)
Coeffects 是程序执行时依赖的上下文信息:环境变量、系统资源、外部服务等。
- Coeffects 是 effects 的对偶 (dual) 概念,通常通过余单子 (comonad) 建模。(Petricek 2013, 2014; Brünnler 2014)
- 更前沿的理论将带有资源的上下文建模为 **graded algebra**(有序半环加最大元):
- 加法 = 并行组合;0 元 = 无资源
- 乘法 = 串行组合;1 元 = 单位资源
- 序 = 资源约束;最大元 = 无限资源
- (Breuvart 2015, Gaboardi 2016, Dal Lago 2022)
## 现有理论的不足
这些理论主要面向**静态分析**和**短时程序**:
1. **缺乏运行时追踪**:类型系统能标记副作用的存在,但无法在运行时追踪和回收。对长时运行程序(服务端、Agent),这意味着资源泄漏不可避免。
2. **缺乏动态性**:面向编译期分析,无法处理运行时的加载/卸载需求。
3. **崩溃而非降级**:类型不满足时直接拒绝编译或运行时崩溃,而长时运行程序更希望安全降级——挂起不满足依赖的部分,而非停止整个系统。
## Cordis 的突破
Cordis 选择了不同的路径——在运行时层面解决可组合性问题:
| 现有理论 | Cordis 方案 |
|----------|-------------|
| 类型标记副作用 | 运行时追踪并自动回收副作用 |
| 编译期拒绝 | 运行时挂起/恢复 |
| 面向短时程序 | 面向长时运行程序设计 |
这由两个互补机制实现:
- **[可逆作用](revertible-effects)** — 将副作用形式化为可逆的群操作
- **[响应式余作用](reactive-coeffects)** — 将依赖建模为具有生命周期的服务
## 在 Agent 开发中的意义
对 DeepSeek Harness 而言,作用/余作用模型直接支撑了以下能力:
| 作用 (Effect) | 余作用 (Coeffect) |
|---------------|-------------------|
| 注册一个 tool | 依赖 tool registry 服务 |
| 注册一个 LLM adapter | 依赖 LLM 服务接口 |
| 监听 session 事件 | 依赖 session 服务存在 |
| 启动子进程 | 依赖 bash executor 实现 |
每一个 effect 都可逆(tool 可注销、adapter 可移除);每一个 coeffect 都有生命周期(服务消失则依赖者挂起)。这就是 Agent 能被安全热替换的根本原因。