HARNESS / 代理工程下载 EPUB ↓
17 / 32

第十六章:工具、技能、插件与钩子的生命周期

16.1 四种扩展解决不同问题

工具提供可执行动作;技能提供完成任务的方法和材料;插件把能力、配置或行为接入宿主;钩子在明确节点观察或干预。一个插件可以注册工具与钩子,一个技能也可能指导模型使用现有工具,但它们不是同义词。

如果技能文本写着“自动部署”,它并不因此获得部署权限。权限仍应通过真实工具执行路径判断。类似地,某插件能读取配置,也不意味着它可以在任何 Agent 的作用域里改变策略。

16.2 扩展点首先要说明能否否决

通知用于观察,准入用于允许或拒绝,包围执行用于计时、重试或资源管理。三者的异常、等待和返回值应分别定义。DeepSeek 的 emit、serial、waterfall 语义,是研究这种区别的清晰起点。DeepSeek Harness · dispatch.ts L52–66

Pi 的应用 ExtensionRunner 则提示另一项边界:应用扩展事件与底层 Agent 工具钩子不一定具有相同等待语义。不要把“回调支持 async”直接解读为“主流程一定等待它完成”。需要查看实际调用处。Pi · runner.ts L362–376

16.3 注册需要配套撤销

插件卸载时,应撤销注册、停止接受新任务、取消或等待在途任务,最后释放资源。若只删掉工具名称,在途调用可能仍持有过期服务。若先关闭服务,再等待工具退出,工具又可能无法正常清理。

DeepSeek 的工厂所有权代码追踪活跃 Agent 和启动任务,体现生命周期协调的具体成本。任何扩展体系只要允许长任务,都需要回答“谁等谁结束”。DeepSeek Harness · index.ts L102–116

16.4 作用域防止隐式共享

一份工具或事件注册是全局、项目级、会话级还是 Agent 级?两个并行会话能否读到同一配置?子代理继承的是引用还是快照?这些问题决定隔离,而不只是影响目录组织。

可以给每种注册记录 owner、scope 和 dispose。调试时能列出“当前工具来自哪个插件、在哪个作用域可见”,比单纯列出工具名更有解释力。注销时还应保证观察者不会把失效注册重新写回。

16.5 扩展协议也需要测试

测试插件抛错是否阻断通知后面的观察者,测试准入链是否必须委托 next,测试卸载时是否仍有任务使用服务。还要验证扩展不能悄悄改变已接受调用的身份和取消链。

练习:增加一个执行耗时插件。先确定计时覆盖排队、实际执行还是全部宿主流程,再决定挂载位置。若没有说明边界,一项“工具耗时”指标就可能被不同实现解释成不同含义。

非官方学习读物 · 固定源码快照 · 原始代码保留各自许可。GitHub · 源码依据 · 实验代码