1522 字
8 分钟
- 次浏览
聊天机器人加功能时,我会先写插件清单
读前导览

新功能不该直接塞进 OneBot 代理。我会先写 manifest,把权限、配置和健康检查定下来,再动手写功能代码。

正文
1522 字
阅读
8 分钟
结构
8 节
来源线索
GitLaughs/chatbot-qq
chatbot-qq:plugin-platform chatbot-qq:plugins-image chatbot-qq:test-plugins

聊天机器人项目很容易越写越像一个大脚本。

一开始只是接收消息、判断关键词、发一条回复。后来要加画图、提醒、总结、文件处理、状态查询、管理员命令,每个功能都往主代理里塞一点逻辑。短期看最快,长期看最难维护。

chatbot-qq 后来把可隔离功能拆成插件。我回看这块时,更关心每个插件是否提前说清自己是什么、要什么、会影响哪里。

功能逻辑别占住传输层#

QQ 机器人有一层很现实的传输复杂度:

  • NapCat 登录。
  • OneBot 事件。
  • 群聊和私聊路由。
  • 消息发送。
  • 重连。
  • cc-connect 调度。

这些东西应该留在平台层。

插件只处理功能行为。比如画图插件不该关心 OneBot websocket 怎么连,也不该自己管理 NapCat 生命周期。它只需要判断一条消息是不是触发了画图命令,然后把任务交给宿主提供的命令 API。

这样拆开以后,排查会清楚很多:消息收不到看传输层,触发词解析错看插件,画图任务失败看后端命令。

manifest 先把话说清楚#

每个插件目录里都有 plugin.json,它不只是元数据。

它要声明:

  • 插件 id。
  • 标题和版本。
  • host API 版本。
  • 最低宿主版本。
  • 默认是否启用。
  • 适用场景是群聊、私聊还是两者。
  • 需要哪些权限。
  • 暴露哪些 hook。
  • 默认配置。
  • 配置 schema。

这份清单让宿主在加载插件前就能知道:这个插件能不能加载、应该给它什么能力、配置是否合法、是否需要拒绝未来版本。

没有 manifest 的插件系统,很容易退化成“约定大家都别乱写”。而机器人项目一旦靠约定,后面一定会被越来越多的功能打破。

权限要显式注入#

插件平台里把权限和宿主 API 绑定起来。

例如:

send_message -> ctx.api.sendMessage
exec_command -> ctx.api.runCommand
schedule -> ctx.api.schedule
read_workspace_file -> ctx.api.readWorkspaceFile
write_local_file -> ctx.api.writeLocalFile

这说明插件不是天然拿到所有能力。它在 manifest 里声明自己需要什么,宿主再按权限注入 API。

对聊天机器人来说,这很重要。不同插件的风险不同:提醒插件需要 schedule,画图插件需要运行任务,状态插件可能只需要 health。把所有能力默认暴露出去,会让一个小功能拥有不必要的破坏面。

权限声明不是安全的全部,但它是最基本的自我约束。

配置 schema 要挡在写入前#

插件配置如果只是一个随便写的 JSON,很快会出问题。

比如画图插件有触发词、单群并发数、队列上限。这里每个字段都要写清类型和限制:

  • triggers 是字符串数组。
  • max_concurrent_per_group 是整数,并且有上限。
  • queue_max_per_group 是整数,并且允许为 0。
  • 不允许额外字段。

管理员命令修改配置时,应该先过 schema,再写本地配置文件。否则一个拼错字段、类型错误或超大并发值,可能直接让机器人行为变得不可预测。

配置 schema 的好处很直接:错误配置还没写入状态,就先被拦下来。

health 和 capabilities 让插件可观察#

插件除了能触发,还要能回答两个问题:

我现在健康吗?
我现在提供哪些能力?

画图插件的 capabilities 可以返回当前触发词、队列上限和并发上限。health 则交给宿主的 health API 汇总。

这类信息对管理员很有用。机器人出问题时,不需要去翻每个插件源码,先看插件快照就能知道哪些插件启用、哪些失败、哪些配置异常。

可观察性不是服务端系统才需要,聊天机器人同样需要。

插件测试应该就地写#

插件目录下有自己的 tests/,例如画图插件会测试:

  • /img cat 能解析出 cat
  • 画图cat 这种中文触发词能解析。
  • 普通消息不会误触发。
  • 命中后会调用宿主提供的 runCommand

这些测试很小,但刚好覆盖插件最容易坏的地方。

更重要的是,插件本地测试不需要启动 NapCat,也不需要连真实 QQ。它只构造一个 context,验证插件逻辑和宿主 API 调用即可。

这能避免把所有测试都塞进端到端机器人环境。端到端测试昂贵、慢、还容易受登录状态影响;插件测试应该快、确定、可重复。

circuit breaker 管运行时故障#

插件平台还提到 runtime hook 的 timeout 和连续失败计数。插件反复失败后,circuit 会打开,宿主跳过这个插件,直到 reload 或配置变更。

这对聊天机器人很实际。

一个插件坏了,不该拖死整个机器人。尤其是群聊场景里,机器人要先保持基础在线,再局部降级。画图坏了,提醒和状态查询仍然应该工作;某个插件超时,不该阻塞所有消息处理。

这也是插件系统和大脚本的区别:大脚本里一个功能异常可能把主循环带崩,插件系统至少有机会隔离失败。

新功能先问自己六件事#

以后给聊天机器人加功能,我会先问:

它的 manifest 是什么?
它需要哪些权限?
它的配置 schema 是什么?
它暴露哪些 hook?
它怎么报告 health 和 capabilities?
它的插件本地测试覆盖什么?

这些问题答不清,就先别写业务逻辑。

聊天机器人越接近真实使用,光靠“先能跑”会很快吃亏。功能会越来越多,群聊和私聊上下文也会越来越复杂。插件清单、权限、配置、健康状态和本地测试,是后面继续维护时最省心的底座。

聊天机器人加功能时,我会先写插件清单
https://blog.sunmmyapi.xyz/posts/qqbot-plugin-manifest-before-feature-code/
作者
Sun
发布于
2026-05-29
许可协议
CC BY-NC-SA 4.0

继续读

相关内容