一切皆插件与动态组合
为什么静态组合不足以支撑自我进化?
- 传统组合: 函数调用、模块导入和类继承都在编译期确定,运行期不再变化,属于静态组合;
- 插件系统的需求: 组件要在运行中被装入、卸下和重新配置,属于动态组合;
- 联系: Agent 的每一次自我修改,本质上都是一次动态组合;
- 来源: DeepSeek Harness(
dsh)的底座 Cordis 论文给出的区分;
时间可组合性与空间可组合性分别问什么?
| 维度 | 问的问题 | 关心什么 |
|---|---|---|
| 时间可组合性(temporal composability) | 一个组件被移除时,它对共享环境做过的修改能否被完整、安全地撤销 | 改了什么 |
| 空间可组合性(spatial composability) | 组件之间能否以结构化、可验证的方式声明、发现和解析彼此的依赖,并在依赖变化时协调生命周期 | 依赖什么 |
- 时间维度的要求: 运行时必须追踪它的每一次资源分配、事件注册和状态变更;
缺少可组合性会导致什么后果?
- 缺时间可组合性: 每次自我修改都要整体重启,丢掉进程内积累的全部状态,进行中的任务被反复打断;
- 缺空间可组合性: 每个模块只能用临时手段自己察觉依赖的出现、消失和改变;
- 空间失配的代价: 一次简单的代码替换可能静默地破坏依赖方,或者引入循环依赖;
- 场景难度: 要撤销的副作用是长期存活、带状态的;要解析的依赖会在运行中出现、消失或改变身份;
Cordis 用什么机制把编译期概念提升到运行时?
- 可撤销效果: 效果系统原本用于推理“计算如何修改环境”,被提升为每次对上下文的变换都携带一个显式逆操作,由运行时追踪,组件移除时上下文随之恢复;
- 反应式协效果: 协效果(coeffect)系统原本用于推理“计算对环境有什么要求”,被提升为组件把依赖声明成一份规格,上下文每次变化都按规格通知它激活、失活还是无关;
- 传递性: 论文用一套动态组合演算把该性质从单个组件推广到相互交错的组件系统——可组合性必须是可传递的;
自我进化的上限由什么决定?
- 结论: 自我进化的上限不取决于模型能写出多好的代码,而取决于承载它的系统具有多强的可组合性;
- 设计对应: 这也是
dsh让模型适配器、工具注册表、会话日志乃至 Agent 主循环本身都成为插件的原因; - 推论: 不存在一个只能由人类维护的特权内核;
可组合性解决了什么,没解决什么?
- 解决了: 能不能安全地装卸组件;
- 没解决: 该不该装;
- 现实约束: 模型写出的插件只活在进程内存里,重启即消失,不能被自动提升为正式插件;
- 留存路径: 要留下来必须另走 worktree 加 Pull Request 那条更慢的路(见将经验写成程序与自我修改的发布流程);
进化本身的代价是什么?
- 上下文变化: 运行中的插件会改变模型可见的工具集和提示片段;
- 缓存失效: 请求前缀一变,KV Cache 就从变化处开始失效;
- 记录要求: 插件的说明文档中需要专门描述对上下文和 KV Cache 的影响;