背景与问题定义
《A Programming Paradigm for Spatiotemporal Composability》由 Yifan Shi、Wei Zhang(北京大学)与 Tianyi Cui(DeepSeek-AI,即 Koishi 框架作者 Shigma)合著,是一篇编程语言理论与运行时系统论文,而非模型训练或模型能力论文。
Agent = Model + Harness
【论文原文结论 §1.2.2】论文把 Agent Runtime 作为 motivating example 之一:现代 AI agent 依赖 runtime agent harnesses,这些系统组合工具套件、执行环境、权限沙箱、会话状态、上下文记忆、子 agent 工作流和 UI;"未来的 harness 可能生成并部署对自己组件的修改,同时持续服务请求"。
这一定义与 DeepSeek 官方对 Harness 的描述完全吻合:Agent = Model + Harness。Model 负责推理和决策;Harness 通过插件提供 Tools / Skills / Sessions / Sandboxes / Storage / Loops / Sub-agent scheduling / UI。DeepSeek Harness 把所有这些能力域都做成 Cordis 插件。
为什么长期运行、可自我修改的 Agent 需要动态加载、卸载和替换组件?因为自演化 Agent 的核心特征是"在运行中修改自己"——升级某个工具、替换某个 Skill、调整某个子 Agent 的环境。如果每次修改都要重启整个 session,会丢失上下文与中间状态;如果不重启,旧组件的副作用(打开的连接、注册的回调、持有的状态)就成了悬空的垃圾,污染后续运行。传统机制没有给出"如何干净地换掉一个正在被使用的组件"的答案。
传统插件系统、DI 和 HMR 为什么不够
论文 §1.2.1 以 VSCode 为典型例子:
- Temporal limitation:VSCode 的 extension host 不提供运行时卸载单个扩展代码的机制,禁用或卸载一个扩展需要重启整个 host。前 100 名扩展中 87 个含可执行代码,都需要重启。
deactivate钩子只在进程关闭时作为优雅退出回调使用,且把 effect disposal 与 effect creation(在activate中)分离,违反 locality of concern。 - Spatial limitation:
extensionDependencies几乎无人使用(前 100 名中只有 7 个声明),扩展之间没有结构性契约,getExtension(...).exports返回值是any类型。
【基于原文的推断】传统 DI(如 Spring、Angular)只在初始化时注入依赖,运行时提供者被替换或移除时现有依赖者既不会被停用也不会被重新初始化;React 的 useEffect 把 effect 和 cleanup 配对,但 hook 不能在条件/循环/嵌套函数里调用,effect body 不接受 async 函数或迭代器,无法组合出复合 inverse;HMR(webpack、Vite)通过 import.meta.hot 把状态向前迁移,依赖开发者手写迁移函数;事务内存(STM)和 RAII 把 reversal 限定在固定静态作用域内;OSGi Declarative Services 反应服务可用性,但 deactivation 回调是手写且同步的。
【论文原文结论 §1.2.3】操作系统在进程粒度提供 temporal composability,容器编排器在服务粒度提供 spatial composability,但这是粗粒度替代物:每次重启丢弃所有进程本地状态(缓存、连接、部分计算),重建需要数秒到数分钟;容器级编排无法表达共享地址空间的组件间依赖。论文要的是与组件本身同粒度的组合抽象。
两个正交维度
【论文原文结论 §1.1】论文识别动态组合的两个正交维度:
- Temporal composability(时间维度):组件被移除时,它对共享环境所做的修改必须被完全且安全地撤销。这要求跟踪组件执行过的每一次资源分配、事件注册和状态变更,并保证其有序回收。
- Spatial composability(空间维度):组件必须能结构化、可验证地声明、发现和解析彼此之间的依赖。这要求管理依赖拓扑并在依赖变化时协调组件生命周期。
【论文原文结论 §2.3】Effect 描述"计算如何修改环境",Coeffect 描述"计算如何依赖环境"——两者方向互补,不要混淆。在静态设定下,temporal 归约为词法作用域(RAII、bracket pattern),spatial 归约为模块导入解析;在动态设定下,两者都显著更难。
论文的解法:把经典 effect/coeffect 从编译期静态分析提升为运行时机制——Revertible Effects(每个上下文变换携带一个 inverse,运行时跟踪)解决 temporal;Reactive Coeffects(组件声明 coeffect 规格,上下文变化时按规格通知)解决 spatial。两者统一在单一 context 类型中,构成 component 概念,给出动态组合演算并证明元理论性质。
核心概念映射表
| 概念 | 含义 | 出处 |
|---|---|---|
| Revertible Effect | 每个上下文变换携带一个 inverse,运行时跟踪 | §3.1, Def 8 |
| Reactive Coeffect | 组件声明 coeffect 规格,上下文变化时按规格通知 | §3.2.2, Def 26 |
| Unified Context Γ∞ | 递归携带 (状态, 累加器, coeffect 表) 的单一 context 类型 | §3.3.1, Def 32 |
| Component ℭΓ | 三元组 (依赖规格 d, 提供 p, 见证 effect 函数 e) | §4.1, Def 43 |
| Fiber | 组件一次实例化,携带生命周期状态 | §4.1, Def 44 |
| Committed View ω | 当前已提交的依赖解析(fiber 名映射) | §4.1, Def 44 |
| Target View | 期望 fiber 应处于的依赖解析状态 | §4.2, Def 46 |
| Isolation Realm | 同一 key 在不同 context 解析为不同实例 | §3.2.3, Def 28 |
| Interception | 不替换依赖,只修改其使用方式 | §3.2.3, Def 30 |
后续章节按这条主线展开:Effects 讲 temporal 怎么撤销,Coeffects 讲 spatial 怎么响应,生命周期 讲两者如何在组件实例上协同,定理 讲这套机制保证了什么,DeepSeek Harness 讲它如何落到一个真实 Agent Runtime 上,局限 讲它没保证什么。