
日常开发中,很多人都遇到过类似的场景:给IDE装了新插件后觉得不好用,卸载时却提示必须重启整个IDE才能生效,其他正在运行的插件也会被打断;搭建可动态扩展的应用时,新增一个功能模块需要重启整个服务,缓存的运行时数据全部丢失;做AI智能体框架时,动态新增工具或子智能体容易出现依赖冲突,甚至直接导致整个服务崩溃。这些问题的核心,都指向软件工程领域长期存在的一个短板:动态组合的正式理论基础不足,现有方案普遍只能依赖重启进程、重新调度容器等粗粒度的机制解决问题,成本高、损耗大。
最近,北京大学与DeepSeek联合发表的研究针对这一问题提出了系统性的解决方案,首次从理论层面定义了动态组合的两个正交维度:时间可组合性(temporal composability)与空间可组合性(spatial composability),并基于经典的效应与协效应(coeffect)概念构建了一套完整的编程范式,实现了组件无需重启即可安全加载、卸载、重新配置,同时自动管理跨组件依赖。

论文标题:A Programming Paradigm for Spatiotemporal Composability
论文链接:https://github.com/cordiverse/paper/blob/main/paper.pdf
研究背景
在软件工程领域,组合是搭建复杂系统的核心原则,传统的组合方式大多是静态的:函数调用、模块导入、类继承等关系都在编译阶段确定,运行过程中不会发生变化。但随着软件形态的演进,越来越多的场景要求系统支持动态组合:插件架构需要支持用户随时安装、卸载扩展;自进化智能体框架需要在运行过程中动态新增、替换工具或子智能体;在线服务需要在不重启的前提下更新功能模块,避免影响用户体验。
但目前动态组合的实践普遍缺乏完善的理论支撑。以大家熟悉的VSCode插件系统为例,统计显示下载量前100的插件中87%包含可执行代码,卸载这类插件必须重启整个扩展宿主进程,会影响所有已经加载的插件;虽然VSCode提供了deactivate钩子,但它仅能在进程终止时作为优雅退出的回调使用,无法支持运行时的实时卸载,且钩子与效应创建分离,开发者很难保证清理逻辑的完整性。在跨组件依赖方面,VSCode的扩展依赖机制使用率极低,前100的插件中仅7个声明了对非内置插件的依赖,且跨插件交互没有结构化的契约约束,依赖方无法依赖经过检查的接口,很容易出现兼容性问题。
现有的粗粒度替代方案同样存在明显缺陷:操作系统以进程为粒度提供时间可组合性,容器编排系统以服务为粒度提供空间可组合性,卸载一个模块只能通过重启进程、重新调度容器实现,会丢失所有进程内的运行时状态,重建状态需要数秒到数分钟的时间,为了保证可用性还需要部署冗余副本,带来额外的资源开销;同时跨进程交互会引入网络开销,很多原本可以通过本地函数调用完成的操作被迫走远程调用链路,性能损耗明显。
核心创新点
这项研究的核心贡献是将传统静态分析中的效应与协效应概念提升到运行时机制,分别解决动态组合的两个核心维度问题。
时间可组合性的核心要求是,当一个组件被卸载时,它对共享环境做出的所有修改都能被完全、安全地撤销。为了实现这一点,研究团队提出了可还原效应(revertible effects)的概念:每一次上下文转换都附带一个明确的逆操作,运行时会自动跟踪这些逆操作,当组件卸载时按顺序执行即可恢复到组件加载前的状态。
关掉或更新一个插件,不用重启整个 Harness,旧东西也不会残留。比如你写了一个本地 Skill/插件:它注册工具、监听事件、开定时任务,甚至接了一个连接。编辑配置把它设为 disabled,或直接保存新代码触发热更新后,Harness 会先卸载旧实例、清掉它注册的资源,再加载新版本。用户不会遇到“插件明明关了,旧命令还在响应”或“改一行代码必须重开会话”的情况。这就是可逆效应。
具体实现上,研究团队构建了效应上下文结构,每个上下文不仅保存当前的状态,还维护一个逆操作的累加器,每次执行效应操作时,对应的逆操作会被追加到累加器中。为了支持选择性撤销单个组件的效应而不影响其他组件,研究还定义了效应独立性的判定条件:当两个效应的所有转换操作都互相可交换时,它们的逆操作执行顺序不会影响最终结果,因此可以独立撤销。
这种设计彻底解决了传统钩子式清理的痛点:效应与对应的逆操作在定义时就绑定在一起,符合局部关注点原则,开发者不需要单独编写整个组件的卸载逻辑,复合效应的逆操作会由运行时自动组合生成;同时运行时会保证逆操作执行的正确性,不会出现遗漏清理的情况。
空间可组合性的核心要求是,组件能够声明自身对其他组件的依赖,系统可以在运行时自动解析、提供、撤销这些依赖,当依赖发生变化时自动通知相关组件。研究团队提出的响应式协效应(reactive coeffects)机制,将组件的依赖声明为规格说明,每次上下文发生变化时,系统会将变化与组件的依赖规格进行比对,分为激活、去激活、中性三类通知,驱动组件的生命周期转换。
假设一个“联网检索 Skill”依赖搜索服务,一个“并行子代理插件”依赖定时器或任务队列。前者缺服务时不是崩溃,而是显示为 PENDING;当你后来启用对应服务,它会自动转为运行。这是响应式协效应:插件声明“我需要什么”,运行时持续根据环境是否满足来激活、暂停或恢复它。
协效应上下文采用类型化的依赖表结构,每个依赖键都关联特定的值类型,保证依赖访问的类型安全。同时系统还支持协效应隔离与协效应拦截两种扩展机制:隔离机制允许同一个逻辑依赖键在不同上下文中绑定到不同的值,适用于多租户、测试环境、组件沙箱等场景;拦截机制允许在依赖访问时附加横切元数据,无需修改依赖值本身即可添加访问控制、监控等行为。
依赖变更的通知机制保证了组件激活的安全性:只有当组件声明的所有依赖都可用时,组件才会被激活,不会出现访问不存在依赖的运行时错误;当某个依赖被撤销时,所有依赖它的组件会先收到去激活通知,在依赖仍然可用的状态下完成自身的卸载流程,之后依赖才会被真正移除,避免卸载过程中访问已失效的依赖。
研究团队进一步将效应上下文与协效应上下文统一为单一的递归上下文类型,构成了完整的时空可组合性编程范式。这种统一上下文支持层级化组合:父上下文可以聚合多个子级的效应,形成树状的控制结构,既保持了模块化,又支持跨层级的统一管理。
这种范式结合了函数式与命令式两种编程风格的优势:一方面所有效应与依赖都通过显式的上下文参数传递,可追溯、可验证,具备函数式编程的安全性;另一方面不需要像纯函数式编程那样在每个调用链上传递状态参数,也不需要手动管理依赖注入,具备命令式编程的易用性。开发者只需要为每个原子操作提供对应的逆操作,组件的卸载逻辑会由运行时自动推导生成;只需要声明组件需要的依赖,运行时会自动解析、重新布线,当依赖发生变化时自动更新。
动态组合演算的理论保障
为了验证这套范式的正确性,研究团队提出了动态组合演算,为组件的生命周期定义了形式化的操作语义,并证明了多个关键的系统性质,为实际实现提供了严格的理论支撑。
组件被定义为依赖声明、提供声明、效应函数的三元组,每个组件实例化为一个纤程,维护自身的生命周期状态。基础的组件生命周期包含未激活与激活两种状态,当组件的依赖全部满足时,组件从非激活转为激活,执行自身的效应函数;当依赖不再满足或者组件被要求卸载时,组件从激活转为非激活,执行逆操作恢复上下文。

考虑到实际运行时的复杂情况,研究团队进一步扩展了生命周期模型,增加了加载中、卸载中两种过渡状态,支持迭代式的组件加载、异步操作、错误处理等实际场景。这套演算的元理论证明了多个核心性质:恢复精确性,即卸载组件时只会撤销该组件的效应,不会影响其他组件的状态;排序正确性,依赖的提供者一定会在消费者之前激活,在消费者全部卸载之后才会卸载;无死锁性,系统永远不会因为依赖等待陷入停滞;汇合性,无论组件的加载、卸载顺序如何,最终的静止状态都和静态一次性加载所有需要的组件的结果完全一致。
这些理论性质保证了基于这套范式开发的系统的行为可预测、可验证,不会出现动态组合场景下常见的死锁、资源泄漏、状态不一致等问题。
落地实现与生产验证
研究团队将上述理论成果落地为名为Cordis[1]的元框架,这是一个与领域无关的通用框架,只提供动态组合的核心语义,不限制具体的应用场景。Cordis的实现分为三层:核心库直接实现了效应跟踪与协效应系统,组件加载器扩展了配置对账与热模块替换能力,上层的应用框架可以基于这两层构建特定领域的功能。

目前这套框架已经在生产环境得到了大规模验证:开源聊天机器人框架Koishi基于Cordis构建,经过四年的发展已经积累了超过4000个社区贡献的插件,覆盖即时通讯适配器、数据库驱动、管理控制台、终端用户功能等各个领域。在Koishi的实践中,用户可以随时从控制台禁用某个插件,其效应会被即时撤销,不需要重启服务;开发过程中热模块替换引擎可以在保存代码时自动重新加载修改的插件,同时保留系统其他部分的缓存状态与长连接;切换存储后端、重连适配器等操作只会重新激活对应的依赖组件,不会影响其他不相关的功能。
Koishi的实践证明了这套范式的表达性与通用性:其核心只提供动态组合的能力,Koishi作为上层框架只需要补充聊天机器人领域的词汇即可支撑完整的生产级系统;同时这套模型可以适配完全不同的运行时,Koishi的网页控制台也是一个独立的Cordis应用,组合浏览器与用户界面的原语,与服务端实现共享同一个组合模型。
应用前景
这套时空可组合性编程范式的应用场景非常广泛。除了现有的插件系统、应用框架之外,最值得关注的方向是自进化智能体框架:未来的智能体可能会在运行过程中持续生成、修改自身的组件,频繁的动态调整如果依赖重启进程,会导致大量的服务不可用时间,甚至在修改出错时无法恢复。基于这套范式,智能体框架可以实现组件的安全动态替换,修改出错时可以自动回滚到之前的状态,不会影响整个系统的运行;同时响应式协效应可以自动管理组件之间的依赖,避免出现依赖冲突或循环依赖。
此外,这套范式还可以和编程语言、操作系统进行协同设计:原生支持上下文范式的编程语言可以进一步简化开发流程,让上下文隐式传递同时保证安全性;操作系统层面如果将系统资源作为协效应提供,基于依赖声明实现细粒度的访问控制与资源回收,可以实现更轻量、更安全的进程隔离与动态扩展能力。
Cordis: https://github.com/cordiverse/cordis
> 本文由 Intern-S2 等 AI 生成,机智流编辑部校对
-- 完 --
机智流推荐阅读:
1.
2.
3.
4.
cc | 大模型技术交流群 hf | HuggingFace 高赞论文分享群 lc|LangChain 技术交流群 code | AI Coding 交流群 具身 | 具身智能交流群 硬件 | AI 硬件交流群 推理 | AI 推理框架交流群 智能体 | Agent 技术交流群