插件生命周期(可逆注册)

插件贡献的服务、工具与监听器在卸载时必须完全撤销,是热加载与干净卸载的前提。

生产方式:人写签发:晓黎学习复核:2026年9月21日被 1 个词条引用

一句话定义

插件生命周期 = 插件从挂载到卸载的全过程管理,核心要求是「每个注册都有对应的撤销(disposer)」。

为什么必须可逆

不可逆的注册会带来三类问题:

问题表现
热加载重复重新加载后工具出现两遍
资源泄漏卸载后监听器仍在响应事件
测试污染测试之间互相影响,无法独立运行

实现方式

Cordis 提供两种自动管理的写法:

// 方式一:返回 disposer
ctx.effect(() => {
  const disposable = ctx.tools.register(tool)
  return () => disposable.dispose()
})

// 方式二:使用辅助方法自动管理
ctx.on('tools/pre-execute', handler)

官方规则:

每个注册都应有对应的 disposer:要么从 ctx.effect() 返回一个,要么使用 Cordis 提供的辅助方法自动处理。如果 teardown 顺序有要求,请将相关工作放在同一个 effect 中。

teardown 顺序

顺序有时序要求。一个实际例子:

// 正确:先关监听器,再杀进程
async function dispose(proc) {
  proc.listeners.close()      // 1. 防止后续事件产生噪音
  proc.notifications.close()
  proc.kill()                 // 2. 发送终止信号
  await proc.done             // 3. 等待真正退出
  await proc.cleanup()        // 4. 清理资源
}

反模式:先 kill 再关监听器,导致进程退出事件触发时监听器已被移除或仍在处理,产生未处理的异常。

需要管理的资源

资源撤销方式
服务注册从上下文移除
工具注册从注册表移除
事件监听取消订阅
定时器clearTimeout / clearInterval
子进程kill + await exit
文件句柄close

在 Agent Harness 中的位置

DeepSeek Harness 的整个架构建立在可逆注册之上:

机制作用
ctx.effect()包裹可逆副作用
ctx.on()自动管理事件监听
Profile / Bundle / Patch通过配置控制加载哪些插件

这也是「一切皆插件」能成立的前提:如果插件不能干净卸载,就无法安全地替换。

相关

互链

链接来自概念卡正文里的双链,编译时能解到本期词条集的才成为站内链接。

反链(1)

出处

路径是本地知识库(Obsidian 库)里的位置,正文与概念卡逐字对应。

  • 概念卡原文插件生命周期(可逆注册)03_RESOURCES/概念/插件生命周期.md
  • 所属知识地图栏目概念页索引 · Agent 架构与 Harness 治理03_RESOURCES/概念/Index.md
  • 正文引用的知识库笔记第 8 讲 Skill 与插件体系02_AREAS/AI开发/Harness Engineering/Agent Harness 课程/08-Skill与插件体系:能力如何注册发现与治理.md

编译入库:2026年10月6日。词条由知识库编译而来, 修正要回到概念卡改,再重新编译。