尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

DeepSeek新论文讲了什么:插件和Agent如何不停机更换组件

DeepSeek新论文讲了什么:插件和Agent如何不停机更换组件 DeepSeek新论文讲了什么插件和Agent如何不停机更换组件设想这样一个场景。一个长期运行的 AI Agent 正在处理任务。此时系统发现检索组件效果不好于是生成了一个新版本准备在不中断当前会话的情况下替换旧组件。代码加载成功并不代表替换完成。旧组件注册过事件监听打开过连接写入过共享状态其他组件还依赖它提供的能力。直接覆盖代码可能留下幽灵监听和陈旧引用。重启整个进程虽然干净却会丢掉会话、缓存和正在执行的任务。这正是论文A Programming Paradigm for Spatiotemporal Composability想解决的问题。论文草稿发布于 2026 年 8 月 13 日作者 Yifan Shi、Wei Zhang 和 Tianyi Cui 来自北京大学与 DeepSeek-AI。仓库将其标注为仍在持续修订的预印本具体定义与结论应以最新版本为准。它没有提出新的大模型也不是一篇 Agent Benchmark而是在尝试建立一种新的编程范式让软件组件在运行时加入、退出和重新组合时系统仍然能够完整回滚副作用并自动协调依赖关系。论文把这两个目标称为时间可组合性temporal composability组件退出后它对共享环境造成的修改能够被完整撤销。空间可组合性spatial composability组件可以声明依赖系统能随着依赖的出现、消失和替换自动调整组件生命周期。这两个词看起来抽象背后讨论的却是插件系统、热更新和自进化 Agent 都绕不开的工程问题。动态加载不是动态组合传统软件的组合大多在编译期确定。函数调用、模块导入和类继承一旦构建完成运行期间不会频繁改变。插件系统把组件加载推迟到了运行时但“能加载”只解决了一半问题。真正困难的是卸载。论文以 VS Code 扩展为例。作者统计了安装量最高的 100 个扩展其中 87 个包含可执行代码。这些扩展一旦执行activate停用或卸载时仍然需要重启整个 Extension Host。deactivate更接近进程关闭前的善后回调并不能让某一个扩展在宿主持续运行时被完整移除。依赖管理也存在类似问题。前 100 个扩展中只有 7 个声明了对非内置扩展的依赖。扩展之间可以通过exports交换能力但返回值缺少可靠的结构契约宿主也不会根据依赖变化自动安排它们的启停。因此下面三件事完全不同加载一段新代码 让新代码开始工作 让旧代码像从未出现过一样退出多数热更新方案主要处理前两件事。这篇论文关心第三件事以及旧组件退出时依赖它的组件应该怎么办。重启进程为什么只是粗粒度解法操作系统其实已经提供了某种时间可组合性结束一个进程操作系统会回收它的内存、文件描述符和其他资源。容器编排器也提供了某种空间可组合性服务消失后流量和依赖可以被重新调度。问题在于粒度不匹配。如果只有一个插件需要更新重启整个进程会同时丢掉无关组件的缓存、连接和中间计算。为了维持可用性系统还要准备额外副本。把每个插件拆成独立服务则会引入部署、通信和序列化成本本来可以是一次本地函数调用的交互被迫跨越网络。论文的判断是副作用和依赖关系应该在组件所在的粒度上被管理而不是一遇到问题就退回进程或容器边界。时间维度副作用必须带着撤销方法论文先处理组件退出后的清理问题。普通副作用可以理解成一次上下文变换Γ → Γ组件注册一个事件、写入一个服务、创建一项资源都会让运行环境从状态 Γ 变成新状态。论文把它改写成Γ → Γ × (Γ → Γ)一次操作不仅返回修改后的上下文还要返回一个逆操作。运行时不需要事后猜测怎样清理而是在创建副作用时就获得清理方法。用接近 TypeScript 的形式表达大致是这样ctx.effect((){constlistenerregisterListener(handleMessage);return(){unregisterListener(listener);};});重点不是多写一个回调而是所有会改变上下文的操作都经过同一个ctx.effect。运行时收集这些逆操作并以与创建相反的顺序执行。如果组件依次完成创建数据库连接 → 注册消息处理器 → 启动定时任务退出时就应该停止定时任务 → 注销消息处理器 → 关闭数据库连接这和调用栈展开、RAII 或try/finally的直觉相近区别在于组件的生命周期可能持续数小时甚至跨越多轮异步任务。它没有一个固定的词法作用域清理信息必须由运行时长期保存。可逆不等于随时可以乱撤销论文在这里比常见的 dispose 模式多走了一步。假设组件 A 和组件 B 都修改了共享环境初始状态 → A 的修改 → B 的修改如果先卸载 A它的逆操作不能顺手抹掉 B 后来写入的状态。否则每个组件单独看都能回滚放在一起却无法组合。这要求不同组件的效果具有某种独立性。论文没有把独立性简单定义为“修改不同字段”而是引入观察等价只要组件通过自己声明的依赖观察环境时两个执行顺序产生的结果不可区分就可以把它们视为等价。这个设计把副作用和依赖联系了起来。系统只有知道一个组件能观察哪些环境内容才有可能判断其他效果是否真正影响了它。时间可组合性因此不是“每个操作都有 undo”这么简单。它还要求逆操作确实能恢复相应修改。多个逆操作按正确顺序组合。撤销一个组件时不破坏仍然存活的组件。空间维度组件不再主动寻找依赖第二个问题是依赖变化。传统依赖注入通常发生在应用启动阶段。容器找到数据库、日志或缓存实现把它们传给消费者之后默认这些依赖一直存在。动态系统里提供者可能在运行中出现、退出或被另一个实例替换。让每个消费者自己监听这些变化会迅速产生大量临时状态和边界条件。论文借用了coeffect概念。effect 描述“程序对环境做了什么”coeffect 描述“程序需要环境提供什么”。本文将它译作“余效”也可以把它理解成组件的环境需求声明。一个组件不直接寻找数据库实例而是声明inject { database, logger }运行时每次发现上下文变化都会重新检查这组需求并把结果分成三类激活原来缺少依赖现在全部满足组件可以加载。停用原来依赖完整现在某个提供者消失组件必须退出。中性变化上下文发生变化但组件需要的依赖没有改变。这是一种组件级响应式系统。Vue 或 SolidJS 的响应式机制会在一个值改变时重新计算相关表达式Cordis 则在服务依赖改变时重新安排相关组件的生命周期。提供者退出时为什么要先停掉消费者动态依赖最容易出错的时刻是提供者退出。假设报表组件依赖数据库组件。数据库准备卸载时如果先关闭连接再通知报表组件退出报表组件的清理逻辑可能还要使用数据库保存进度此时依赖已经不存在。论文给出的顺序是数据库组件进入 UNLOADING ↓ 它立即停止“提供”数据库能力 ↓ 依赖数据库的组件收到变化并开始退出 ↓ 等待所有消费者完成清理 ↓ 数据库组件执行自己的逆操作也就是说提供者在真正释放资源以前先从依赖图中宣布离场。消费者仍能在自己的清理阶段读取已经提交的旧依赖直到退出完成。之后提供者才关闭资源。这个顺序解决的是动态组件系统中的经典悬空引用问题服务虽然正在退出但不能在消费者完成善后前提前消失。异步加载期间依赖又变了怎么办真实组件很少能同步完成加载。它可能要建立连接、读取配置或等待外部服务。加载进行到一半时依赖可能已经被替换。Cordis 使用一种“惯性”状态机处理这个问题一次加载或卸载开始后当前转换先运行到可安全停下的位置再根据最新目标决定下一步。论文中的生命周期可以简化为INACTIVE ↓ 依赖满足 LOADING ↓ 加载完成且目标未变化 ACTIVE ↓ 依赖失效 UNLOADING ↓ 清理完成 INACTIVE如果LOADING过程中依赖发生变化系统不会让两个生命周期转换并发修改同一个组件。它会停止后续迭代保留已经积累的逆操作完成回滚再按照最新依赖重新加载。这比简单的“取消 Promise”更可靠。Promise 被取消不代表前面已经执行的资源分配自动消失真正需要处理的是部分完成后的回滚。Context为什么是整篇论文的中心论文最终把 effect 的运行环境与 coeffect 的依赖环境合并成同一种 Context。在这个模型里Context 同时承担四项职责职责解决的问题记录效果组件做过哪些可撤销修改累积逆操作组件退出时如何恢复保存能力当前环境提供哪些依赖通知依赖变化哪些组件应该激活或停用这也是论文称其为“编程范式”而不仅是插件框架的原因。组件不再直接面对一个全局可变世界而是在自己的 Context 中读取被声明的能力通过 Context 执行可追踪的修改。Context 还支持两种重要操作**隔离isolation**改变一个依赖键解析到哪个 realm。例如两个插件都请求database但可以被定向到不同数据库实例。**拦截interception**不改变依赖指向谁而是改变怎样调用它。例如为某个社区插件提供只读数据库能力或者为调用增加日志与权限检查。隔离解决“拿到哪个服务”拦截解决“怎样使用服务”。两者都能在运行时调整。Cordis如何把理论变成代码论文实现了 TypeScript 元框架 Cordis。它不提供路由、ORM 或聊天机器人等具体能力只负责动态组合语义。实现分成三层核心库提供效果跟踪、依赖解析和组件生命周期。组件加载器把声明式配置转换成组件实例并进行增量协调。应用框架在上面定义自己的领域能力Koishi 就是其中的生产案例。核心 API 可以压缩成几个动作API作用ctx.effect(callback)执行修改并记录逆操作ctx.set(key, value)向上下文提供一项能力ctx.get(key)读取已声明并解析完成的能力ctx.use(component, config)在当前上下文实例化组件ctx.isolate(key, realm)改变某项依赖的解析空间ctx.intercept(key, metadata)调整依赖的访问方式这里最关键的工程约束是所有上下文修改都必须经过ctx.effect。如果组件绕过 Context直接修改全局变量、原生对象或外部系统运行时就看不到这次效果也无法保证卸载时恢复。论文的理论保证只覆盖系统边界以内、能够被独占修改并恢复的位置。热更新不再依赖组件作者声明接受边界Cordis 的组件加载器还实现了热模块替换。一般 HMR 方案需要开发者标记哪些模块接受热更新。Cordis 的做法不同组件本身已经圈定了效果和依赖因此替换组件可以复用同一套卸载与重新加载机制。论文把更新分成三步根据模块导入关系把变更模块分成可热替换和需要完整重启的集合。找出依赖树经过变更模块的组件实例。备份模块缓存卸载旧组件并导入新组件任何一步失败就恢复缓存并重新实例化旧版本。第三步很重要。热更新不是简单重新执行一次import而是一个事务要么相关组件全部切换到新版本要么恢复旧版本系统不能停在一半新、一半旧的状态。4000个插件证明了什么又没有证明什么论文用 Koishi 作为案例。Koishi 是建立在 Cordis 上的聊天机器人框架经过四年发展已经形成超过 4000 个社区插件的生态。服务端插件会组合消息平台适配器、数据库驱动和业务功能Web 控制台本身又是另一个运行在浏览器里的 Cordis 应用。这个案例至少说明两件事这套抽象足以支撑一个真实、长期运行的插件生态而不只是形式化模型。同一套组合机制可以用于服务端和浏览器说明它不依赖聊天机器人这一特定领域。但论文也主动限制了结论。首先Koishi 当前使用的是 Cordis v3论文描述的是重新细化效果、余效和加载器语义的 v4。两者共享核心模型但不能把生产使用规模直接当成 v4 全部机制已经得到同等验证。其次案例来自单一语言、单一生态属于存在性和采用情况证明而不是与其他架构的对照实验。论文没有给出热更新耗时、运行时开销、故障率或开发效率等量化结果。所以“4000 个插件”证明这种方向能够落地却没有证明它在所有指标上优于容器、进程隔离或其他插件架构。这篇论文和自进化Agent到底有什么关系论文在开头把 self-evolving agent harnesses 作为核心动机之一这也是它受到关注的重要原因。未来的 Agent Harness 可能动态增加工具、修改记忆模块、重写权限策略甚至生成并替换自己的组件。每一次自我修改都可以看成动态组合生成新组件 ↓ 检查它需要哪些能力 ↓ 加载并记录全部效果 ↓ 依赖变化时协调上下游 ↓ 出现错误时完整撤销如果没有时间可组合性Agent 每改一次自身都可能需要重启当前任务和内存状态随之丢失。若没有空间可组合性新组件可能拿不到正确依赖或者在替换服务时悄悄破坏其他模块。Cordis 提供的模型确实适合作为这类系统的基础设施组件声明自己需要什么所有修改带着逆操作运行时负责依赖协调和失败回滚。不过必须强调论文尚未在自进化 Agent 上完成验证。作者在结论中把它列为未来研究方向。当前生产案例是 Koishi 插件生态不是一个持续改写自身 Harness 的 Agent。把这篇论文直接说成“DeepSeek 已经实现可自我进化的 Agent”并不准确。三个仍然没有解决的问题论文最后的讨论部分比结论更值得看因为它清楚交代了理论边界。1. 逆操作的正确性仍由作者负责ctx.effect能确保逆操作被记录、按顺序执行并且最多执行一次却不能证明开发者提供的逆操作真的恢复了原状态。如果创建文件后返回的清理函数删错路径运行时仍会忠实执行这个错误操作。形式化系统依赖一个前提组件作者提供的 inverse 是有效见证。2. 外部世界并不总能回滚发送过的邮件、已经扣除的款项、被第三方消费的消息都不能像内存字段一样简单撤销。论文用“系统边界”限定保证范围。只有系统能独占修改并恢复的位置才属于可逆 Context。边界外的动作需要幂等、补偿事务或外部协议配合不能因为包了一层ctx.effect就自动获得可逆性。3. 不可信代码仍然需要沙箱Context 可以控制组件通过声明依赖访问哪些能力却挡不住恶意组件绕过 API直接接触宿主运行时对象。论文明确指出不可信组件需要语言运行时、独立进程、软件故障隔离、WebAssembly 或容器提供真正的执行边界。依赖注入和访问拦截可以缩小能力但不能替代沙箱。此外依赖键的版本和类型兼容仍是开放问题。不同包可能使用同名 key 表示完全不同的接口提供者升级后消费者也可能继续拿到名字相同但行为不兼容的对象。Cordis 当前借助 peer dependencies 缓解问题还没有一个完全语言无关的统一方案。如何读这篇88页的论文这篇论文形式化内容很多从效果与余效的范畴论背景一直推到保存性、进展性、合流性和时空可组合性定理。工程读者不必从第一页顺序啃完。更高效的阅读路线是第 1 节先理解两个可组合性维度 ↓ 第 3.1、3.2 节理解可逆效果与反应式余效 ↓ 第 5.1 节把公式映射到 ctx.effect / ctx.set / ctx.use ↓ 第 5.2 节看配置协调与事务式 HMR ↓ 第 5.3、6 节核对生产证据和适用边界 ↓ 需要验证理论时再回看第 4 节证明阅读英文原稿时我把 PDF 放进 PDFTranslator 做成双语对照主要用来保持公式、算法编号、表格和章节引用的位置关系。涉及effect、coeffect、inverse、fiber和realm的段落仍保留英文术语核对避免中文译名掩盖它们在形式化定义中的差异。最后这篇论文最重要的贡献不是又造了一个热更新工具而是把动态组件系统中两个长期依靠工程经验处理的问题放进了同一套模型组件做过的事情必须能够按顺序撤销。 组件需要的东西必须能够随环境变化重新解析。可逆效果负责时间反应式余效负责空间统一 Context 把二者连接起来组件生命周期再把局部保证扩展到整个依赖图。对于普通业务系统进程和容器仍然是更简单、更可靠的隔离边界。对于需要大量插件、长期保持进程状态、频繁热替换模块尤其是未来可能持续修改自身的 Agent Harness这套范式提出了一个值得认真研究的方向。它距离“自进化软件基础设施”还有验证和工具链上的空白但至少把问题说清楚了真正困难的从来不是把新代码放进去而是让旧代码干净地离开并让周围组件知道世界已经变了。参考资料Yifan Shi, Wei Zhang, Tianyi Cui,A Programming Paradigm for Spatiotemporal Composability, draft of August 13, 2026。
返回列表