写在前面
玩 QQ 机器人的人都知道,原生框架只管”收消息→回消息”,很多实际需求全靠插件补。最近给 AstrBot 写了几个插件,这篇聊聊每个插件是为了解决什么问题、在什么场景下会用到。
跨会话感知 (cross_session_awareness)
痛点
你有没有遇到过这种情况:
你在 A 群跟机器人聊了半天自己最近在学吉他,然后去 B 群 @它,它完全不记得你说过的任何事。这很”AI”,但不够”像人”。真正的朋友不会因为换个群聊天就失忆。
什么时候需要
- 你的 bot 同时服务多个群
- 你希望 bot 能跨群记住用户说过的话
- 你想让对话更自然,不只是一问一答的工具人
怎么实现的
插件监听所有消息,用 LLM 把每条有意义的发言压缩成一句话摘要存起来。当用户在别的群 @bot 时,自动把他在其他地方说过的话注入到 system prompt 里。
v1.3 加了消息抖动合并——用户连发 5 条消息不再调 5 次 LLM,而是等他停下来 15 秒后把这些消息合并成一条再处理。省钱,也更准。
效果
用户在 A 群发了张猫的图片
过了一会在 B 群问 bot “今天天气怎么样”
bot 回复天气后自然地说”对了你那只猫好可爱,是什么品种?“
内容审核 (content_guardian)
痛点
群管不可能 24 小时盯着聊天记录。但凡是个活跃群,总有人发敏感内容。纯人工审核不现实,纯关键词又太傻——“天安门真漂亮”会被误杀。
什么时候需要
- 群人数多、管理员不够用
- 对内容合规有要求
- 想要自动处罚而不是每次手动踢人
怎么实现的
双引擎审核:
- 关键词快筛:22 个预置敏感词直接命中,零 LLM 消耗,毫秒级响应
- LLM 智能判断:关键词没命中的交给 AI 判断语境——“天安门真漂亮”就不会被误杀
处罚是递进式的:第一次警告、第二次禁言、第三次踢出。给人改过的机会,但不惯着。
有个省钱的设计:LLM 审核判断和生成警告语合并成一次 API 调用。按次计费的模型,这一刀砍一半开销。
表情管理黑名单 (meme_manager 改造)
痛点
meme_manager 是个好插件,能根据聊天内容自动发表情包。但有时候你不希望它在某些会话里发——比如私聊、工作群、或者某个特定群。原版没有黑名单功能。
什么时候需要
- 你想让表情包只在特定群生效
- 私聊时不希望 bot 自动甩表情
- 某些正式群需要保持严肃
怎么改的
在配置里加了 sid_blacklist 字段,填入会话的 SID(统一消息来源标识),在 resp 和 on_decorating_result 两个钩子处加检查。黑名单里的会话直接跳过,不发表情。
改动大概 20 行代码,但解决了一个一直想要的需求。
写插件的一些心得
AstrBot 的事件管线
理解这个很重要:
on_llm_request/on_llm_response:只有 bot 被 @或唤醒时才触发event_message_type(ALL):监听所有消息,包括普通群聊
跨群感知必须用后者,不然大部分消息根本捕获不到。
Provider 的坑
__init__ 时 self.context.get_all_providers() 返回空列表——因为 providers 还没加载完。要拿 provider 列表必须在 on_astrbot_loaded 钩子里做。
另外 Provider 对象没有 .id 属性,得用 p.provider_config.get("id") 获取。
Schema 的坑
插件的 _conf_schema.json 在启动时被缓存到内存中的 AstrBotConfig 对象。如果你运行时改了文件但不更新内存里的 schema,后台 UI 不会刷新。解决办法是同时写文件和更新 StarMetadata.config.schema。
总结
| 插件 | 解决的问题 | 核心技术 |
|---|---|---|
| 跨群感知 | bot 在不同群间像失忆人 | 全量消息监听 + LLM 摘要 + 抖动合并 |
| 内容审核 | 群管忙不过来 | 关键词 + LLM 双引擎 + 递进处罚 |
| 表情黑名单 | 不该发表情的地方乱发 | SID 黑名单过滤 |
写插件最大的感受是:好的设计不是功能多,而是少调一次 API、少浪费一次请求。模型按次计费,能合并就合并,能缓存就缓存。
有问题欢迎评论区交流。
部分信息可能已经过时