系列教程
47 节
AI Agent 教程
按顺序阅读,循序渐进掌握相关 AI 工具与实战方法。
从「AI Agent(智能体) 教程」开始
上一篇的插件只打印一行日志就结束了,但真实插件会注册事件监听、工具、定时器。这篇解决一个关键问题:插件卸载时,这些资源谁来清理?答案是:注册交给 ctx,清理也交给 ctx。
通过 ctx 注册的任何东西,在插件卸载时都会被自动清理——你不需要手动 removeListener 或 clearInterval。原因在于:所有经过 ctx 的注册都被记录在插件的 Fiber 作用域里,卸载时框架按注册顺序的逆序逐个撤销。
| 注册操作 | 卸载时的行为 |
|---|---|
| ctx.on(event, handler) | 事件监听自动移除 |
| ctx.tools.register(tool) | 工具注册自动撤销 |
| ctx.llm.registerAdapter(names, adapter) | LLM 适配器注册自动撤销 |
| ctx.effect(() => cleanup) | 执行返回的 disposer 清理函数 |
有些资源不在上面的自动追踪列表里,比如一个网络连接或定时器,这时用 ctx.effect() 告诉框架怎么清理。它接收一个回调:回调里创建资源,并返回一个清理函数(disposer,描述「如何销毁这次创建的资源」);插件卸载时框架会调用这个 disposer。下面是一个心跳定时器的例子:
// 文件路径:scratch-plugin/src/heartbeat.ts
import type { Context } from '@deepseek-ai/cordis'
export function apply(ctx: Context) {
ctx.effect(() => {
// 创建定时器:每 5 秒打印一次 heartbeat
const timer = setInterval(() => {
console.log('heartbeat')
}, 5000)
// 返回的清理函数在插件卸载时执行
// 等价于:不需要你在卸载逻辑里手动 clearInterval
return () => clearInterval(timer)
})
}
如果卸载时什么都不用做,disposer 可以不写;但只要创建了定时器、连接这类资源,就一定要返回对应的清理函数。
一句话:通过 ctx 注册的资源在卸载时自动清理;框架管不到的手动资源,用 ctx.effect() 提供 disposer 交给框架。