Agent 插件系统如何设计,OpenClaw 的插件 API 提供哪些扩展契约?
未标记
考查重点:扩展点、注册与兼容。围绕渠道、工具和 Hook 的注册说明插件接口、生命周期及错误隔离,解释宿主如何校验和加载第三方扩展
本题目录
参考答案
OpenClawTypeScript
核心回答
Agent 插件系统需要把能力声明、加载策略、运行时注册和资源生命周期分开:宿主定义渠道、工具和事件的接口,插件提供实现,再由配置选择启用哪些提供者。注册表保存能力及所属插件,宿主统一负责调用、诊断和卸载,避免每增加一种能力就修改主循环。
OpenClaw 使用 openclaw.plugin.json 声明身份、配置结构和能力,再向插件的同步 register(api) 入口注入 OpenClawPluginApi。插件通过 registerTool、registerChannel、api.on(...) 和 registerService 等契约贡献行为;宿主将它们登记为可调用的运行时能力。
设计时还应明确接口版本、同名冲突、调用上下文、失败处理和资源释放。清单合法与注册成功只代表接入满足契约,不意味着第三方代码已获得进程隔离或业务操作授权。
清单、配置与加载怎样配合
该版先发现插件根目录并读取清单与包元数据,检查路径安全,再依据 plugins.enabled、allow、deny、entries、槽位和激活条件决定加载范围。清单中的 configSchema 用于校验该插件的配置,静态能力声明允许宿主在不导入运行时代码时完成发现和归属判断。
选中的运行时模块才进入加载与注册。例如工具须出现在 contracts.tools 中,registerTool 会核对运行时工具名称与声明;导出身份与清单身份不一致也会产生加载错误。这样能区分“目录里存在一个包”“配置允许它参与”和“其运行时能力已注册”三个状态。
register(api) 必须同步完成注册,该版会拒绝返回 Promise 的注册函数。需要连接外部系统或执行长期后台任务时,应先登记服务,把异步工作交给服务的启动阶段;不能在注册结束后继续补注册。
主要扩展契约是什么
- 工具:
api.registerTool(...)接受工具对象或按上下文创建工具的工厂,定义名称、描述、参数和执行结果。工具进入模型可见集合后,实际调用仍受宿主工具策略和执行层约束;参数结构也不能替代业务字段与权限校验。 - 渠道:
api.registerChannel(...)提交渠道插件,配置适配器负责账号解析,按能力提供认证、收发、状态、线程或消息转换等适配器。渠道的运行和投递通过统一接口接入 Gateway,而不把平台细节散布到 Agent 主循环里。 - 事件 Hook:
api.on("before_tool_call", ...)、api.on("agent_end", ...)等注册有类型的执行阶段回调,参数与返回值由具体事件契约决定。api.registerHook(...)则属于内部事件 Hook 路径,两者不能按名称互换;将before_tool_call注册到后一条路径并不会获得同样的调用。 - 后台服务与清理:
api.registerService(...)提供id、start与可选stop,由宿主安排服务运行和停止。受宿主管理的插件实例还可通过api.lifecycle接入取消信号、销毁回调与registerRuntimeLifecycle,把插件持有的后台工作和状态纳入清理。
插件还可以扩展模型提供者、HTTP 路由、CLI 命令等,但每个扩展点都要使用对应的身份、输入输出与所有权契约,而不是拿到一个宿主内部对象后任意修改共享状态。
在多渠道故障工单平台的场景化接入中,可将查询与进度记录做成两个插件工具:前者接收工单号,后者再接收进度文本;渠道、账号与线程由宿主上下文传入,返回工单号、办理状态与回执,供来源会话答复。写入超时应先保留“待确认”状态并查询工单结果,再决定是否重试,避免把网络超时当作未写入。工单接口及这项处置属于业务适配设计,不是 OpenClaw 已内置工单系统或业务幂等。
怎样处理兼容、失败和卸载
兼容性需要固定宿主与 SDK 版本,核对包声明及实际使用的 API,并验证发现、注册、调用、停用这条完整路径。该版 OpenClawPluginApi 仍标为实验性接口,不能仅因为 TypeScript 类型检查通过,就认为后续宿主升级一定兼容。
加载或注册抛错时,宿主记录插件归属与失败阶段,并回收已登记的宿主侧贡献;插件停用时,也要停止连接、定时任务和事件订阅,避免旧实例继续处理请求。对状态变更类 Hook 和纯观测 Hook,应分别定义失败后停止还是继续,不能把所有异常统一吞掉。
原生插件在宿主进程中运行。清单校验、配置允许名单和注册回收有助于管理能力,但不能撤销插件代码任意产生的文件或网络副作用。若设计要求运行不可信代码,需要额外的进程、容器或远程服务边界,不能把内存注册表当成安全沙箱。
对应教程
- 深度研搜第 7 章:中间件机制与 Skills 配置:回看执行阶段拦截和技能配置的职责;本文进一步说明插件的代码注册、加载与生命周期,技能说明本身不等于插件运行时。
参考资料
- 国内:WeThinkIn:自进化 Agent 与多平台运行时高频考点:参考插件扩展点、配置、依赖与生命周期的划分,组织正文的四类契约;具体 API 仍按
OpenClaw实现核对。 - 国内:JavaGuide / Kingshion:Java SPI 机制详解:借鉴宿主定义接口、外部提供实现的解耦方式,解释插件为何不必直接修改主流程。
- 国内:Doocs:Dubbo 的 SPI 机制:参考接口实现按配置选择的机制,说明能力存在与宿主实际选用之间的区别;不将其 Java 加载方式套用于
OpenClaw。 - 国内:Datawhale:第七章 构建你的 Agent 框架:采用第 7.5.1 节工具抽象、参数描述与注册表的分工,解释工具声明和执行实现如何统一接入宿主。
- 国外:OpenClaw:Building plugins:依据清单、能力声明及运行时注册示例,说明插件接入需要哪些材料和契约。
- 国外:OpenClaw:Plugin load pipeline and registry:参考元数据先行、启用策略和按范围加载的过程,说明配置检查与运行时导入为何分开。
- 国外:OpenClaw:固定版本插件 API:正文中的扩展方法与生命周期接口以此为依据;工具与 Hook 注册核对声明匹配及两种 Hook 的区别,注册入口核对同步注册要求。