808 字
2 分钟
跨群感知插件 v2.1:新增合并转发聊天记录感知
为什么要做这个
群里有一种很常见的行为:有人把其他群的聊天记录以合并转发的形式截过来,然后大家围绕这段记录展开讨论。
v2.0 的插件对这种消息是完全盲目的——合并转发在消息组件里是一个 Forward 类型,get_message_str() 读不到任何内容,只会看到一条空消息被跳过。讨论的内容倒是能记录,但完全缺少「大家在聊什么」的上下文,摘要会莫名其妙。
怎么实现的
消息解析
AstrBot 的消息组件里有三个和合并转发相关的类型:
Forward:只携带一个id,是 QQ 合并转发的引用,需要调接口才能拿到内容Nodes/Node:直接包含转发节点(少数场景)
检测到 Forward 组件后,调用 OneBot 的 get_forward_msg API,把完整的转发内容拉回来,解析成 发送者:内容 格式的对话文本。
核心设计:暂存 + 抖动合并
最直觉的做法是:收到合并转发 → 立刻生成摘要 → 存入群聊上下文。但这样有个问题:摘要会缺少群友的反应和讨论,语义是不完整的。
更合理的处理方式:
- 收到合并转发时,把解析出的内容暂存(
_forward_pending),同时触发群聊 debounce 计时器重置 - 群友看完聊天记录,开始讨论——这些消息正常流入
group_log - 群里静默下来,debounce 到期触发 flush
- flush 时检查
_forward_pending:如果有未超时的暂存,把「聊天记录内容」作为前缀,拼上「群友的讨论」,一起生成摘要
生成的摘要上下文格式是:
【xxx 分享的聊天记录】A:blablaB:blabla...
【群友随后的讨论】群友1:这也太...群友2:确实这样 LLM 摘要出来的内容是完整的,能真正反映「这个群在聊什么」。
超时丢弃
如果有人发了聊天记录,但群里之后各聊各的,跟聊天记录内容无关——这种情况让暂存超时(默认 5 分钟)自然清理,不会产生垃圾摘要。
不记个人记忆
早期版本还给发合并转发的用户生成了一条个人记忆(「分享了聊天记录」)。后来想想意义不大——这条信息含量太低,还会占用用户的记忆配额。去掉了,合并转发只走群聊摘要这条路。
一个小细节
flush 里顺手做了全局 _forward_pending 的过期扫描,防止某个群的暂存因为一直没有后续消息触发 flush 而永久留在内存里泄漏。
新增配置项
| 配置项 | 说明 | 默认值 |
|---|---|---|
forward_pending_ttl | 合并转发暂存等待讨论的最长时间(秒) | 300 |
代码变动
新增约 80 行,改动集中在:
capture_message:检测Forward/Nodes组件,走暂存逻辑_on_group_buffer_flush:flush 时合并转发上下文与群聊讨论- 新增
_extract_nodes_text:本地递归提取 Nodes 组件文本 - 新增
_fetch_forward_content:调用 OneBot API 拉取转发内容
更新已推送至 GitHub:astrbot_plugin_cross_session_awareness
跨群感知插件 v2.1:新增合并转发聊天记录感知
https://xn--jpra6118a.xn--6qq986b3xl/posts/cross-session-awareness-v2-1/ 部分信息可能已经过时