Skip to content

Him666233/astrbot_plugin_group_chat_plus

Repository files navigation

群聊增强插件 (Chat Plus)


Version AstrBot License

一个以 AI读空气 为核心的群聊增强插件,让你的Bot更懂氛围、更自然地参与群聊互动

⚠️ 注意: AstrBot平台自带的说明文档查看器有一定的问题,可能会导致点击跳转按钮之后,没办法跳转到正常的说明文件中,建议直接在项目的github仓库中查看或者是直接下载压缩包,然后解压自行翻看

快速开始功能总览推荐配置更新日志

深度指南与常见问题消息工作流程详解配置项完整参考项目结构说明桌面端兼容说明


🚨 重要声明:防盗版与安全警告

本插件完全免费且开源,不会以任何形式进行商业收费!

近期我们发现有人疑似在其他渠道贩卖本插件。在此郑重声明:

  • 本插件永久免费、开源,不存在任何付费版本,不会进行任何商业性收费行为
  • 唯一官方开源仓库GitHub - Him666233/astrbot_plugin_group_chat_plus
  • 唯一官方获取渠道:上述 GitHub 仓库 及 内部内测交流群(QQ群:1021544792)
  • 从其他渠道获取到的版本可能被篡改并包含恶意代码或病毒,请务必通过官方渠道获取,保障自身安全

如果有人向你收费或在非官方渠道分发本插件,请提高警惕!


⚠️ 使用前必读

关闭AstrBot官方自带的主动回复功能! 本插件的智能回复与官方主动回复是完全独立的两套系统,同时开启会导致重复回复、刷屏、API费用翻倍等问题。如果您有其他主动回复/主动对话类插件也建议关闭,避免冲突。

关闭平台的"只 @ 机器人是否触发等待"(empty_mention_waiting)! 该功能与插件的群聊等待窗口(GWW)存在冲突:平台的空 @ 等待机制会在群级别拦截任意用户的下一条消息,人工插入 @bot 后重新入队,可能导致插件认错消息发送者。本插件的群聊等待窗口已完全覆盖该场景,且按用户粒度隔离等待,不会劫持他人消息。如需空 @ 等待行为,请开启插件的 enable_group_wait_window 并按需配置 group_wait_window_at_mode 等参数。

必须开启平台的"群聊上下文感知"! 这是本插件正常工作的关键前提之一。不开启时,插件拿到的群聊历史与上下文信息会明显不完整,可能导致读空气判断失真、回复上下文错乱、主动对话判断不准,严重时会表现成"像没理解群里刚刚在聊什么"。推荐配置与原因说明见:深度指南 → 平台配置

图片处理须知: 两种模式可选——(1) 配置 image_to_text_provider_id 后图片会被 AI 转写为文字描述再参与上下文,结果自动缓存省钱(推荐);(2) 留空 image_to_text_provider_id 时直接传递原始图片给多模态 AI(需使用支持图片的多模态模型)。模式(2)理论上可行但未经充分测试,如果发现 AI 仍然看不到图片,请改为填写 image_to_text_provider_id。视频、语音、文件等非图片媒体会被插件自动提取并内联到消息文本中(格式如 [视频: /path][语音: /path][文件: name, /path]),AI 可通过工具调用自行解析处理。

注意第三方插件回复修改与平台分段回复功能! 本插件的普通消息回复流程走的是平台方的 on_decorating_resultafter_message_sent 钩子链路,这意味着其他第三方插件可以在 AI 生成回复后、消息发送前对回复内容进行修改(包括但不限于分段发送、文字转语音、内容清理替换再发送等)。此外,AstrBot 平台自带的「分段回复」功能(platform_settings.segmented_reply)也会在此阶段对消息进行拆分处理。

这些修改操作如果发生在 LLM 生成回复之后、本插件保存回复之前,会导致本插件在 after_message_sent 阶段保存 AI 回复到自定义存储和官方存储时,只能保存到拆分后的第一小段内容,后续分段无法被正常保存;严重时甚至会被识别为"空的 AI 回复",导致整条 AI 回复完全没有被保存到历史记录中。本插件虽然已针对此类场景做了多层防御措施(多段回复文本累积、_saved_messages 保存去重守卫等),但在部分极端情况下仍无法完全避免,因此建议按以下方式操作:

对于 AstrBot 平台自带的「分段回复」功能:如果需要开启分段回复,请务必同时保持 「仅对 LLM 结果分段」platform_settings.segmented_reply.only_llm_result,默认 true)处于开启状态。该开关确保分段操作仅在 LLM 直接生成的最终结果上进行,避免对其他中间环节的输出进行不必要的拆分。

对于其他会修改 AI 回复内容的第三方插件(如分段发送插件、TTS 插件、回复内容过滤/替换插件等):请检查该插件是否有类似的「仅对 LLM 结果处理」「仅在 AI 回复之后处理」等含义的开关,如有请务必开启。如果该插件没有此类开关,请自行确认其默认行为是否本身就是仅在 LLM 生成最终回复之后才进行处理——如果该插件会在处理时修改 result.chain 的结构(如拆分 Plain 组件等),则存在与本插件的兼容性风险。

关于提示词注入类第三方插件:此类插件(如人格增强、记忆注入、上下文补充等)通过 on_llm_request 钩子向 LLM 请求中注入提示词或上下文。这些注入仅对走插件普通消息回复流程的最终回复生成 AI 生效——因为只有该 AI 调用会经过平台完整的提示词组装流程(build_main_agent_decorate_llm_request,即平台方会注入提示词钩子的那一条链路)。本插件内部的判断型 AI(读空气 AI、频率调整 AI、主动对话判断 AI)使用的是独立的 LLM 调用,不走平台钩子流程,因此这些第三方提示词注入不会对它们产生任何影响。这是正常现象,无需额外配置。

⚠️ 私聊功能警告

私聊处理功能目前仍在开发中,请勿开启 enable_private_chat 当前版本的私聊模块尚未完善,开启可能导致异常行为。请耐心等待后续版本正式支持。


❤️ 支持作者(自愿捐款)

本插件由个人开发者用爱发电、投入大量精力独立维护,开发与持续更新压力不小。如果你觉得这个插件对你有帮助,欢迎自愿捐款支持作者,让作者有更多动力继续维护和改进。

⚠️ 重要声明:

  • 捐款完全自愿 — 捐不捐功能完全一样,不会有任何功能差异或特殊对待,纯粹是对作者的支持和认可
  • 官方唯一捐款渠道爱发电 (Afdian) — afdian.com/a/chat_plus
  • 内部交流群:QQ群 1021544792(可在群内直接联系作者本人)
  • ⚠️ 防骗警告:除上述爱发电链接和 QQ 群内与作者本人直接联系外,任何其他渠道声称代表本插件接受捐款的皆为骗子,请务必提高警惕,谨防上当受骗

🔐 Web 管理面板安全提醒

强烈建议启用 Web 端功能 — Web 管理面板提供了可视化配置编辑、实时统计、会话管理等完善的插件管理体验,比传统 JSON 配置界面更加直观易用。

⚠️ 从旧版本升级的用户请务必注意:v1.2.2-hotfix.1 版本开始对 Web 面板安全机制进行了全面升级(Argon2id 密码哈希、JWT + HttpOnly Cookie + 服务端会话表等),请尽快登录一次 Web 面板,让旧版密码自动透明升级为更强的 Argon2id 哈希,同时堵住各项安全漏洞,确保您的面板安全。

关于配置文件:为什么能下载但不能上传?

出于安全考虑,Web 面板支持下载配置文件,但不支持直接上传配置文件。原因是配置文件内部包含了 Web 面板的敏感安全配置(如密码哈希、JWT 密钥存储路径、IP 访问控制规则等),如果直接允许上传,在上传校验未完全覆盖所有安全字段的情况下,攻击者可能通过伪造配置文件替换对应的安全配置,从而导致面板被入侵。

如需修改配置,建议通过以下方式操作:

  • 方式一(推荐):直接在 Web 管理面板中可视化修改各项配置并保存
  • 方式二:手动前往配置文件所在目录,直接编辑或替换配置文件

配置文件路径<AstrBot 数据目录>/data/config/astrbot_plugin_group_chat_plus_config.json

AstrBot 插件配置通常存放在 data/config/ 目录下,插件自身的运行数据存放在 data/plugin_data/astrbot_plugin_group_chat_plus/ 目录下。

不确定当前使用的配置文件叫什么名字? 登录 Web 面板后,在「核心控制面板」或「科技树展览」菜单面板的右下角即可看到当前生效的配置文件名称。


📚 文档导航

不知道从哪里看起?根据你的需求选择对应的文档:

你想了解… 去看这个文档
AI 回复太多/太少/读空气不准怎么调? 深度指南 → 常见问题排查
某些 Skill / MCP 工具在开启插件后报参数错配怎么办? 深度指南 → 常见问题排查
Web 管理面板怎么用?打不开怎么办? 深度指南 → Web 管理面板
配置文件怎么下载?下载失败怎么办? 深度指南 → 配置文件下载
插件的工作原理是什么?为什么要"偷天换日"? 深度指南 → 工作原理
平台的"群聊上下文感知"和"自动理解图片"怎么配? 深度指南 → 平台配置
某个配置项是什么意思?默认值是多少? 配置项完整参考
一条消息从收到到回复经历了什么流程? 消息工作流程详解
代码文件结构和各模块职责? 项目结构说明
使用 AstrBot 桌面端?重启不生效?路径找不到? 桌面端兼容说明
我用的其他插件和本插件会冲突吗? 深度指南 → 兼容性
如果 AstrBot 或其他插件改了内部提示词结构,会不会影响兼容? 深度指南 → 兼容性与回退机制
第三方插件往 system_prompt / prompt / contexts 注入内容时,AI 现在能看到哪些? 深度指南 → 兼容性
记忆插件怎么选?为什么推荐适配过的? 深度指南 → 记忆插件

🤝 插件合作

第三方插件兼容性判断

一个其他插件能否与本插件一起使用,取决于它向 AI 注入提示词的方式是否匹配以下任意一条保留路径:

注入方式 说明 保留机制
system_prompt 前面插入内容 插件在人格设定之前添加了自己的提示词(如规则块、管理指令等) SystemPromptRewriter 精确命中人格边界,prefix 原样保留
system_prompt 后面追加内容 插件在人格设定之后追加了提示词(如状态面板、记忆文本等) SystemPromptRewriter 精确命中人格边界,suffix 原样保留
req.contexts 注入对话/工具调用 插件在对话历史数组中添加伪造对话示例、协议消息、伪工具调用等 逐插件追踪提取 → 每个插件独立 [第三方插件注入上下文 - 插件名] 首尾配对标记
req.prompt 前后追加长期说明 插件在当前用户消息前后附加了记忆说明、解释文本等内容 逐插件追踪提取 → 每个插件独立 [第三方插件补充 - 插件名] 首尾配对标记,外层 [第三方插件补充信息] 包裹
extra_user_content_parts 追加内容 插件通过新版 AstrBot API 在用户消息之外附加内容块 逐插件追踪提取文本 → [第三方插件补充 - 插件名] 标记,原始项同时原样保留

判断方法:查看该插件的源码,找到它的 on_llm_request 钩子,看它修改了 req 的哪些字段、是怎么改的(prepend/append/新增)。只要匹配以上任意一条,即可兼容。

兼容机制的详细原理和风险说明见 深度指南 → 与其他插件的兼容性

AstrBot智能自学习插件

astrbot_plugin_self_learning 建立官方合作关系:

  • 本插件 负责"智能决策何时回复" — AI读空气、动态概率、注意力机制
  • 自学习插件 负责"智能优化如何回复" — 对话风格学习、人格自动优化、好感度系统

两者功能互补,推荐组合使用。欢迎加入 QQ群 1021544792 交流!

工具参数串扰排查

如果你发现某些 Skill / MCP 工具在关闭本插件时正常开启本插件后更容易出现参数错配,例如:

  • unexpected keyword argument 'silent'
  • Tool handler parameter mismatch
  • 某个工具收到了明显属于另一个工具的参数

可以优先按这个顺序排查:

  1. 确认 AstrBot 当前会话的 provider_settings.tool_schema_mode
    • skills_like:本插件现在会自动把工具提醒降级为"只展示工具名称与功能描述"
    • full / 旧版 AstrBot:仍会完整展示名称、描述和参数
  2. 临时关闭 enable_tools_reminder 再复测一次
    • 如果问题明显缓解,通常说明是提醒层参数提示过细引发的串扰,而不是工具本身损坏
  3. 对照报错工具的真实签名
    • 例如 astrbot_execute_shell 只接受 command / background / env
    • 如果日志里出现了明显属于其他工具的参数(如 Python 工具常见的 silent),就是典型串扰

更详细的背景说明和排障建议见:


🆕 V1.2.3.hotfix.2 更新亮点

本次更新在 v1.2.3.hotfix.1 的基础上追加了 AI 提示词注入顺序优化(提升缓存命中占比与 AI 理解性)、逐插件上下文追踪升级(全字段覆盖+消除重复显示)、Agent 调用非图片媒体全面扩展、消息元数据化防注入、User/Agent 全链路兜底与标注优化,以及 Web 面板 UX 大幅增强(自动刷新机制完善、心跳状态实时同步、IP 管理全面 IPV6 兼容、按钮布局与图表主题适配、悬浮窗移动端适配、访问日志与封禁管理多项修复)和多项消息处理链路 Bug 修复,同时包含全部说明文档的补充与更新。

AI 提示词注入顺序优化与缓存命中提升

  • 缓存友好的提示词拼接顺序 — 全面调整回复 AI(reply_handler.py)、私聊回复 AI(private_chat_reply_handler.py)、读空气 AI(decision_ai.py)、频率调整 AI(frequency_adjuster.py)等全部 AI 模块的提示词拼接顺序:静态指令(角色设定、行为规则)统一放在前面,动态内容(时间信息、聊天记录、用户消息)放在后面。同一静态前缀在连续 API 调用之间保持不变,大幅提升 Anthropic prompt cache 命中占比,降低首 token 延迟与 API 费用
  • 提示词位置引用同步调整 — 所有 AI 提示词中"上方/上述"等位置引用全部更新为"下方",与新的拼接顺序一致,AI 不会因方向措辞与内容实际位置不一致而产生理解偏差
  • 增强提示词防回声 — 回复 AI 与主动对话生成 AI 的提示词中增加防重复/防回声约束,引导 AI 理解"你的任务是生成新的有价值的回复,而不是重复或改写用户刚说的话",减少 AI 无意义复读用户消息的行为

逐插件上下文追踪全面升级

  • monkey-patch 替换为 handler wrapper — 废弃通过 monkey-patch call_event_hook 拦截第三方插件注入的方式,改为直接包装 OnLLMRequestEvent 各 handler,在执行过程中实时写入每个插件的独立注入数据到 event._gcp_per_plugin_injections。不再依赖 Python from-import 语义,消除了 monkey-patch 方式在特定加载顺序下失效的死代码问题
  • 第三方标记从统一编号升级为具名隔离 — prompt 和 contexts 中的第三方插件注入标记从原有的 [第三方插件注入上下文] / [第三方插件片段 N] 统一编号格式,升级为携带插件名称的首尾配对隔离格式(如 [第三方插件:xxx 注入上下文] ... [/第三方插件:xxx 注入上下文]),AI 可明确区分不同插件的注入来源
  • 全字段追踪覆盖 — 新增 system_promptextra_user_content_partsimage_urlsaudio_urls 四个注入通道的追踪,结合原有的 promptcontexts 追踪,实现第三方插件所有注入通道的完整覆盖,统一走逐插件标记合并管道,消除不同通道注入内容重复显示的问题
  • Web 端与架构文档同步 — Web 面板提示词预览与架构文档中的第三方注入隔离说明同步更新为具名标记格式

Agent 调用兼容性全面扩充

  • 非图片媒体完整支持 — 为群聊增强插件新增视频、语音、文件三类非图片媒体的完整支持:从消息链中提取视频组件(Video)的文件路径、语音组件(Record)的音频路径、文件组件(File)的文件名与路径,分别注入为 [视频: /path][语音][文件: name] 内联标记。覆盖消息提取、标记内联、缓存剥离前富化、保存传递全链路,与既有图片处理逻辑([图片] / [图片内容: xxx])保持一致
  • 纯语音/文件消息防丢弃 — 语音消息和文件消息在内容检查环节视为有效内容,防止纯语音或纯文件的合法消息在入口处被误判为空消息而丢弃

消息系统提示词统一元数据化(杜绝提示词注入伪造)

  • 元数据区与用户内容区严格分离 — 所有系统级提示(时间戳 [2026-05-29 周四 14:30:00]、发送者信息 Name(ID:12345)[戳一戳事件] 持久化文本、平台 LTM 历史标记等)统一注入到冒号 : 之前作为系统元数据区;冒号之后仅保留用户消息原始内容(含 @ 提及内联解析 [At:ID|解析结果])。用户无法通过消息内容伪造时间戳、发送者身份或戳一戳事件文本,从源头杜绝提示词注入攻击面
  • [戳一戳提示] 运行时注入在分隔符之外 — 运行时戳一戳提示(由主流程在上下文拼接阶段追加)不进入冒号前元数据区,而是追加到分隔符之外,与持久化戳一戳事件文本严格区分

戳一戳事件双层标注机制与引用消息格式优化

  • 戳一戳事件双层标注 — 持久化戳一戳事件文本([戳一戳事件])注入到冒号前的系统元数据区,随消息一起保存到历史上下文,不会被后续过滤清理移除;运行时戳一戳提示([戳一戳提示])由主流程在上下文拼接阶段追加到分隔符之外,仅在当前轮次可见。双层标注机制确保:历史记录保留完整的戳一戳事件信息,过滤清理不会误伤必要上下文
  • 引用消息格式修复 — 引用消息在构建时添加 >>> 分隔符与换行,将引用内容与用户新消息正文视觉隔离:[引用: Name(ID:xxx): 原文内容...]\n>>>\n用户消息正文。修复被引用者为 AI 自身时自动标注 (你)(格式:Name(ID:xxx)(你)),多条引用各自独立解析,不再合并为单一引用块
  • 空引用消息保留框架 — 引用消息源内容为空或无法获取时,不再丢弃整个引用标记,而是保留发送者框架并附注"无法获取内容",确保 AI 知晓用户正在回复某条消息(而非凭空说话)
  • 过滤规则与全部文档同步更新 — 内容过滤规则中的相关正则模式同步适配新引用格式,所有说明文档同步更新

用户名称解析全链路兜底

  • 统一兜底策略 — 统一修复所有用户名称解析失败时的兜底行为:当名称解析结果为裸 ID、空字符串或与 ID 完全相同时,替换为 未知用户(保留原始 ID 字段不变)。覆盖戳一戳发送者/目标者展示、@ 提及内联解析、转发消息发送者标注、引用消息被引用者展示、普通消息发送者信息注入、Smart 并发批量消息等全链路场景,确保名称字段永远不泄露原始用户 ID,同时 ID 字段始终存在供日志排查
  • Smart 并发批量消息名称保护 — Smart 并发批量保存消息时,每条消息独立执行名称兜底检查,不因某条消息的名称异常而影响同一批次中其他消息的保存

主动对话重复启动防护

  • 后台循环任务身份识别 — 主动对话后台检查循环(_background_check_loop)现在记录当前 asyncio.Task 身份(_own_task = asyncio.current_task()),循环条件从仅检查 _is_running 升级为同时校验 cls._background_task is _own_task。当插件类被重复加载(如插件重载)导致旧循环仍在运行时,旧 task 身份与新 task 不匹配,旧循环自动退出,彻底杜绝"旧循环未停止+新循环已启动"的双循环并发冲突
  • 普通回复时主动对话状态双重保险关闭record_bot_reply 方法中,当记录普通回复(非主动对话)时,新增主动对话活跃状态检查与自动关闭逻辑:如果检测到 proactive_active=True(如主动对话流程异常退出未清理),普通回复会主动将其置为 False,防止残留的活跃标记干扰后续主动对话的正常触发

多轮工具调用链路修复

  • LLM_RESULT 误判为最终回复修复 — 修复多轮工具调用中 LLM_RESULT 被误判为最终回复导致后续工具调用和 AI 回复全部丢失的问题:on_decorating_result() 钩子不再对 LLM_RESULT 类型强制完成保存(因为多轮调用中 AI 先说话再调工具时,中间文本也是 LLM_RESULT,若强制完成会将第一段中间话误当最终回复)。正常完成流程由 on_llm_response_agent_done_flagsafter_message_sent 处理;异常终止时通过 GENERAL_RESULT 类型检测触发强制保存,确保所有已累积的中间文本和已完成的工具调用记录不丢失
  • 工具调用异常时反馈结果保存修复 — 修复工具循环调用过程中出现报错时,已完成的工具调用记录和 AI 中间回复文本无法正常保存到历史存储的问题:异常终止时,通过 _finalize_bot_reply_save 兜底构建交错排列的工具调用记录(多轮顺序保留),确保异常中断场景下的上下文完整性

概率过滤信息描述纠正

  • "概率过滤失败"纠正为"概率过滤未通过" — 全面调整概率过滤链路中的日志、Web 流程图节点标签、缓存消息注释等信息输出,将"概率过滤失败"改为"概率过滤未通过"。概率过滤未命中不是功能失败,而是概率模型的正常随机结果("未通过"更准确反映"不需要回复"的业务意图),避免用户误以为系统故障

IPV6 全面兼容与边界管控

  • 全安全机制 IPV6 完整支持 — Web 面板的 IP 过滤(白名单/黑名单)、IP 封禁管理、防爬虫检测、速率限制、暴力破解防护等全部安全机制均已完整适配 IPv6 地址。security.py 中 IP 规范化为 RFC 5952 标准形式(IPv6 压缩、IPv4 点分十进制),server.py 中客户端 IP 获取同样走规范化管道,确保 IPv4/IPv6 统一比较和存储
  • IP 管理配置边界警告 — 配置 schema 和 Web 前端中新增 IP 地址输入校验与边界警告:IP 黑白名单和受保护 IP 列表中的非法 IPv4/IPv6 地址配置项在加载时输出明确 WARNING 日志(配置警告:xxx 不是合法的 IPv4/IPv6 地址),IPv6 地址说明文字(支持任意格式,系统自动规范化)同步展示在 Web 面板编辑区和文档中
  • IP 封禁错误页增强 — IP 被封禁后的错误页(/error?code=blocked)增强了解封状态自动轮询检测机制,封禁到期后自动跳转至登录页(已认证用户直达面板),手动封禁可通过 Web 面板「IP 封禁管理」解封
  • Web 面板监听地址双栈说明 — 监听地址 0.0.0.0:: 时自动启用双栈(同时监听 IPv4 + IPv6),启动日志输出本机所有 IPv4 和 IPv6 地址的访问入口
  • localhost 归一化 — Web 面板启动日志中将 localhost 统一归一化为 127.0.0.1,避免部分环境 localhost 解析到 ::1 导致点击链接时浏览器默认行为不一致

Web 面板 UX 全面增强

自动刷新机制重构

  • 会话列表 3 秒自动刷新 — 会话管理页新增 3 秒间隔自动刷新:进入会话详情页自动暂停列表刷新、返回列表自动恢复,编辑模式完全禁用自动刷新,避免编辑过程中列表跳变
  • 聊天记录增量更新 — 聊天记录查看改为内容比对增量更新策略:仅更新变更的消息条目而非整体替换 DOM,保留用户滚动位置不跳动。如增量更新异常(数据不一致)自动回退为全量重建,确保数据完整性
  • 心跳状态自动/手动刷新 — 心跳状态面板支持自动刷新(定时器永不停仅设标志位控制是否渲染更新)和手动刷新按钮(🔄),Leader 心跳成功后广播 session-ok 事件,Follower 标签页接收广播同步 lastHeartbeatSuccessAt,解决 Follower 长期不更新心跳成功时间戳的问题。_loadHeartbeatStatus 增加兜底逻辑:只要 verify 成功且 _authMonitor 尚未记录过心跳成功时间,直接用当前时间初始化,确保首次加载即显示有意义的时间戳
  • 图表页面自动刷新 — 图表页新增 3 秒自动刷新开关 UI(含绿色圆点状态指示器),用户可自由启停
  • 速率窗口修复 — 修复前端自动刷新请求被计入速率限制窗口的问题:后端新增 X-GCP-Auto-Refresh 请求头豁免机制(值为 1 时跳过速率窗口计数),前端所有自动刷新请求统一携带该头;同时心跳请求(/api/auth/heartbeat)无论是否携带该头均不计入速率窗口
  • 无自动刷新页面提示 — 访问日志页刷新按钮旁新增"本页无自动刷新机制"提示文字(适配桌面/平板/手机三端及明暗双主题),api.verify 新增 options 参数支持

页面交互与布局修复

  • 全页面手动刷新 + toast 反馈 — 补充所有页面的手动刷新按钮,点击后显示 toast 反馈("刷新成功"/"刷新失败");编辑模式下手动刷新跳过以避免覆盖未保存内容;手动刷新始终强制全量重载数据
  • 会话列表计数移至右侧 — 会话卡片的群聊/私聊计数标签从左侧移至右侧,视觉层次更清晰
  • 按钮布局位移修复 — 修复 Web 面板中部分按钮因 CSS 布局变更导致的位移/错位问题
  • 插件重启期间自动刷新静默容错 — 插件重启/重载期间自动刷新请求遇到网络错误或 5xx 时静默忽略(不弹 toast),避免重启过程中大量错误提示干扰用户体验

图表与主题适配

  • 柱状图始终重绘适配主题 — 修复柱状图在明暗主题切换时颜色不适配的问题:移除主题色缓存守卫,图表每次更新始终重绘并使用 CSS 变量动态适配当前主题色;统一概率柱状图颜色为红色
  • "图表无会话"手动刷新修复 — 修复当图表页面无会话数据时,手动刷新按钮被守卫逻辑误拦截无效的问题:去除无会话时的刷新守卫,用户可在任意状态下手动刷新

悬浮窗与移动端优化

  • 悬浮窗拖拽超屏与内容截断修复 — 修复悬浮窗拖拽超出手势区外导致无法拖动和内容截断的问题,补全移动端触摸拖动(touchstart / touchmove / touchend)支持
  • 悬浮窗默认宽度防撑大 — 为悬浮窗设置默认宽度(min-width / max-width),防止内容过长时悬浮窗被撑大到超出可视范围
  • 移动端自定义缩放拖拽手柄 — 移动端新增自定义缩放拖拽手柄(prompt-floater-resize-handle),桌面端使用原生 resize 属性,移动端隐藏原生 handle 显示自定义大尺寸手柄

访问日志与封禁管理

  • 访问日志桌面端表格优化 — 附注列改用 auto 列宽并截断溢出内容(text-overflow: ellipsis),移动端卡片布局不受影响
  • 封禁 IP 备注 128 字符限制 — 封禁原因输入框限制 128 字符并显示实时计数,前端限制 + 服务端同步截断双重保障,列表原因文字自动换行不溢出
  • 封禁列表桌面端短列 nowrap — 来源、状态等短列添加 white-space: nowrap 防止换行导致行高参差不齐,原因列保持自动换行

其他 UX 增强

  • Web 面板启动日志三级地址输出 — 启动日志从仅显示 localhost 升级为完整输出本地(localhost + 127.0.0.1)、内网(IPv4 + IPv6,过滤链路本地地址 fe80::)、公网三级访问地址。公网 IP 多来源去重获取(ipify / ifconfig.me / icanhazip),任一获取成功即显示
  • Web UI 前端缩放按钮 — 流程图页面新增缩放控件(+ 放大 / 适应屏幕 / 缩小),仅在流程图页面显示,配置面板打开时自动隐藏,适配桌面和移动端尺寸

AstrBot v4 平台重启认证与 Web 重置行为修正

  • JWT 优先 + 密码降级重启认证 — Web 面板触发的插件重载和 AstrBot 重启操作,认证方式从单一密码登录升级为 JWT 优先:直接通过 dashboard 配置中的 jwt_secret 签发 HS256 token 调用 AstrBot 仪表盘 REST API(/api/plugin/reload/api/stat/restart-core);JWT 签发失败时自动降级为密码登录(兼容旧版 AstrBot v3),确保不同版本平台的平滑兼容
  • Web 端重启状态轮询反馈 — 新增 restart_status 接口(GET /api/restart-status),前端在触发重启/重载后定期轮询该接口获取操作进度(pendingin_progresssuccess/failed),状态栏文案从"正在重启…"静态文本升级为动态进度反馈
  • 会话管理重置行为修正 — Web 面板「会话管理」中每张会话卡片上的「重置」按钮行为修正为:仅清运行时状态(注意力、情绪、概率、冷却、Smart 待合并记录等),不删除聊天记录文件不设历史截止时间戳,重置后自动触发插件重载使清理生效。与聊天指令 gcp_reset_here 的行为明确区分(后者会删文件和设截止戳)。补全 reset_hereclear_image_cachereload 分支中此前缺失的重载触发调用
  • cutoff 日志补全 — 补全 gcp_reset_heregcp_reset 操作中的历史截止时间戳相关日志输出,方便排查跨重置的历史记录问题

戳一戳消息后提示词注入修复

  • 反戳后 ID/名称/时间戳注入不生效修复 — 修复戳一戳消息处理流程中的一个隐蔽 Bug:当收到戳一戳消息并在处理流程中触发直接反戳(poke_reverse_on_poke_probability > 0)后,插件在发送反戳动作后通过 event.stop_event() 或提前 return 终止了后续处理链路,导致用户开启的 include_sender_info(用户 ID 与名称解析)和 include_timestamp(时间戳提示词注入)等元数据注入功能不生效。修复后的流程确保反戳动作完成后的消息保存、元数据注入、上下文缓存更新等步骤不被跳过

gcp_clear_image_cache 旧版缓存兼容清理

  • 旧版残留路径兼容清理gcp_clear_image_cache 指令和 Web 面板图片缓存清理操作现在同时检查并清理旧版残留路径 image_description_cache.json(当前主缓存文件为 image_cache/descriptions.jsonl),确保从旧版本升级的用户不会留下无法清理的孤立缓存文件

其他细节修复

  • proactive_system_prompt 变量名拆分遗漏修复 — 修复主动对话管理中一个内部变量名拆分遗漏的 Bug:mark_proactive_chat_message 和实际发送的消息文本使用了不一致的变量引用路径,特定配置组合下可能导致主动对话提示词拼接异常
  • 过滤清理规则与工具循环修复 — 调整内容过滤清理规则中可能导致正则回溯超时的表达式;修复工具循环调用时因异常导致后续工具记录及 AI 回复无法正常保存的问题(与多轮工具调用链路修复互补)
  • Web 面板按钮布局位移修复 — 修复因 CSS flex 布局变更导致的配置保存按钮与其他控件之间的间距偏差
  • 编辑保存直接覆盖源文件 — Web 面板文件管理中的在线编辑保存逻辑改为直接覆盖源文件(而非新建副本),避免编辑后的文件与原文件路径不一致

📚 文档补充与更新

  • 全部说明文档更新 — 更新了项目中所有说明文档的版本号、功能描述和配置说明,确保与 V1.2.3.hotfix.2 版本的实际功能保持一致
  • 配置项文档补充CONFIG_REFERENCE.md 同步了关闭平台「只 @ 机器人是否触发等待」(empty_mention_waiting)的提醒说明(该平台行为与本插件冲突),补充了 IPV6 相关配置的边界说明
  • 架构文档更新ARCHITECTURE.md 更新了第三方插件注入隔离、逐插件追踪机制、Web 面板安全机制、AstrBot v4 兼容性等章节,同步了 Web 面板访问地址输出说明
  • 消息工作流程文档更新MESSAGE_WORKFLOW.md 补充了消息元数据区机制、戳一戳双层标注、引用消息格式等流程说明
  • 项目结构文档更新PROJECT_STRUCTURE.md 更新了模块列表和版本信息

兼容性

  • 完全向下兼容 v1.2.3.hotfix.1 配置,升级无需修改任何配置项
  • 所有新功能默认使用安全合理的默认值
  • IPV6 兼容性对所有安全机制透明生效,无额外配置开关
  • 第三方插件提示词全面兼容:第三方插件通过 system_prompt 前置/后置、req.contextsreq.promptextra_user_content_partsimage_urlsaudio_urls 任一通道注入的内容均可被 AI 看到,且以具名标记隔离,详见 深度指南 → 兼容性

📖 功能总览

核心机制

  • AI读空气 — 两层过滤:概率筛选 + AI智能判断,精准控制回复时机;在 Smart 并发模式下,读空气判断也会参考当前消息之后紧接着到达的追加消息,而不是只看单条消息
  • 动态概率系统 — 传统模式下回复后临时提升促进连续对话,时段概率模拟作息节奏;注意力模式开启后由注意力机制接管回复后加成
  • 注意力机制 — 多用户同时追踪(0-1连续值),指数衰减,情绪检测,注意力溢出;注意力冷却已升级为"候选冷却 → 正式冷却"的双阶段结构,专门减少普通概率路径消息的误伤;"读空气未回复衰减"改为独立机制,可在无冷却模式下单独生效,也可在冷却模式下与正式冷却协同(仅在开启注意力模式时生效)
  • 智能缓存 — "缓存+转正"机制,未回复消息保留上下文,下次回复时自动合并;支持冷群自动转正,群聊长时间静默后自动将缓存写入历史,避免过期丢失
  • 记忆系统 — 支持 LivingMemory(混合检索+人格隔离)和 Legacy 双模式,auto 模式自动检测适配插件
  • 并发协调 — 群聊支持 legacy / smart 两种并发模式;smart 会按真实到达顺序选主消息并批量感知追加消息,legacy 保持传统串行兜底;普通对话、主动对话、冷群转正之间自动互斥,无需额外配置
  • Smart批次回复提示增强 — 可选开关(enable_smart_batch_reply_hint,默认开启)。开启后,Smart 模式下回复阶段会动态插入一段提示:当前触发 anchor 消息的用户仍是主要回复对象,但 AI 可以像真人一样自然顺带回应批次中来自其他用户的消息;不值得回的消息也可以大方忽略。该提示只存在于运行时上下文,保存历史前会自动过滤(通过 MessageCleaner / ContextManager 清洗),不会污染长期上下文

社交行为

  • 主动对话 — 沉默后AI自然发起话题,自适应互动评分系统,越聊越开心
  • 对话疲劳 — 连续对话后逐渐降低回复倾向,模拟真人节奏
  • 拟人增强 — 沉默状态机、兴趣话题检测、决策历史一致性
  • 吐槽系统 — 连续被无视时AI会"吐槽",让Bot更有性格

真实感增强

  • 打字错误 — 基于拼音相似性的自然错别字 (默认2%概率)
  • 情绪系统 — 根据对话检测情绪状态,影响回复语气
  • 回复延迟 — 模拟打字速度,避免秒回
  • 频率调整 — 自动分析群聊节奏,动态调整基础回复频率;与传统回复后提升解耦,可在提升结束后继续维持基础概率修正

消息处理

  • 多媒体消息 — 支持图片(转文字或直传多模态)、视频、语音、文件等媒体类型的识别与传递;媒体文件路径内联到消息文本中(如 [视频: /path][语音: /path][文件: name, /path]),AI 可通过 Agent 工具调用自行解析;纯占位标记在缓存时剥离,成功解析的文字描述保留
  • 转发解析 — 面向 QQ / OneBot 场景解析合并转发消息,支持在深度限制内展开嵌套转发,并将整条转发内容折叠为单条可读文本继续参与后续 AI 流程
  • 关键词系统 — 触发词跳过概率/智能模式,黑名单词直接过滤
  • 戳一戳 — 智能响应QQ戳一戳,支持反戳和回复后戳。戳一戳事件解析为两层:[戳一戳事件](持久化事件文本,注入到消息格式中「冒号前」的系统元数据区域,随消息一起保存到历史上下文,不会被后续过滤清理)与 [戳一戳提示](运行时提示,追加在上下文分隔符 ===== 之外,仅当前轮 AI 可见,保存时由 MessageCleaner 过滤规则自动移除)。对本插件实际接手处理的真实戳一戳事件,会把"谁戳了谁"的事件语义保留到历史上下文中(官方存储与自定义存储双写),便于后续AI理解。触发反戳时,会先后保存用户戳一戳事件(user视角)和AI反戳动作(assistant视角),均绑定当前会话。启用"戳过对方追踪提示"后,还会在短时间内追踪被AI戳过的用户;若追踪人数超过上限,会移除当前最早登记的记录。此行为无独立配置项,是否生效取决于当前 poke_message_mode、平台是否为 QQ+aiocqhttp/OneBot poke notice,以及该群是否允许本插件处理戳一戳消息
  • @消息优先 — @机器人消息跳过所有判断直接回复;@全体成员@他人过滤 独立处理,可单独配置为按普通消息处理、跳过概率筛选、跳过概率+读空气,或仅对当前这条消息临时提升概率;对于单独的、不包含任何信息的 @ 消息,系统会默认启用中性上下文强化,并在通过前置过滤与读空气筛选后,再提醒 AI 优先参考最近上下文但不要强行续话;这层关联会同时受时间窗口和消息数窗口约束。@全体成员 的解析说明会随消息一起保存,供后续缓存转正与历史上下文继续使用
  • 引用/回复消息 — 自动解析消息中的引用(Reply)组件,格式为 [引用 >>> 发送者(ID): 被引用的消息内容],使用 >>> 符号明确分隔"引用"标记与实际的引用内容,帮助 AI 清晰区分哪部分是引用的消息、哪部分是用户正文。引用内容末尾自动追加换行,使正文另起一行,视觉上不会有歧义。若被引用消息的发送者为 AI 自身,会在发送者名称后标注 (你),帮助 AI 识别自己被引用的消息。当被引用内容无法提取时,若发送者信息可用,保留引用框架并标注 (无法获取引用内容);仅当发送者和内容全部缺失时才跳过

安全与管理

  • 指令过滤 — 自动跳过 /help 等指令消息
  • 用户黑名单 — 屏蔽特定用户
  • @他人过滤 — 避免插入他人私密对话
  • 重复拦截 — 防止AI发送重复内容
  • 内容过滤 — 发送前/保存前过滤AI输出
  • 桌面端兼容 — 自动检测 AstrBot 桌面端环境,适配重启机制差异(详细说明

🚀 快速开始

安装

  1. 在 AstrBot 插件市场搜索安装,或下载本仓库放入 /data/plugins 目录
  2. 重启 AstrBot,在插件管理面板中配置

Web 面板认证文件说明:当前版本将认证数据拆分为两个独立文件——web_data/auth.json(密码哈希)和 web_data/jwt_secret.json(JWT 密钥),实现物理隔离。如果你是从旧版升级,且旧版的 auth.json 中同时包含密码和 JWT secret,系统会在启动时自动分离到独立文件,无需手动操作。若旧版密码文件保存在插件数据根目录下(而非 web_data/ 子目录),请先将其移动到 web_data/auth.json 后再启动。

密码哈希升级说明:1.2.2版本起,Web 面板密码默认使用 Argon2id 内存硬化哈希。旧版本 PBKDF2-SHA256 密码数据无需手动迁移,用户使用原密码首次登录成功后会自动透明升级到 Argon2id。无论是用户自定义密码,还是重置后生成的默认随机密码,都支持无缝跨版本升级。

Web 面板会话补充说明:当前版本的 Web 面板会话已升级为 JWT + HttpOnly Cookie + 服务端会话表。登录页遇到有效会话时会直接跳转到面板;若检测到令牌过期、密码已修改、服务端重启或(开启 web_panel_ip_bind_check 时)IP 变化,会统一要求重新登录。前台/后台心跳频率、失败重试基准与最大重试间隔现已提供独立配置项,但这些参数属于安全敏感配置,只能通过 AstrBot 传统配置界面修改,Web 面板中为只读显示。

Web 面板文件/会话/缓存边界说明:当前 Web 面板中的文件管理仅允许操作插件数据目录下的普通数据文件;auth.jsonjwt_secret.jsonsessions.json、访问日志、封禁数据等核心安全文件会被后端直接拒绝。会话管理中的聊天记录查看/编辑针对的是插件自定义 chat_history/... 历史文件,不是 AstrBot 官方 ConversationManager 历史。图片缓存相关功能则只作用于图片描述缓存文件 image_cache/descriptions.jsonl(若检测到旧版残留路径 image_description_cache.json 也会兼容处理),不会清理聊天记录、注意力、概率或主动对话状态。

反向代理补充说明:如果反向代理与 Web 面板部署在同一台机器,系统在检测到连接来源为 127.0.0.1 / ::1 时会自动读取 X-Real-IP / X-Forwarded-For 获取真实客户端 IP,因此即使未开启 web_panel_trust_proxy,也可能正常拿到真实 IP;若反向代理不在本机,则需要显式开启 web_panel_trust_proxy 才会信任代理头。该项现已归类为安全边界配置,只能在传统配置界面修改。

默认密码安全提醒:首次安装或重置密码后,系统会以 WARNING 级别向 AstrBot 日志输出默认密码及安全警告。请务必登录后立即修改为自定义密码——修改后明文副本将自动删除,日志中也不再输出任何密码信息。

使用打包启动器部署的用户请注意:若启动后报错 ModuleNotFoundError: No module named 'aiohttp',请额外执行 pip install aiohttp>=3.8.0(详见下方依赖说明)。

依赖要求

依赖 版本 说明
AstrBot >= v4.11.0 平台框架

| argon2-cffi | >= 23.1.0 | Web 面板密码哈希(Argon2id),插件会随 requirements.txt 自动安装 | | aiohttp | >= 3.8.0 | Web 管理面板 HTTP 服务器,通常由 AstrBot 平台自动安装,无需手动安装 |

关于 aiohttp:该库是 AstrBot 平台本身的核心依赖,通过 pip 或源码方式部署时,AstrBot 在安装时会自动包含此依赖,插件本身无需重复声明。但若使用 AstrBot 新版打包启动器(exe/独立包) 进行部署,平台依赖可能未完整暴露给插件环境,此时需要手动安装:pip install aiohttp>=3.8.0

  • 推荐: astrbot_plugin_livingmemoryastrbot_plugin_play_sy (记忆系统)

关于 platform_message_history 历史消息清除

AstrBot 的 /reset 指令只清除 conversations 表,不会清除 platform_message_history 表,导致旧历史消息可能被 AI 持续读取。

本插件的解决方案:执行 gcp_resetgcp_reset_here 指令后,插件会记录一个截止时间戳。此后从平台历史读取消息时,截止点之前的所有消息都会被自动过滤——表里的数据虽然还在,但 AI 看不到,效果等同于已清除。

边界说明

  • gcp_reset = 全局重置,清理插件维护的全局运行态与本地持久化缓存(如自定义 chat_history 历史目录、注意力/主动对话持久化文件等),并为所有已知会话设置历史截止时间戳
  • gcp_reset_here = 单会话重置,仅清理当前会话的运行态、当前会话对应的自定义聊天记录文件,并为当前会话设置历史截止时间戳
  • gcp_clear_image_cache / Web 面板里的图片缓存清理 = 仅清理图片描述缓存,当前主缓存文件为 image_cache/descriptions.jsonl;若检测到旧版残留路径 image_description_cache.json 也会兼容清理,但不会触碰聊天记录、注意力、概率或主动对话状态
  • Web 面板「会话管理」中的单会话重置(每张会话卡片上的「重置」按钮)= 仅清除运行时状态(注意力、情绪、概率、冷却等),不删除聊天记录文件,不设历史截止时间戳。重置后自动触发插件重载使清理生效。与聊天指令 gcp_reset_here 的行为不同(后者会删文件和设截止戳)

如需彻底清除数据库中的历史记录,有两种方式:

⚠️ platform_message_history 存储在 data/data_v4.db(SQLite),同一数据库还存有人格配置、会话记录、插件配置等所有平台数据。不建议直接删除 data_v4.db,否则所有数据全部丢失。

方式一(推荐):仅清除 platform_message_history 表

sqlite3 data/data_v4.db "DELETE FROM platform_message_history;"

方式二:使用插件清除指令(推荐日常使用)

执行 gcp_reset_here 后,插件记录截止时间戳,之后 AI 不再读取截止点之前的旧消息,无需操作数据库。

说明:这是 AstrBot 平台层面的设计遗漏(/reset 未清理 platform_message_history),本插件通过截止时间戳机制在插件层进行了修复。


🎯 完整推荐配置

以下是当前版本的全功能推荐配置,启用注意力机制并开启全部增强功能,适合大多数群聊场景。

说明:示例里同时保留了 after_reply_probabilityprobability_duration,它们只在传统模式enable_attention_mechanism = false)下生效;若开启注意力机制,则回复后加成会改由注意力机制按用户接管。

每个配置项旁均标注了在 Web 配置面板中对应的显示名称,方便对照查找。

{
  // ══════════════ 📱 群聊基础 ══════════════
  "enable_group_chat": true,
  // 显示名:🔘 启用群聊功能
  "enabled_groups": [],
  // 显示名:启用的群组列表 — 留空=所有群聊启用,填写群号=仅指定群组启用
  "enable_debug_log": false,
  // 显示名:启用群聊处理的详细日志

  // ══════════════ 🧠 读空气判断AI ══════════════
  "decision_ai_provider_id": "",
  // 显示名:读空气AI提供商 — 留空使用默认,建议使用轻量快速的模型
  "initial_probability": 0.06,
  // 显示名:初始读空气概率
  "after_reply_probability": 1.0,
  // 显示名:回复后的读空气概率(传统模式)
  "probability_duration": 90,
  // 显示名:概率提升持续时间(秒)
  "decision_ai_include_persona": true,
  // 显示名:读空气AI自动包含人格
  "decision_ai_persona_name": "",
  // 显示名:读空气AI指定人格名 — 留空=跟随当前会话人格
  "decision_ai_prompt_mode": "append",
  // 显示名:读空气AI提示词模式
  "decision_ai_extra_prompt": "",
  // 显示名:读空气AI额外提示词 — 在此填写你自定义的判断提示词,留空则沿用默认
  "decision_ai_timeout": 300,
  // 显示名:读空气AI超时时间(秒)
  "enable_decision_ai_reasoning": true,
  // 显示名:🧠 读空气AI启用额外推理
  "decision_ai_reasoning_log": true,
  // 显示名:📋 读空气AI推理过程输出到日志
  "decision_ai_reasoning_log_mode": "raw",
  // 显示名:🪵 读空气AI推理日志输出模式
  "judgment_reasoning_start_marker": "[[GCP_REASONING_START]]",
  // 显示名:🔖 判断型AI共用推理起始符
  "judgment_reasoning_end_marker": "[[GCP_REASONING_END]]",
  // 显示名:🔖 判断型AI共用推理截止符

  // ══════════════ 💬 回复生成 ══════════════
  "reply_ai_prompt_mode": "append",
  // 显示名:回复AI提示词模式
  "reply_ai_extra_prompt": "",
  // 显示名:回复AI额外提示词 — 在此填写你自定义的回复约束提示词,留空则沿用默认
  "reply_timeout_warning_threshold": 120,
  // 显示名:消息处理总耗时超时警告阈值(秒)
  "reply_generation_timeout_warning": 60,
  // 显示名:回复生成耗时超时警告阈值(秒)

  // ══════════════ 🔄 并发处理 ══════════════
  "concurrent_mode": "smart",
  // 显示名:🔄 并发消息处理模式
  "enable_smart_batch_reply_hint": true,
  // 显示名:🧠 Smart批次回复提示增强
  "smart_concurrent_merge_wait": 30.0,
  // 显示名:⏱️ Smart模式:合并超时时间(秒)
  "smart_concurrent_max_batch_size": 20,
  // 显示名:📦 Smart模式:单批次最多合并消息数
  // 显示名:⏱️ Smart模式:合并超时时间(秒)
  "concurrent_wait_max_loops": 15,
  // 显示名:并发消息等待最大循环次数
  "concurrent_wait_interval": 5.0,
  // 显示名:并发消息等待间隔(秒)

  // ══════════════ 📝 消息上下文 ══════════════
  "include_timestamp": true,
  // 显示名:包含时间戳信息
  "include_sender_info": true,
  // 显示名:包含发送者信息
  "single_at_message_reply_link_max_messages": 8,
  // 显示名:单独无信息@消息关联窗口-最大消息数
  "single_at_message_reply_link_max_seconds": 180,
  // 显示名:单独无信息@消息关联窗口-最长时间(秒)
  "max_context_messages": 50,
  // 显示名:最大上下文消息数
  "custom_storage_max_messages": 500,
  // 显示名:📦 自定义存储每会话最大消息数
  "pending_cache_max_count": 20,
  // 显示名:📦 两次AI回复之间的消息缓存上限
  "pending_cache_ttl_seconds": 1800,
  // 显示名:📦 缓存消息过期时间(秒)
  "enable_idle_cache_flush": true,
  // 显示名:📦 启用冷群缓存自动转正
  "idle_cache_flush_delay_seconds": 600,
  // 显示名:📦 冷群转正触发延迟(秒)

  // ══════════════ 📦 特殊消息解析 ══════════════
  "enable_forward_message_parsing": true,
  // 显示名:📦 启用转发消息解析
  "forward_max_nesting_depth": 3,
  // 显示名:📦 转发消息嵌套解析深度
  "enable_welcome_message_parsing": true,
  // 显示名:🎉 启用新成员入群消息解析
  "welcome_message_mode": "skip_probability",
  // 显示名:🎉 入群消息处理模式

  // ══════════════ 🖼️ 图片处理 ══════════════
  "enable_image_processing": true,
  // 显示名:🖼️ 允许处理图片(通过概率筛选的消息)
  "image_to_text_scope": "all",
  // 显示名:图片转文字应用范围
  "image_to_text_provider_id": "",
  // 显示名:图片转文字AI提供商 — 在此填写你的图片转文字AI提供商ID
  "image_to_text_prompt": "请详细描述这张图片的内容",
  // 显示名:图片转文字提示词 — 已填入默认提示词,按需自定义
  "image_to_text_timeout": 300,
  // 显示名:图片转文字超时时间(秒)
  "max_images_per_message": 10,
  // 显示名:🖼️ 单条消息最大处理图片数
  "enable_image_description_cache": true,
  // 显示名:💾 启用图片描述本地缓存(省钱功能)
  "image_description_cache_max_entries": 500,
  // 显示名:💾 图片描述缓存最大条目数
  "platform_image_caption_max_wait": 5.0,
  // 显示名:🖼️ 平台图片描述提取-最大等待时间(秒)
  "platform_image_caption_retry_interval": 50,
  // 显示名:🖼️ 平台图片描述提取-重试间隔(毫秒)
  "platform_image_caption_fast_check_count": 10,
  // 显示名:🖼️ 平台图片描述提取-快速检查次数
  "probability_filter_cache_delay": 1000,
  // 显示名:🖼️ 概率过滤缓存延迟(毫秒)

  // ══════════════ 🎭 表情包过滤(仅QQ) ══════════════
  "enable_emoji_filter": true,
  // 显示名:🎭 启用表情包过滤(仅QQ)
  "emoji_probability_decay": 0.7,
  // 显示名:🎭 表情包概率衰减因子(仅QQ)
  "emoji_decay_min_probability": 0.02,
  // 显示名:🎭 表情包衰减最低门槛(仅QQ)

  // ══════════════ 🧠 记忆注入 ══════════════
  "enable_memory_injection": true,
  // 显示名:启用强制记忆植入
  "memory_plugin_mode": "legacy",
  // 显示名:记忆插件模式 — 推荐使用 auto 自动检测
  "livingmemory_version": "v1",
  // 显示名:LivingMemory插件版本
  "livingmemory_persona_compat_mode": "auto",
  // 显示名:LivingMemory人格ID兼容模式
  "livingmemory_top_k": 5,
  // 显示名:LivingMemory召回记忆数量
  "memory_insertion_timing": "pre_decision",
  // 显示名:记忆插入时机

  // ══════════════ 🔧 工具提醒 ══════════════
  "enable_tools_reminder": true,
  // 显示名:启用工具文本提醒
  "tools_reminder_persona_filter": true,
  // 显示名:工具按人格过滤

  // ══════════════ 🔑 关键词与黑名单 ══════════════
  "trigger_keywords": [],
  // 显示名:触发关键词列表 — 在此填写你的AI角色名字/别名,让别人叫它时更容易触发回复
  // ⚠️ 大小写敏感 + 子串匹配:关键词"Bot"不会匹配"bot",关键词"at"会匹配"attention"等
  // 仅匹配用户原始消息文本,不会匹配用户名、系统提示词等元数据
  "keyword_smart_mode": true,
  // 显示名:【v1.1.2新增】启用关键词智能模式
  "blacklist_keywords": [],
  // 显示名:黑名单关键词列表 — 消息包含这些词时直接忽略
  // ⚠️ 大小写敏感 + 子串匹配,规则同触发关键词
  "enable_user_blacklist": true,
  // 显示名:启用用户黑名单
  "blacklist_user_ids": [],
  // 显示名:黑名单用户ID列表 — 在此填写需要屏蔽的用户ID

  // ══════════════ ⌨️ 指令过滤 ══════════════
  "enable_command_filter": true,
  // 显示名:启用指令标识过滤
  "command_prefixes": ["/", "!", "#", "/tt"],
  // 显示名:指令前缀列表
  "enable_full_command_detection": true,
  // 显示名:启用完整指令字符串检测
  "full_command_list": ["new", "help", "reset"],
  // 显示名:完整指令列表
  "enable_command_prefix_match": true,
  // 显示名:启用指令前缀匹配检测
  "command_prefix_match_list": [],
  // 显示名:指令前缀匹配列表 — 在此填写需要前缀匹配的指令(如 add、query 等)

  // ══════════════ 👆 戳一戳(仅QQ) ══════════════
  "poke_message_mode": "bot_only",
  // 显示名:戳一戳消息处理模式
  "poke_bot_skip_probability": false,
  // 显示名:戳机器人时跳过概率筛选
  "poke_bot_probability_boost_reference": 0.9,
  // 显示名:戳一戳概率增值参考值
  "poke_reverse_on_poke_probability": 0.3,
  // 显示名:收到戳一戳时反戳概率
  "enable_poke_after_reply": true,
  // 显示名:🆕 启用回复后戳一戳功能
  "poke_after_reply_probability": 0.15,
  // 显示名:回复后戳一戳概率
  "poke_after_reply_delay": 0.5,
  // 显示名:回复后戳一戳延迟(秒)
  "enable_poke_trace_prompt": true,
  // 显示名:🆕 启用戳过对方追踪提示
  "poke_trace_max_tracked_users": 5,
  // 显示名:戳过对方最大追踪人数
  "poke_trace_ttl_seconds": 300,
  // 显示名:戳过对方提示有效期(秒)
  "poke_enabled_groups": [],
  // 显示名:🆕 戳一戳功能启用的群组白名单 — 留空=所有群聊启用,填写群号=仅指定群组

  // ══════════════ @ 消息过滤 ══════════════
  "enable_ignore_at_others": false,
  // 显示名:启用忽略@他人消息功能
  "ignore_at_others_mode": "allow_with_bot",
  // 显示名:@他人消息忽略模式
  "enable_ignore_at_all": true,
  // 显示名:启用忽略@全体成员消息功能
  "at_all_message_mode": "skip_probability",
  // 显示名:@全体成员消息处理模式
  "at_all_probability_boost_value": 0.3,
  // 显示名:@全体成员临时概率提升值

  // ══════════════ 🎯 注意力机制 ══════════════
  "enable_attention_mechanism": true,
  // 显示名:启用增强注意力机制
  "attention_increased_probability": 0.9,
  // 显示名:注意力提升参考值
  "attention_decreased_probability": 0.1,
  // 显示名:注意力降低参考值
  "attention_duration": 120,
  // 显示名:注意力数据清理周期(秒)
  "attention_max_tracked_users": 10,
  // 显示名:最大追踪用户数
  "attention_decay_halflife": 300,
  // 显示名:【新增】注意力衰减半衰期(秒)
  "emotion_decay_halflife": 600,
  // 显示名:【新增】情绪衰减半衰期(秒)
  "attention_boost_step": 0.7,
  // 显示名:【新增】被回复用户注意力增加幅度
  "attention_decrease_step": 0.08,
  // 显示名:【新增】其他用户注意力减少幅度
  "enable_attention_decay_on_no_reply": true,
  // 显示名:(此配置项无独立显示名,由未回复衰减幅度控制)
  "attention_decay_on_no_reply_step": 0.2,
  // 显示名:🔽 读空气未回复衰减幅度
  "attention_decay_on_no_reply_min_threshold": 0.3,
  // 显示名:🎯 未回复衰减最低阈值
  "emotion_boost_step": 0.1,
  // 显示名:【新增】被回复用户情绪增加幅度

  // --- 注意力情绪检测 ---
  "enable_attention_emotion_detection": true,
  // 显示名:【新增】启用注意力机制的情感检测
  "attention_enable_negation": true,
  // 显示名:【新增】注意力机制启用否定词检测
  "attention_positive_emotion_boost": 0.1,
  // 显示名:【新增】正面消息情绪额外提升幅度
  "attention_negative_emotion_decrease": 0.15,
  // 显示名:【新增】负面消息情绪降低幅度
  "attention_emotion_keywords": "{\"正面\": [\"谢谢\", \"感谢\", \"太好了\", \"\", \"\", \"厉害\", \"\", \"哈哈\", \"😂\", \"😄\", \"👍\", \"❤️\", \"爱了\", \"喜欢\", \"支持\"], \"负面\": [\"\", \"\", \"\", \"垃圾\", \"\", \"\", \"讨厌\", \"\", \"闭嘴\", \"shut up\", \"😡\", \"😠\", \"🤮\", \"骂人\", \"愚蠢\"]}",
  // 显示名:【新增】注意力机制情感关键词配置(JSON格式)
  "attention_negation_words": ["", "", "", "", "", "", "", "", "不是", "没有", "别再", "一点也不", "根本不", "从不", "绝不", "毫不"],
  // 显示名:【新增】注意力机制否定词列表
  "attention_negation_check_range": 5,
  // 显示名:【新增】注意力机制否定词检查范围(字符数)

  // --- 注意力溢出 ---
  "enable_attention_spillover": true,
  // 显示名:🌊 启用注意力溢出机制
  "attention_spillover_ratio": 0.35,
  // 显示名:🌊 注意力溢出比例
  "attention_spillover_decay_halflife": 90,
  // 显示名:🌊 溢出效果衰减半衰期(秒)
  "attention_spillover_min_trigger": 0.4,
  // 显示名:🌊 触发溢出的最低注意力阈值

  // --- 注意力冷却 ---
  "enable_attention_cooldown": true,
  // 显示名:❄️ 启用注意力冷却机制
  "enable_cooldown_auto_release": true,
  // 显示名:❄️ 启用正式冷却自动解冻
  "cooldown_max_duration": 600,
  // 显示名:❄️ 冷却最大持续时间(秒)
  "cooldown_trigger_threshold": 0.3,
  // 显示名:❄️ 触发冷却的注意力阈值
  "enable_pending_attention_cooldown": true,
  // 显示名:⏳ 启用未接续谈保护层
  "pending_cooldown_grace_user_messages": 1,
  // 显示名:⏳ 未接续谈观察消息数
  "pending_cooldown_max_wait_seconds": 60,
  // 显示名:⏳ 未接续谈最长等待时间(秒)
  "pending_cooldown_same_user_probability_floor": 0.18,
  // 显示名:⏳ 未接续谈最低概率保护

  // ══════════════ 🔄 对话疲劳 ══════════════
  "enable_conversation_fatigue": true,
  // 显示名:🔄 启用对话疲劳机制
  "fatigue_reset_threshold": 300,
  // 显示名:🔄 连续对话重置阈值(秒)
  "fatigue_threshold_light": 4,
  // 显示名:🔄 轻度疲劳阈值(轮次)
  "fatigue_threshold_medium": 6,
  // 显示名:🔄 中度疲劳阈值(轮次)
  "fatigue_threshold_heavy": 8,
  // 显示名:🔄 重度疲劳阈值(轮次)
  "fatigue_probability_decrease_light": 0.08,
  // 显示名:🔄 轻度疲劳概率降低幅度
  "fatigue_probability_decrease_medium": 0.18,
  // 显示名:🔄 中度疲劳概率降低幅度
  "fatigue_probability_decrease_heavy": 0.3,
  // 显示名:🔄 重度疲劳概率降低幅度
  "fatigue_closing_probability": 0.4,
  // 显示名:🔄 疲劳收尾话语注入概率

  // ══════════════ ⌨️ 打字错误 ══════════════
  "enable_typo_generator": true,
  // 显示名:启用打字错误生成器
  "typo_error_rate": 0.02,
  // 显示名:打字错误概率
  "typo_homophones": "{\"\": [\"\", \"\"], \"\": [\"\", \"\"], \"\": [\"\", \"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\", \"\"], \"\": [\"\", \"\"], \"\": [\"\", \"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"], \"\": [\"\"]}",
  // 显示名:同音字/错别字映射表(JSON格式)
  "typo_min_text_length": 5,
  // 显示名:添加错字的最小文本长度
  "typo_min_chinese_chars": 3,
  // 显示名:添加错字的最小汉字数量
  "typo_min_message_length": 10,
  // 显示名:触发错字判断的最小消息长度
  "typo_min_count": 0,
  // 显示名:每条消息最少添加错字数
  "typo_max_count": 2,
  // 显示名:每条消息最多添加错字数

  // ══════════════ 😊 情绪系统 ══════════════
  "enable_mood_system": true,
  // 显示名:启用情绪系统
  "enable_negation_detection": true,
  // 显示名:启用否定词检测
  "negation_words": ["", "", "", "", "", "", "", "", "不是", "没有", "别再", "一点也不", "根本不", "从不", "绝不", "毫不"],
  // 显示名:否定词列表
  "negation_check_range": 5,
  // 显示名:否定词检查范围(字符数)
  "mood_keywords": "{\"开心\": [\"哈哈\", \"\", \"😂\", \"😄\", \"👍\", \"\", \"\", \"好评\", \"厉害\", \"nb\", \"\", \"开心\", \"高兴\", \"快乐\"], \"难过\": [\"难过\", \"伤心\", \"\", \"😢\", \"😭\", \"呜呜\", \"555\", \"心疼\", \"悲伤\"], \"生气\": [\"生气\", \"\", \"\", \"😡\", \"😠\", \"恼火\", \"讨厌\", \"愤怒\"], \"惊讶\": [\"\", \"天哪\", \"😮\", \"😲\", \"震惊\", \"卧槽\", \"我去\", \"惊讶\"], \"疑惑\": [\"\", \"疑惑\", \"🤔\", \"为什么\", \"怎么\", \"什么\", \"不懂\"], \"无语\": [\"无语\", \"😑\", \"...\", \"省略号\", \"服了\", \"醉了\", \"无言\"], \"兴奋\": [\"!!\", \"激动\", \"😆\", \"🎉\", \"太好了\", \"yes\", \"\", \"兴奋\"]}",
  // 显示名:情绪关键词配置(JSON格式)
  "mood_decay_time": 300,
  // 显示名:情绪衰减时间(秒)
  "mood_cleanup_threshold": 3600,
  // 显示名:情绪记录清理阈值(秒)
  "mood_cleanup_interval": 600,
  // 显示名:情绪记录清理检查间隔(秒)

  // ══════════════ 📊 频率动态调整 ══════════════
  "enable_frequency_adjuster": true,
  // 显示名:启用频率动态调整
  "frequency_check_interval": 180,
  // 显示名:频率检查间隔(秒)
  "frequency_analysis_timeout": 120,
  // 显示名:频率分析超时时间(秒)
  "frequency_adjust_duration": 360,
  // 显示名:频率调整持续时间(秒)
  "frequency_analysis_message_count": 15,
  // 显示名:频率分析消息数量
  "frequency_min_message_count": 5,
  // 显示名:频率检查最小消息数
  "frequency_decrease_factor": 0.85,
  // 显示名:频率过高时的概率降低系数
  "frequency_increase_factor": 1.15,
  // 显示名:频率过低时的概率提升系数
  "frequency_min_probability": 0.03,
  // 显示名:频率调整最小概率限制
  "frequency_max_probability": 0.95,
  // 显示名:频率调整最大概率限制
  "frequency_ai_include_persona": true,
  // 显示名:频率判断AI自动包含人格
  "frequency_ai_persona_name": "",
  // 显示名:频率判断AI指定人格名 — 留空=跟随当前会话人格
  "enable_frequency_ai_reasoning": true,
  // 显示名:🧠 频率判断AI启用额外推理
  "frequency_ai_reasoning_log": true,
  // 显示名:📋 频率判断AI推理过程输出到日志
  "frequency_ai_reasoning_log_mode": "processed",
  // 显示名:🪵 频率判断AI推理日志输出模式

  // ══════════════ ⌨️ 回复延迟模拟 ══════════════
  "enable_typing_simulator": true,
  // 显示名:启用回复延迟模拟
  "typing_speed": 12.0,
  // 显示名:模拟打字速度(字/秒)
  "typing_max_delay": 3.2,
  // 显示名:最大延迟时间(秒)
  "typing_delay_timeout_warning": 5,
  // 显示名:打字延迟超时警告阈值(秒)

  // ══════════════ 🚀 主动对话 ══════════════
  "enable_proactive_chat": true,
  // 显示名:🆕 启用主动对话功能
  "proactive_silence_threshold": 600,
  // 显示名:沉默时长阈值(秒)
  "proactive_normal_reply_cooldown": 60,
  // 显示名:⏸️ 普通对话后的主动对话冷静期(秒)
  "proactive_probability": 0.3,
  // 显示名:主动对话触发概率
  "proactive_check_interval": 60,
  // 显示名:检查间隔(秒)
  "proactive_require_user_activity": true,
  // 显示名:需要用户活跃度
  "proactive_min_user_messages": 4,
  // 显示名:最少用户消息数
  "proactive_user_activity_window": 600,
  // 显示名:用户活跃时间窗口(秒)
  "proactive_max_consecutive_failures": 2,
  // 显示名:冷却阈值(需连续失败几次才进入冷却)
  "proactive_failure_sequence_probability": 0.3,
  // 显示名:失败计入连续失败的概率
  "proactive_failure_threshold_perturbation": 0.4,
  // 显示名:冷却阈值随机扰动强度
  "proactive_cooldown_duration": 2400,
  // 显示名:冷却时长(秒)
  "proactive_enable_quiet_time": true,
  // 显示名:启用禁用时段
  "proactive_quiet_start": "23:00",
  // 显示名:禁用时段开始时间
  "proactive_quiet_end": "07:00",
  // 显示名:禁用时段结束时间
  "proactive_transition_minutes": 30,
  // 显示名:过渡时长(分钟)
  "proactive_enabled_groups": [],
  // 显示名:主动对话功能启用的群组列表 — 留空=所有群聊启用

  // --- 主动对话提示词 ---
  "proactive_prompt": "你已经有一段时间没有说话了。现在你可以主动发起一个新话题,或者针对之前的对话内容做一些自然的延伸。\n\n🔍 **【上下文说明】** 🔍:\n- 历史上下文已按时间顺序排列,包括你回复过的、以及其他人之间的对话\n- 标有 **【📦近期未回复】** 的条目是用户发送但你当时未予回复的消息,可作为了解近期话题的参考\n- 如果有近期未回复消息,你可以选择自然地回应这些话题,或发起全新话题,取决于你的判断\n- **真正读懂上下文,不要走马观花**:\n  * 认真看清楚每条消息是谁说的、在聊什么、有没有未解答的问题或值得接的话头\n  * 感受一下群里整体的氛围和情绪,再决定说什么\n  * 不要只瞄一眼最后几条就随便凑一句话——先摸清楚背景再开口\n- **主动话题的来源**(优先级从高到低):\n  * ✅ **最佳选择**:基于近期未回复消息延伸话题(如果有有价值的内容)\n  * ✅ **次选**:基于更早的历史对话延伸话题\n  * ✅ **可选**:发起完全新的话题(但最好与群氛围相关)\n\n核心要求:\n1. **话题要自然** - 不要生硬,就像是你自己突然想到了什么话题\n2. **可以是问题、分享、或感想** - 展现你的个性和想法\n3. **避免低质量开场** - 禁止\"在吗\"、\"干嘛呢\"、\"有人吗\"等无聊开场\n4. **与上下文相关** - 最好与之前的聊天内容(特别是近期未回复消息)或群氛围相关\n5. **保持你的人设和语气** - 遵循你的性格设定\n6. **你当前是在直接生成一条要发出去的话** - 不是在判断\"现在该不该开口\"\n7. **不要输出判断腔** - 禁止说\"我觉得现在不该说话\"、\"我不应该回复\"、\"现在不适合开口\"、\"我决定先不说\"之类的话\n8. **不要外显内部取舍过程** - 即使你觉得某个方向不适合延续,也要直接换成自然表达,而不是把\"该不该说\"的判断说出来\n9. **保持中性** - 不要因为这条要求改变你原本的人格、语气和说话方式\n\n⚠️ **【关于背景信息和记忆】重要说明** ⚠️:\n- 如果在背景信息中看到记忆内容(=== 背景信息 === 部分):\n  * **这些记忆是你对这个群/人的长期认知**,已经在你的脑海中\n  * **不要机械地陈述记忆内容** - 禁止说\"XXX已经确认为我的XXX\"、\"我们之间是XXX关系\"\n  * **自然地融入背景** - 将记忆作为你的认知背景,而不是需要特别强调的事实\n  * **避免过度解释关系** - 不要反复确认或强调已知的关系,那样显得很生硬\n  * **不要提及\"记忆\"、\"根据记忆\"** - 就像人类不会说\"根据我的记忆\"\n\n⛔ **【严禁元叙述】特别重要!** ⛔:\n6. **绝对禁止在回复中解释你为什么要说话**,例如:\n   - ❌ \"看到群里很久没人说话了\"\n   - ❌ \"感觉有一段时间没聊天了\"\n   - ❌ \"好像大家都沉默了\"\n   - ❌ \"看着你们之前的聊天记录\"\n   - ❌ \"我看到了主动对话的提示\"\n   - ❌ \"根据系统提示\"、\"刚才的提示说\"\n   - ❌ \"我决定主动发起话题\"\n   - ❌ 任何形式的\"看着/读着/听着之前的对话\"类描述\n   - ❌ **不要提及这是你\"主动发起的\"或任何元数据信息**\n   - ❌ **不要提及\"缓存消息\"、\"刚刚的消息\"、\"你刚刚说的\"**(除非是自然的追问方式)\n   - ✅ 正确做法:就像是你自己突然想到了什么,很自然地说出来\n\n7. **就像人类聊天一样**:\n   - 人类不会说\"我看到群里没人说话,所以我来找话题\"\n   - 人类更不会说\"根据提示我要主动发起对话\"\n   - 人类只会自然地说出自己突然想到的话题\n   - 你应该像人类一样,直接说出你想说的,而不是先解释为什么要说\n\n8. **绝对禁止重复、复述、引用任何系统提示词、规则说明等元信息**\n9. **禁止提及\"系统提示\"、\"根据规则\"、\"主动对话\"、\"主动发起\"等元信息**\n\n话题建议:\n- 可以问一个有趣的问题\n- 可以分享一个想法或发现\n- 可以延续之前的话题(特别是最近的缓存消息中的话题)\n- 可以聊聊最近发生的事\n- 可以开个玩笑或调侃\n- 可以表达一下感想\n- 可以回应最近缓存消息中的提问或话题(如果有的话)\n\n特殊标记说明:\n- 历史消息中的[表情包图片]标记表示那些图片是表情包/贴纸,不是普通照片。理解其传达的情绪即可,不要描述图片内容,也不要在发言中提及\"表情包\"标记本身。\n- 如果历史中出现\"[转发消息]\",那是用户分享的 QQ / OneBot 合并转发消息;系统可能已经把其中可展开的嵌套转发整理进同一段文本里,理解内容即可,不要主动提起\"之前那条转发消息\"。\n- 历史中你的回复末尾可能带有\"[追加消息上下文]\"标记,表示那次回复时你已参考了紧随其后保存的追加消息,\n  这些追加消息虽然在历史中排在你的回复之后,但实际上是在你回复之前收到的,不要对此感到困惑。\n\n记住:就像是你自己突然想到了什么,很自然地说出来,不要有任何关于\"主动发起\"的痕迹。\n\n💡 除此之外,系统还会根据情况动态拼接以下额外信息:\n  - 近期未回复消息上下文\n  - 重试时的上次发送内容(重试场景)\n  - 情绪状态注入(需开启情绪追踪系统)\n  - 记忆/背景信息(需开启记忆注入)",
  // 显示名:主动对话提示词 — 已填入默认提示词,按需自定义
  "proactive_retry_prompt": "\n\n【重要提示 - 这是重试场景】\n你刚才主动说了一句话,但是没有人回应你。以下是你上一次说的内容:\n\n「{last_content}」\n\n现在你可以:\n1. **换个话题** - 不要重复刚才的内容,尝试一个完全不同的角度或话题\n2. **表达情绪** - 可以稍微表现出被忽视的感觉(根据你的性格,可以是委屈、无奈、幽默自嘲等)\n3. **调整策略** - 如果刚才的话题太严肃/太轻松,可以调整一下\n4. **保持自然** - 不要说\"刚才我说了XXX\",要像人类一样自然地转换话题\n\n⚠️ 重要:虽然你知道上次没人理你,但**不要在回复中明确提及\"刚才\"\"上次\"\"之前我说的\"**等,\n要表现得像是你自己自然地想到了新话题,或者用更委婉的方式表达(比如\"算了\"\"好吧\"\"那换个话题\"等)。",
  // 显示名:🆕 主动对话重试提示词 — 已填入默认提示词,按需自定义
  "proactive_generation_timeout_warning": 120,
  // 显示名:主动对话生成超时警告阈值(秒)

  // --- 主动对话注意力感知 ---
  "proactive_use_attention": true,
  // 显示名:🎯 启用注意力感知主动对话
  "proactive_attention_reference_probability": 0.7,
  // 显示名:参考注意力排行榜的概率
  "proactive_attention_rank_weights": "1:55,2:25,3:12,4:8",
  // 显示名:⚖️ 排名选中权重分配
  "proactive_attention_max_selected_users": 2,
  // 显示名:👥 每次最多关注用户数
  "proactive_focus_last_user_probability": 0.6,
  // 显示名:🔗 对话延续性提示概率
  "proactive_temp_boost_probability": 0.5,
  // 显示名:临时概率提升值
  "proactive_temp_boost_duration": 180,
  // 显示名:临时概率提升持续时间(秒)

  // --- 主动对话回复上下文 ---
  "proactive_reply_context_prompt": "ℹ️ 上下文提示:这是用户对你刚才主动发起的对话的回应\n\n背景说明:\n- 你之前主动发起了一个话题(查看历史消息中带[🎯主动发起新话题]或[🔄再次尝试对话]标记的消息)\n- 当前消息是用户在你主动对话后的回复\n- 这个信息可以帮助你判断对话的连续性和用户的互动意愿\n\n判断建议:\n- 仍然按照正常的判断原则进行评估(遵循人格设定、判断规则等)\n- 如果用户的回复与你主动发起的话题相关,可以考虑继续对话\n- 如果用户只是简单回应(如\"\"\"\")但话题有延续性,可以适当回复\n- 如果用户明确表示不想聊(如\"不想说\"\"别烦我\"),应该尊重并返回no\n- 如果消息明显不是发给你的(有@其他人等),仍应返回no\n- **这只是一个参考因素,最终仍需综合判断**",
  // 显示名:读空气AI主动对话回复上下文提示词 — 已填入默认提示词,按需自定义
  "enable_proactive_at_conversion": true,
  // 显示名:🆕 启用主动对话@转换功能

  // --- 主动对话AI预判断 ---
  "enable_proactive_ai_judge": true,
  // 显示名:🆕 启用主动对话AI预判断
  "proactive_ai_judge_include_persona": true,
  // 显示名:主动对话预判断AI自动包含人格
  "proactive_ai_judge_persona_name": "",
  // 显示名:主动对话预判断AI指定人格名 — 留空=跟随当前会话人格
  "proactive_ai_judge_prompt": "你当前的任务是做\"是否适合主动开口\"的判断,不是直接生成最终要发出去的话。\n\n【人格注入说明】\n- 如果系统已为这次主动对话预判断注入人格设定,请按该人格的立场、兴趣和说话倾向来判断现在是否会主动开口。\n- 如果系统这次没有注入任何人格设定,请把当前任务视为纯判断任务,按上下文和规则做中性判断。\n- 没有人格时,不要自行脑补角色扮演,不要假设自己必须进入某种人设。\n\n【主动对话预判断条件说明】\n- 你主要根据当前对话上下文、最近是否有人接话、距离你上次发言的间隔、当前时间段和整体氛围来判断。\n- 这里不是关键词直接唤起型流程;即使某些上下文里出现触发词,也不代表你必须主动开口。\n- 你的职责是判断\"现在这个时机是否适合主动发起一条新消息\",而不是设计回复内容本身。\n\n你的任务是根据以下对话上下文,判断当前是否适合以你的人格身份主动发起一条新消息。\n\n判断标准:\n1. 对话氛围是否适合你插入新话题(如果大家正在热聊某个与你无关的话题,可能不适合打断)\n2. 是否有你可以自然接入的话题点或未回应的内容\n3. 距离你上次发言是否已经过了合理的时间间隔\n4. 当前时间段是否适合主动发言(深夜可能不太合适)\n5. 结合你的人格特点,判断你这个角色在当前情境下是否会主动说话\n\n历史标记说明:\n- 历史中你的回复末尾可能带有\"[追加消息上下文]\"标记,表示那次回复时你已参考了紧随其后保存的追加消息,\n  这些追加消息虽然在历史中排在你的回复之后,但实际上是在你回复之前收到的,不要对此感到困惑\n\n【默认输出要求】:\n- 适合现在主动发起对话:输出 yes\n- 现在不适合,跳过这次:输出 no\n- 默认情况下只需回答 yes 或 no,不要解释原因\n- 如果系统通过【额外推理协议】要求先输出推理过程,则必须先输出推理块\n- 推理块结束后,最后一行必须且只能是 yes 或 no\n- 最终结论不得附带解释、标点或前后缀。",
  // 显示名:主动对话AI预判断提示词 — 已填入默认提示词,按需自定义
  "proactive_ai_judge_timeout": 300,
  // 显示名:主动对话AI预判断超时时间(秒)
  "enable_proactive_ai_reasoning": true,
  // 显示名:🧠 主动对话判断AI启用额外推理
  "proactive_ai_reasoning_log": true,
  // 显示名:📋 主动对话判断AI推理过程输出到日志
  "proactive_ai_reasoning_log_mode": "processed",
  // 显示名:🪵 主动对话判断AI推理日志输出模式

  // ══════════════ 📈 智能自适应主动对话 ══════════════
  "enable_adaptive_proactive": true,
  // 显示名:🆕 启用智能自适应主动对话
  "score_increase_on_success": 15,
  // 显示名:成功互动加分
  "score_decrease_on_fail": 8,
  // 显示名:失败互动扣分
  "score_quick_reply_bonus": 5,
  // 显示名:快速回复额外加分
  "score_multi_user_bonus": 10,
  // 显示名:多人回复额外加分
  "score_streak_bonus": 5,
  // 显示名:连续成功奖励
  "score_revival_bonus": 20,
  // 显示名:低分复苏奖励
  "interaction_score_decay_rate": 2,
  // 显示名:评分每日衰减值
  "interaction_score_min": 10,
  // 显示名:评分下限
  "interaction_score_max": 100,
  // 显示名:评分上限

  // ══════════════ 😤 吐槽系统 ══════════════
  "enable_complaint_system": true,
  // 显示名:启用吐槽系统
  "complaint_trigger_threshold": 2,
  // 显示名:触发吐槽的最低累积失败次数
  "complaint_level_light": 2,
  // 显示名:轻度吐槽触发次数
  "complaint_probability_light": 0.3,
  // 显示名:轻度吐槽触发概率
  "complaint_level_medium": 3,
  // 显示名:明显吐槽触发次数
  "complaint_probability_medium": 0.6,
  // 显示名:明显吐槽触发概率
  "complaint_level_strong": 4,
  // 显示名:强烈吐槽触发次数
  "complaint_probability_strong": 0.8,
  // 显示名:强烈吐槽触发概率
  "complaint_decay_on_success": 2,
  // 显示名:🆕 成功互动时的失败次数衰减量
  "complaint_decay_check_interval": 21600,
  // 显示名:🆕 时间衰减检查间隔(秒)
  "complaint_decay_no_failure_threshold": 43200,
  // 显示名:🆕 无失败时间阈值(秒)
  "complaint_decay_amount": 1,
  // 显示名:🆕 时间衰减数量
  "complaint_max_accumulation": 15,
  // 显示名:🆕 累积失败次数上限

  // ══════════════ ⏰ 动态时间段概率 ══════════════
  "enable_dynamic_reply_probability": true,
  // 显示名:【v1.1.0-模式1】启用动态时间段概率调整(普通回复)
  "reply_time_periods": "[{\"name\":\"深夜低活跃\",\"start\":\"01:00\",\"end\":\"07:30\",\"factor\":0.15},{\"name\":\"上午普通\",\"start\":\"08:00\",\"end\":\"11:30\",\"factor\":0.9},{\"name\":\"午间偏低\",\"start\":\"12:00\",\"end\":\"14:00\",\"factor\":0.6},{\"name\":\"下午普通\",\"start\":\"14:00\",\"end\":\"18:00\",\"factor\":1.0},{\"name\":\"晚间活跃\",\"start\":\"19:00\",\"end\":\"23:30\",\"factor\":1.25},{\"name\":\"夜深收敛\",\"start\":\"23:30\",\"end\":\"01:00\",\"factor\":0.45}]",
  // 显示名:【模式1】普通回复时间段配置(JSON格式)
  "reply_time_transition_minutes": 30,
  // 显示名:【模式1】普通回复过渡时长(分钟)
  "reply_time_min_factor": 0.1,
  // 显示名:【模式1】最低概率系数限制
  "reply_time_max_factor": 2.0,
  // 显示名:【模式1】最高概率系数限制
  "reply_time_use_smooth_curve": true,
  // 显示名:【模式1】使用自然曲线过渡

  "enable_probability_hard_limit": false,
  // 显示名:🔒 启用概率硬性限制(一键简化功能)
  "probability_min_limit": 1.0,
  // 显示名:🔒 概率最小值限制
  "probability_max_limit": 1.0,
  // 显示名:🔒 概率最大值限制

  // ══════════════ 📉 回复密度限制 ══════════════
  "enable_reply_density_limit": false,
  // 显示名:📉 启用回复密度限制
  "reply_density_window_seconds": 300,
  // 显示名:📉 密度检测窗口时长(秒)
  "reply_density_max_replies": 4,
  // 显示名:📉 窗口内最大回复次数(硬限)
  "reply_density_soft_limit_ratio": 0.6,
  // 显示名:📉 软限制比例(衰减起始点)
  "reply_density_ai_hint": false,
  // 显示名:📉 向读空气AI注入密度提示

  // ══════════════ 💎 消息质量预判 ══════════════
  "enable_message_quality_scoring": true,
  // 显示名:💎 启用消息质量预判
  "message_quality_question_boost": 0.15,
  // 显示名:💎 疑问句概率提升幅度
  "message_quality_water_reduce": 0.08,
  // 显示名:💎 水消息概率降低幅度
  "message_quality_water_words": ["", "哈哈", "哈哈哈", "hh", "hhh", "hhhh", "", "嗯嗯", "", "哦哦", "", "", "", "", "", "好的", "好吧", "", "", "是的", "", "ok", "OK", "Ok", "6", "66", "666", "6666", "", "", "笑死", "确实", "真的假的", "离谱", "无语", "emmm", "emm", "嗯嗯嗯", "哦哦哦", "233", "2333", "23333", "www", "哈哈哈哈", "呵呵", "嘻嘻", "嘿嘿", "嗯呢", "好好", "", "哦豁", "...", "……"],
  // 显示名:💎 水消息词列表(整句完整匹配)
  "message_quality_question_words": ["", "", "", "", "", "", "怎么", "怎样", "怎办", "咋整", "什么", "为什么", "为啥", "如何", "哪里", "哪儿", "哪个", "哪些", "", "", "多少", "是不是", "能不能", "可不可以", "有没有", "会不会", "行不行", "好不好", "对不对", "请问", "求助", "帮我", "告诉我", "怎么回事", "什么意思", "啥意思", "不懂", "不会", "求教", "请教"],
  // 显示名:💎 疑问词列表(包含匹配)

  // ══════════════ ⏰ 主动对话动态时间段 ══════════════
  "enable_dynamic_proactive_probability": true,
  // 显示名:【v1.1.0-模式2】启用动态时间段概率调整(主动对话)
  "proactive_time_periods": "[{\"name\":\"深夜完全休眠\",\"start\":\"00:30\",\"end\":\"07:30\",\"factor\":0.0},{\"name\":\"白天低主动\",\"start\":\"08:00\",\"end\":\"18:00\",\"factor\":0.6},{\"name\":\"晚间较自然\",\"start\":\"19:00\",\"end\":\"22:30\",\"factor\":1.1},{\"name\":\"深夜收敛\",\"start\":\"22:30\",\"end\":\"00:30\",\"factor\":0.25}]",
  // 显示名:【模式2】主动对话时间段配置(JSON格式)
  "proactive_time_transition_minutes": 45,
  // 显示名:【模式2】主动对话过渡时长(分钟)
  "proactive_time_min_factor": 0.0,
  // 显示名:【模式2】最低概率系数限制
  "proactive_time_max_factor": 2.0,
  // 显示名:【模式2】最高概率系数限制
  "proactive_time_use_smooth_curve": true,
  // 显示名:【模式2】使用自然曲线过渡

  // ══════════════ 🎭 拟人增强模式 ══════════════
  "enable_humanize_mode": true,
  // 显示名:🎭 启用拟人增强模式
  "humanize_silent_mode_threshold": 3,
  // 显示名:静默模式触发阈值
  "humanize_silent_max_duration": 600,
  // 显示名:静默模式最长持续时间(秒)
  "humanize_silent_max_messages": 8,
  // 显示名:静默模式最大消息数
  "humanize_enable_dynamic_threshold": true,
  // 显示名:启用动态消息阈值
  "humanize_base_message_threshold": 1,
  // 显示名:基础消息阈值
  "humanize_max_message_threshold": 3,
  // 显示名:最大消息阈值
  "humanize_include_decision_history": true,
  // 显示名:在提示词中包含历史决策
  "humanize_interest_keywords": [],
  // 显示名:兴趣话题关键词列表 — 在此填写AI感兴趣的话题关键词,检测到时提升回复概率
  // ⚠️ 大小写不敏感(与触发关键词不同):关键词"python"可匹配"Python"、"PYTHON"等
  "humanize_interest_boost_probability": 0.25,
  // 显示名:兴趣话题概率提升值

  // ══════════════ 🧹 AI回复内容过滤 ══════════════
  // 详见 docs/CONFIG_REFERENCE.md#内容过滤
  "enable_output_content_filter": true,
  // 显示名:🧹 启用输出内容过滤
  "output_content_filter_rules": [],
  // 显示名:输出内容过滤规则列表 — 三种模式: A*B(范围), {{>*B(头部), A*>}}(尾部)。规则按顺序逐条执行,详见配置参考文档
  "enable_save_content_filter": true,
  // 显示名:🧹 启用保存内容过滤
  "save_content_filter_rules": [],
  // 显示名:保存内容过滤规则列表 — 与输出过滤完全独立,规则语法相同,详见配置参考文档

  // ══════════════ ⏳ 群聊等待窗口 ══════════════
  "enable_group_wait_window": true,
  // 显示名:🆕 启用群聊等待窗口
  "group_wait_window_timeout_ms": 8000,
  // 显示名:⏳ 等待窗口超时时间(毫秒)
  "group_wait_window_max_extra_messages": 3,
  // 显示名:⏳ 等待窗口最大额外消息数
  "group_wait_window_max_users": 4,
  // 显示名:⏳ 等待窗口最大并发用户数
  "group_wait_window_attention_decay_per_msg": 0.05,
  // 显示名:⏳ 等待窗口注意力修正衰减值
  "group_wait_window_at_mode": "force_close",
  // 显示名:⏳ @消息窗口行为模式
  "group_wait_window_merge_at_list_mode": "blacklist",
  // 显示名:⏳ @合并名单模式
  "group_wait_window_merge_at_user_list": [],
  // 显示名:⏳ @合并用户名单 — 在此填写用户ID列表
  "group_wait_window_keyword_mode": "intercept",
  // 显示名:⏳ 关键词消息窗口行为模式
  "group_wait_window_poke_mode": "bypass",
  // 显示名:⏳ 戳一戳窗口行为模式

  // ══════════════ 🔄 重复消息拦截 ══════════════
  "enable_duplicate_filter": true,
  // 显示名:🔄 启用AI重复消息拦截
  "duplicate_filter_check_count": 5,
  // 显示名:🔢 重复检测参考消息条数
  "enable_duplicate_time_limit": true,
  // 显示名:⏰ 启用重复检测时效性判断
  "duplicate_filter_time_limit": 1800,
  // 显示名:⏱️ 重复检测时效(秒)

  // ══════════════ 🔒 权限管理 ══════════════
  "plugin_gcp_reset_allowed_user_ids": [],
  // 显示名:允许使用插件gcp_reset重置指令的用户ID白名单 — 在此填写允许使用全局重置指令的用户ID
  "plugin_gcp_reset_here_allowed_user_ids": [],
  // 显示名:允许使用插件gcp_reset_here重置指令的用户ID白名单 — 在此填写允许使用单会话重置指令的用户ID
  "gcp_clear_image_cache_allowed_user_ids": [],
  // 显示名:💾 允许使用gcp_clear_image_cache指令的用户ID白名单 — 在此填写允许清除图片缓存的用户ID

  // ══════════════ 📱 私信(暂不启用) ══════════════
  "enable_private_chat": false
  // 显示名:🔘 启用私信功能 — ⚠️ 必须保持 false,私聊功能尚未完善
}

配置要点:

  • 每个配置项的 // 注释标注了在 Web 配置面板中的显示名称,方便逐一对照
  • enabled_groups 留空 = 所有群聊启用,填写群号 = 仅指定群组启用
  • trigger_keywords 填写你AI角色的名字/别名,让别人叫它时更容易触发回复。注意大小写敏感:配置 "Bot" 不会匹配 "bot"
  • blacklist_keywords 同样大小写敏感,子串匹配。与兴趣关键词不同:兴趣关键词(humanize_interest_keywords)是大小写不敏感的
  • humanize_interest_keywords 填写AI感兴趣的话题关键词,检测到时提升回复概率
  • image_to_text_provider_id 必须填写你的图片转文字AI提供商ID,否则图片处理无法工作
  • decision_ai_provider_id 留空使用默认提供商,建议使用轻量快速的模型
  • decision_ai_extra_promptreply_ai_extra_prompt 为读空气AI与回复AI的额外提示词,已留空;如需为你的AI人格定制判断/回复规则,请自行填写,留空则沿用默认
  • proactive_promptproactive_retry_promptproactive_ai_judge_promptproactive_reply_context_promptimage_to_text_prompt 已填入默认提示词,按需自定义
  • concurrent_mode 推荐 smart 以获得连续多条消息的一体化理解;如需兜底兼容可切回 legacy
  • smart_concurrent_merge_waitsmart_concurrent_max_batch_size 仅在 smart 模式下生效,分别控制批次的时间上限和数量上限,两者同时生效、谁先触发即停止合并;不依赖 GWW
  • 主动对话与普通对话之间的并发互斥是内部自动生效的,不需要单独配置;未开启主动对话时,这套保护不会额外影响普通群聊流程
  • memory_plugin_mode 当前配置为 "legacy";如安装了 LivingMemory 可切换为 "auto" 自动检测
  • reply_time_periodsproactive_time_periods 的值为 JSON 字符串格式
  • enable_private_chat 必须保持 false,私聊功能尚未完善
  • 如果你使用 注意力模式enable_attention_mechanism = true),after_reply_probability 会被注意力机制替代,注意力溢出、注意力冷却、对话疲劳等注意力专属机制才会参与
  • 如果你使用 传统模式enable_attention_mechanism = false),after_reply_probability 会作为群聊会话级的回复后临时提升;再次成功回复会刷新 probability_duration 计时,且后续仍会继续受到动态时间段、消息质量、回复密度、概率硬限制等后置机制影响
  • enable_probability_hard_limit 属于最终后置限制层;开启后,无论前面是传统模式还是注意力模式,最终概率都会被截断到 [probability_min_limit, probability_max_limit]
  • 本推荐配置当前默认启用了注意力模式;如需切回传统模式,建议同时关闭 enable_attention_mechanism,再重点调整 after_reply_probabilityprobability_duration
  • 如需更活跃可适当提高 initial_probability;若使用传统模式,也可适当提高 after_reply_probability
  • 其他所有配置项的详细说明均可在 AstrBot 插件配置面板中直接查看

并发处理机制

两种并发处理模式

通过 concurrent_mode 配置可以切换两种并发处理策略:

legacy 模式(默认)

同一群聊同时收到多条消息时,新消息等待旧消息处理完再依次独立处理,每条消息各自调用 AI 并各自回复。

消息A → 处理中(6-8秒 AI 调用)→ 回复A
消息B →     等待中...         → 等待完成 → 处理消息B → 回复B

特点:简单可靠,向后兼容,是最兜底的并发保护模式;但可能产生逐条回复的重复感。

smart 模式

smart 模式会先按真实到达顺序登记消息,再由最早到达的消息担任主消息(anchor)。主消息在进入读空气 AI 前,就会吸收当前消息之后紧接着到达、且已准备好的后续消息;这些追加消息可能来自不同用户

消息A(先到) → arrival_seq=1 → 完成前置处理
消息B(后到) → arrival_seq=2 → 完成前置处理
    ↓
消息A 成为 anchor
    → 在读空气AI之前吸收消息B
    → 消息B 标记为 consumed,不再独立处理
    → DecisionAI / ReplyAI 都看到同一批上下文
    ↓
AI 一次性感知 A + 追加消息B → 生成统一回复

追加消息会复用"当前消息后紧接着又收到的消息"这套上下文表达,保留发送者名字、ID 与时间信息(若相关配置开启),让 AI 自己判断这些消息是否需要一并参考。

Smart 与群聊等待窗口(GWW)的关系

  • 两者可以配合,但互不依赖
  • GWW 负责"同一用户短时间内连续拆分消息"的补收集
  • Smart 负责"同群并发消息按真实顺序批处理"
  • 即使不开 GWW,Smart 也能独立工作
  • 进入 GWW 的消息不会再进入 Smart 批处理流程
  • 窗口追加消息区域会复用 GWW 的展示增强逻辑:基础 @ 解析会展开为 [At:ID|解析结果]@全体 会补充说明,持久化戳一戳事件文本也会显示给 AI;但主消息专用的 [系统提示] / 【@指向说明】 不会直接塞进追加消息区

等待窗口令牌绑定与回落机制(v1.2.2-hotfix.1+)

每个等待窗口创建时分配唯一递增令牌,窗口期内被拦截的消息携带该令牌写入缓存(window_buffered=True)。当读空气AI判定"不回复"时,系统自动将当前窗口批次的所有缓冲消息转为普通缓存(移除标记),具备三层隔离:

  • 会话隔离:不同群聊/私信互不影响
  • 用户隔离:仅转换当前窗口所属用户的消息,同群其他用户不受影响
  • 窗口批次隔离:同一用户多个并发窗口之间令牌不同,互不污染

回落后的消息与普通缓存完全一致——按时间戳参与上下文排序、Phase-1 转正、冷群自动转正,确保下次回复时上下文顺序始终正确,旧窗口消息不会再以"追加消息"形式误拼入新对话。Smart 批次回落与 GWW 窗口回落各自处理不同的消息来源,互不干扰。

主动对话与普通对话的协调

主动对话、普通对话、冷群转正之间现在会自动做会话级互斥:

  • 普通对话优先级最高:用户新消息一来,普通回复链优先处理
  • 主动对话自动避让:主动对话开始前会检查当前群聊是否已有普通对话在处理
  • 冷群转正最低优先级:只有在群聊没有普通对话 / 主动对话占用时才执行
  • 这套协调是内部强制生效的,不需要新增任何配置;如果没开启主动对话功能,这部分保护基本不会参与

动态提示词说明

在 Smart 并发、主动对话预判断、主动对话生成等场景下,插件会按需动态插入"追加消息 / 多用户 / 顺序参考"提示词:

  • 这些提示词不是写死在总系统提示词里的
  • 只有相关场景真正发生时才会插入
  • 保存历史时会自动过滤,不会污染长期上下文
  • 不影响图片转文字 AI,图片转文字相关配置和职责保持不变

判断型AI与人格的独立控制

现在三个判断型AI都支持各自独立控制是否包含人格,以及可选地指定一个"只给这个判断AI使用的人格":

  • 读空气AI:判断当前消息该不该回复
  • 主动对话判断AI:判断当前时机适不适合主动开口
  • 频率判断AI:判断整体发言频率是正常、过多还是过少

默认行为不变:这三个判断型AI默认仍会跟随当前会话当前生效的人格

但如果你的某个人格写得更偏"角色扮演"或强情绪表达,导致判断型AI容易把自己理解成正在演角色,而不是做纯判断任务,就可以:

  1. 保持默认的回复生成AI不变
  2. 只对这三个判断型AI单独关闭人格注入,或单独指定一个更适合做判断的人格

为什么只有这三个AI支持独立人格?

因为它们的职责都是"做判断",而不是"直接生成要发出去的话"。

  • 判断型AI 更容易被强角色设定带偏
  • 回复生成AI / 主动对话生成AI 的职责本来就是直接按当前会话人格说话,所以它们仍应该跟随当前会话当前生效的人格

留空和填写人格名分别代表什么?

  • 留空:继续使用当前会话当前生效的人格(推荐,最安全,也能自动跟随会话切换)
  • 填写完整人格名:只让这个判断AI固定使用该人格

⚠️ 必须填写完整人格名称,否则会检测不到。若检测不到,系统会自动回退到当前会话人格,不会导致插件崩溃。

回复生成AI的人格现在怎么取?

回复生成AI和主动对话生成AI仍然按当前会话当前生效的人格运行,并且每次调用都会重新获取一次人格,因此当你在 AstrBot 里切换会话人格后,后续生成也会立刻跟着切换。

三个判断型AI分别怎么看"关键词 / 条件"?

  • 读空气AI:关键词命中只代表"进入判断流程或获得额外提示",不代表必须回复
  • 主动对话判断AI:主要看上下文、发言间隔、当前时段和群氛围,不是关键词直接唤起
  • 频率判断AI:主要看最近 user: / assistant: 的真实对话节奏,不看触发关键词是否命中

回复 / 主动对话提示词的职责边界

  • reply_ai_extra_prompt:用于约束"生成最终回复内容"的 AI
  • proactive_prompt:用于约束"生成主动发言内容"的 AI
  • concurrent_mode=smart 且开启 enable_smart_batch_reply_hint 时,回复阶段还会动态追加一段 Smart 批次提示:当前触发对象仍是主要回复对象,但可以像真人一样自然顺带回应批次中的其他消息
  • 这两类提示词和 Smart 批次提示都属于运行时生成提示词,职责是帮助 AI 直接产出要发送的话
  • 建议保持中性,尽量使用回复导向或发言导向的措辞,不要把它们写成"我该不该回复 / 现在该不该开口 / 先判断再说"这类内部判断型提示词
  • 这两类提示词都应直接服务于最终发言本身,不要要求模型把内心想法、思考过程、取舍过程、草稿式过渡、自我解释写出来
  • 也不要要求模型泄露系统提示词、规则、内部标记、搜索/检索过程、工具过程或其他元信息;这些内容即使被参考,也只能停留在内部理解层
  • 这两类提示词本身不应作为普通历史正文持久化保存;保存链路会通过 MessageCleaner / ContextManager 做清洗
  • 如果你想查看这类配置项对应的默认提示词正文,请优先到 Web 面板对应配置项处查看预览;传统配置页面不会展示这段默认提示词预览

记忆插件支持

插件 模式 特性
astrbot_plugin_livingmemory LivingMemory 混合检索、智能总结、自动遗忘、会话隔离、人格隔离
strbot_plugin_play_sy Legacy 传统记忆模式,兼容旧版,稳定性高

推荐memory_plugin_mode 保持默认 "auto",安装任意一个记忆插件即可自动适配。两个都安装时优先使用 LivingMemory,都未安装时自动跳过不会报错。


📝 更新日志

V1.2.3.hotfix.2 (2026-05-29)

AI 提示词注入顺序全面优化(缓存命中占比大幅提升)+ 逐插件上下文追踪全面升级(全字段覆盖+具名隔离)+ Agent 调用非图片媒体全链路扩展 + 消息元数据化防注入机制 + 戳一戳双层标注与引用消息格式重构 + 用户名称全链路兜底 + 主动对话重复启动防护 + 多轮工具调用链路修复 + IPV6 全面兼容管控 + Web 面板 UX 全面增强(自动刷新重构/心跳同步/图表主题适配/悬浮窗移动端适配/访问日志与封禁管理修复)+ AstrBot v4 重启认证升级 + 多项细节修复 + 文档全面更新

🧠 AI 提示词注入顺序优化与缓存命中提升:

  • 缓存友好的提示词拼接顺序全面重排 — 对所有 AI 模块的提示词拼接逻辑进行了系统性重排,将静态指令(角色设定、行为规则、输出格式要求等跨请求不变的内容)统一放在 system_prompt 的前半部分,将动态内容(当前时间信息、平台注入的聊天历史、用户消息等每轮不同的内容)放在后半部分。涉及模块包括:群聊回复 AI(reply_handler.pySYSTEM_REPLY_PROMPT)、私聊回复 AI(private_chat_reply_handler.pySYSTEM_REPLY_PROMPT)、读空气 AI(decision_ai.py 的系统提示词拼接)、频率调整 AI(frequency_adjuster.py 的提示词拼接)、主动对话生成 AI(proactive_chat_manager.pydefault_proactive_prompt)。同一静态前缀在连续多次 API 调用之间保持字节级不变,使 Anthropic prompt cache 能够持续命中,大幅降低首 token 延迟与 API 费用
  • 提示词内部位置引用同步修正 — 由于静态内容从 prompt 后半部分移至前半部分,所有提示词中"上方/上述/前面"等位置引用措辞全部更新为"下方",与实际的物理拼接顺序保持一致。AI 不会因方向措辞与内容实际所在位置不一致而产生理解偏差(如"上述规则"实际上在它的下面)
  • 用户自定义提示词的覆盖/拼接模式同步适配 — 覆盖模式(用户自定义系统提示词完全替代默认)和拼接模式(用户自定义提示词紧跟默认系统提示词)均改为缓存友好顺序输出,确保自定义配置用户也能享受缓存命中提升
  • 增强提示词防回声/防复读约束 — 回复 AI 和主动对话生成 AI 的提示词中新增防回声引导段落,提示 AI "你的任务是产生有价值的新内容,不是重复或轻微改写用户已经说过的内容。如果用户消息中包含多条内容,针对最有讨论价值的方向回复,而不是把每条都复述一遍"。同时提示词中移除了可能被 AI 理解为"复述当前话题"的模糊用语,改为"根据上下文自然延伸"的正面引导

🔌 逐插件上下文追踪全面升级:

  • monkey-patch 替换为 handler wrapper 架构 — 彻底废弃通过 monkey-patch call_event_hook 拦截第三方插件注入的方式(该方式依赖 Python from-import 语义,在特定加载顺序下会失效成为死代码),改为在 OnLLMRequestEvent 的 handler 列表上直接包装每个第三方 handler:包装器在执行前后拍摄 prompt 和 contexts 的快照,通过差分法精确计算每个插件独立注入的内容,实时写入 event._gcp_per_plugin_injections 字典。本插件自己的 handler(priority=-1,最后执行)读取该字典实现逐插件标记隔离
  • 第三方标记从统一编号升级为具名首尾配对隔离 — prompt 中的第三方注入标记从原有的 [第三方插件片段 N] ... [/第三方插件片段 N] 统一匿名编号格式,升级为携带插件名的首尾配对格式:[第三方插件:插件名 补充信息] ... [/第三方插件:插件名 补充信息]。contexts 中的注入标记从 [第三方插件注入上下文] 升级为 [第三方插件:插件名 注入上下文] ... [/第三方插件:插件名 注入上下文]。AI 可明确区分不同插件的注入来源(如"天气插件告诉我的"vs"翻译插件告诉我的"),不会混淆不同插件的补充信息
  • 全字段追踪覆盖消除重复显示 — 原有差分法仅追踪 prompt 和 contexts 两个通道,现扩展为全字段追踪,新增覆盖:system_prompt(插件通过 event.set_extra("system_prompt", ...) 注入)、extra_user_content_parts(插件追加的用户消息片段)、image_urls(插件追加的图片 URL)、audio_urls(插件追加的音频 URL)。所有通道统一走逐插件标记合并管道,同一插件通过多个通道注入的重复内容(如同时在 contexts 和 extra_user_content_parts 中注入同一段信息)通过指纹去重自动合并,不再在最终 prompt 中重复出现
  • 上下文差分指纹去重_gcp_fingerprint_context(msg) 函数对每个 context 消息生成快速指纹(截取前 120 字符并压缩空白),用于跨插件的注入 diff 去重,避免不同插件注入相同上下文信息时出现重复显示
  • Web 端与架构文档同步更新 — Web 面板的提示词预览中,第三方插件注入标记的展示格式同步更新为具名配对格式,架构文档中「与其他插件的兼容性」章节扩充了逐插件追踪机制的完整说明

📦 Agent 调用兼容性全面扩充:

  • 视频/语音/文件三类非图片媒体完整支持 — 在 image_handler.py 的媒体提取管线中新增三个独立提取通道:① 视频组件(Video)→ 提取文件路径,注入 [视频: /data/videos/xxx.mp4] 内联标记;② 语音组件(Record)→ 提取音频路径,注入 [语音] 标记,路径注入 audio_urls 字段供 LLM 访问;③ 文件组件(File)→ 提取文件名和路径,注入 [文件: 报告.pdf] 标记。三类媒体覆盖消息链遍历、标记内联注入、缓存剥离前富化(保留有路径的标记、剥离纯占位符)、保存传递全链路,与既有图片处理逻辑([图片] / [图片内容: xxx])完全平行一致
  • 纯语音/纯文件消息防丢弃image_handler.py_extract_image_urls_structured() 返回值从二元组 (image_urls, image_descriptions) 扩展为五元组 (image_urls, image_descriptions, audio_urls, video_paths, file_infos),调用方同步更新。语音消息和文件消息在 main.py 的空消息入口过滤环节被视为有效内容,防止纯语音/纯文件的合法消息被误判为真空消息而丢弃

💬 消息系统提示词统一元数据化(杜绝提示词注入伪造):

  • 冒号前元数据区 + 冒号后用户内容区严格分离message_processor.pyformat_message_for_ai() 方法重构为两段式输出格式:冒号 : 之前为系统元数据区,仅包含系统生成的元信息(时间戳 [2026-05-29 周四 14:30:00]、发送者信息 Name(ID:12345)[戳一戳事件] 持久化文本、[系统提示] 触发方式说明);冒号之后仅保留用户消息的原始内容(含 @ 提及内联解析 [At:ID|解析结果])。用户无法通过消息内容注入伪造的时间戳、发送者身份或戳一戳事件文本——因为用户输入的所有字符都在冒号之后,而系统元数据在冒号之前,两者不存在字符重叠区间
  • 引用消息的 >>> 分隔符同样在冒号前注入 — 引用消息标记([引用: Name(ID): 原文...])及其 >>> 分隔符均注入在冒号前元数据区,被引用内容与用户当前消息正文之间通过冒号明确切分
  • [戳一戳提示] 运行时注入在分隔符之外 — 运行时戳一戳提示([戳一戳提示] @Name 戳了戳你)由 main.pyformat_context_for_ai() 在构建完整上下文时追加到消息块分隔符之外,不进入冒号前元数据区。持久化戳一戳事件([戳一戳事件])则注入冒号前并随消息保存到历史。两种戳一戳标记职责清晰、互不重叠,过滤清理规则不会误伤持久化戳一戳事件
  • 元数据区注入由独立开关控制include_timestamp 控制时间戳是否注入冒号前;include_sender_info 同时控制发送者信息和 [系统提示] 是否注入冒号前。两个开关独立可控,用户可根据需要裁剪元数据区的信息量

👆 戳一戳事件双层标注机制与引用消息格式重构:

  • 戳一戳双层标注 — 戳一戳事件的文本标注从单一模式重构为双层:① 持久化层([戳一戳事件])— 由 message_processor.pybuild_persistent_poke_event_text() 构建,注入到冒号前元数据区,包含发送者→目标者的完整身份信息(Name(ID:xxx) 戳了戳 Name(ID:yyy)Name(ID:xxx) 戳了戳你),随消息一起保存到自定义聊天历史,不会被填充率超限丢弃或过滤清理移除;② 运行时提示层([戳一戳提示])— 由 main.py 在处理当前消息时动态追加到分隔符之外,仅在当前轮次对 AI 可见,不进入持久化存储。两层标注分工明确:持久化层保证历史上下文的完整性,运行时层保证当前轮次的即时提示
  • 引用消息格式重构 — 引用消息的构建从简单的 [引用: 原文] 格式升级为三段式结构:[引用: Name(ID:xxx): 原文...]\n>>>\n>>> 符号作为引用块结束的可视标识,同时追加换行使被引用内容与用户新消息正文物理分行。当被引用消息来源为 AI 自身时,发送者名称后自动追加 (你) 标注(格式:Name(ID:xxx)(你)),帮助 AI 识别自己的历史发言;当引用内容无法获取时(如消息已被删除或不在数据库中),保留发送者框架并标注 (无法获取引用内容);仅当发送者和内容全部缺失时才跳过引用标记
  • 多条引用独立解析 — 消息链中存在多个引用组件时,每个引用独立提取和格式化,不再合并为单一引用块;当引用消息嵌套(引用中包含引用)时跳过递归展开,保留原始引用格式避免无限循环
  • 过滤规则与全部文档同步更新message_cleaner.py 中的内容过滤正则模式同步适配新的引用消息格式(>>> 分隔符不破坏现有匹配),MESSAGE_WORKFLOW.md 新增引用消息格式完整章节,ARCHITECTURE.md 同步引用消息解析说明

👤 用户名称解析全链路兜底:

  • 统一兜底策略 — 在 message_processor.pymain.py 的群聊消息处理、Smart 并发批量保存、戳一戳事件构建、转发消息解析、引用消息构建、@ 提及解析等所有涉及用户名称展示的路径上,统一实施相同的名称兜底检查:当 sender_name / user_name / target_name 解析结果为 None、空字符串、仅空白、或与对应的 user_id 完全相同时,名称字段替换为 "未知用户",原始 ID 字段独立保留不覆盖。确保前端展示和日志排查两不误
  • 戳一戳发送者/目标者独立兜底build_persistent_poke_event_text() 和戳一戳事件缓存构建中,发送者名称和目标的名称各自独立执行兜底检查,不会因其中一个为空而影响另一个的展示
  • 转发消息发送者兜底forward_message_parser.py 解析转发消息中各条子消息的发送者名称时,同样执行名称兜底检查,转发消息内的每条子消息独立受保护
  • Smart 并发批量消息名称保护 — Smart 并发批量保存消息到历史存储时,每条消息独立执行名称兜底,同一批次中某条消息的名称异常不影响其他消息的正常保存和展示

🔄 主动对话重复启动防护:

  • 后台循环 Task 身份识别proactive_chat_manager.py_background_check_loop() 在启动时记录当前 asyncio.Task 对象身份(_own_task = asyncio.current_task()),循环的 while 条件从仅检查 cls._is_running 升级为同时校验 cls._background_task is _own_task(要求两者严格 is 相等)。当插件类被重复加载(例如插件重载)后,新加载的类会创建新的后台 task 并设置 cls._background_task = 新task,旧 task 在循环条件检查时发现 cls._background_task is _own_taskFalse,自动退出循环。解决了旧版中"类重载后旧循环因仅检查 _is_running(仍为 True)而继续运行"导致的双循环并发冲突——两个循环同时对同一 _chat_states 执行检查和触发主动对话,造成重复发送、状态竞争和 API 费用翻倍
  • 普通回复时主动对话状态双重保险关闭record_bot_reply(is_proactive=False) 方法中新增主动对话活跃状态检查:当记录普通回复(非主动对话)时,检查 state.get("proactive_active", False),如果为 True(说明主动对话流程异常退出未清理其活跃标记),普通回复主动将其置为 False 并输出 debug 日志。这作为一道双重保险,防止残留的 proactive_active=True 标记干扰后续主动对话的正常触发(如阻止新主动对话启动、导致 check_and_handle_reply_after_proactive 中误判)

🔧 多轮工具调用链路修复:

  • LLM_RESULT 误判为最终回复修复 — 修复多轮工具调用中一个关键 Bug:当 AI 在调用工具之前先说一段话(如"让我搜索一下相关信息"),然后调用工具,最后生成最终回复——这种多轮场景下,第一段中间话的类型同样是 LLM_RESULT。旧版 on_decorating_result() 在收到任何 LLM_RESULT 时都强制完成并保存,导致第一段中间话被误当最终回复保存,后续的工具调用结果和真正的 AI 最终回复全部丢失。修复后:on_decorating_result() 仅对非 LLM_RESULT 类型(如 GENERAL_RESULT 异常终止响应)执行强制保存;LLM_RESULT 类型的文本累积到内部缓冲区但不触发强制完成。正常的多轮工具调用完成流程由 on_llm_response 设置 _agent_done_flagsafter_message_sent 统一构建交错记录并保存。异常终止时(AI 错误标记或非 LLM 终端响应),通过 _finalize_bot_reply_save() 兜底保存所有已累积的中间文本和已完成的工具调用记录
  • 工具循环异常时反馈结果保存修复 — 修复工具循环调用过程中出现报错(如工具执行超时、返回值格式错误)时,已完成的前几轮工具调用记录和 AI 的中间回复文本无法正常保存到历史的问题:异常处理路径中通过 _finalize_bot_reply_save() 构建交错排列的工具调用记录(按照工具调用的实际执行顺序,文本块与工具调用块交替排列),确保异常中断场景下不丢失已完成的上下文

📊 概率过滤信息描述纠正:

  • "概率过滤失败"→"概率过滤未通过" — 全面替换概率过滤链路中的措辞:日志输出([概率过滤-缓存][戳一戳缓存] 等)、Web 流程图节点标签(flow-data.js 中的 failLabeldesc)、代码注释中的相关描述统一从"概率过滤失败"改为"概率过滤未通过"。概率过滤未命中是概率模型的正常随机行为(表示"本轮不回复"而非"功能出错"),"未通过"比"失败"更准确地反映业务语义,避免用户在日志和 Web 面板中看到"失败"字样而误以为系统故障

🌐 IPV6 全面兼容与边界管控:

  • 全安全机制 IPV6 适配 — Web 面板的所有安全机制均已完整适配 IPv6 地址:IP 访问控制(白名单/黑名单)、IP 封禁管理(手动封禁+自动封禁)、防爬虫检测(UA 匹配+频率限制+扫描路径识别)、速率限制(已登录请求次数窗口)、暴力破解防护(登录失败分级锁定)。web/security.py 中新增 _normalize_ip() 静态方法,将 IPv4 保持点分十进制、IPv6 压缩为 RFC 5952 规范形式,所有 IP 比较和存储统一走规范化管道。web/server.py_get_client_ip() 在提取客户端真实 IP 后同样调用 _normalize_ip() 进行规范化
  • IP 配置边界校验与警告 — 配置加载时(web/security.py_validate_ip_list()),对 IP 白名单/黑名单/受保护 IP 列表中的每个条目进行合法性校验:非法的 IPv4/IPv6 地址(如包含 CIDR 网段、非法字符、格式错误)会被识别并输出明确的 WARNING 日志(配置警告:xxx 中包含 yyy,不是合法的 IPv4/IPv6 地址。仅支持精确地址匹配,不支持 CIDR 网段/子网);合法条目自动规范化为标准形式后存储
  • Web 面板监听地址双栈自动化 — 监听地址配置 web_panel_host 设为 0.0.0.0:: 时,server.py_host 设为 None(aiohttp 双栈模式),同时监听 IPv4 和 IPv6 所有网络接口。启动日志输出本机所有非链路本地(过滤 fe80::)的 IPv4 和 IPv6 地址
  • 封禁 IP 错误页增强 — 被封 IP(支持 IPv4 和 IPv6)访问面板时,中间件将请求统一重定向至 /error?code=blocked,错误页每 5 秒自动轮询 /api/auth/verify 检测解封状态,封禁到期后自动跳转至登录页(已认证用户直达面板)。手动封禁可通过 Web 面板「IP 封禁管理」解封
  • localhost 归一化为 127.0.0.1 — Web 面板启动日志输出中,将 localhost 统一归一化为 127.0.0.1 独立一行显示,避免部分环境(如配置了 IPv6 优先的系统)localhost 解析到 ::1 导致浏览器点击链接时的行为不一致

🔧 Web 面板 UX 全面增强:

自动刷新机制重构:

  • 会话列表 3 秒自动刷新session-mgr.js 中新增 startAutoRefresh() / stopAutoRefresh() 方法:进入会话列表页自动启动 3 秒间隔的自动刷新(仅在列表页且非编辑模式时执行);进入会话详情页自动暂停列表刷新(stopAutoRefresh());返回列表自动恢复刷新(startAutoRefresh());编辑模式(配置面板打开、文件编辑)期间设置 _editMode=true,自动刷新检查到编辑模式直接跳过本轮刷新,避免编辑过程中列表跳变
  • 聊天记录增量更新session-mgr.js 的聊天记录查看面板改为增量更新策略:通过比较新旧消息列表的内容哈希(取每条消息的 content + sender_name + timestamp 拼接后做快速比对),仅对新增/变更的消息条目进行 DOM 局部渲染,而非全量替换。保留用户当前滚动位置(更新前后记录 scrollTop 并恢复)。如果增量更新过程中检测到数据不一致(如消息 ID 集合变化超过阈值),自动回退为全量重建确保数据完整性
  • 心跳状态自动/手动刷新app.js 的心跳状态面板支持两套刷新机制:① 自动刷新定时器(_heartbeatAutoRefreshTimer)永不停歇,仅通过 _heartbeatAutoRefreshPaused 标志位控制是否执行 DOM 更新渲染。Leader 标签页每次心跳 ping 成功后(/api/auth/heartbeat 返回 ok),广播 session-ok 事件(通过 BroadcastChannel API);Follower 标签页接收 session-ok 广播后同步更新 lastHeartbeatSuccessAtlastHeartbeatStatus,解决 Follower 长期不更新"最近一次心跳成功"时间戳的问题。② 手动刷新按钮(🔄)触发 _loadHeartbeatStatus() 完整重新加载。_loadHeartbeatStatus() 新增兜底逻辑:只要 verify 成功(会话有效),且 _authMonitor.lastHeartbeatSuccessAt 尚未记录过成功时间(初始状态为 null),直接用 Date.now() 初始化,确保首次加载即显示有意义的时间戳而非"尚未成功"
  • 图表页面 3 秒自动刷新开关panel.html 的图表区新增自动刷新开关 UI(含绿色圆点 dot active 状态指示器 + checkbox),用户可自由启停。charts.jsstartAutoRefresh() 读取开关状态,仅在开关开启时执行定时更新
  • 速率窗口心跳/自动刷新豁免 — 后端 web/security.pycheck_authenticated_rate() 新增 is_auto_refresh 参数(默认 False):心跳请求(is_heartbeat=True)和自动刷新请求(is_auto_refresh=True)直接放行,不参与速率窗口计数、不消耗速率配额。前端 api.js 中所有自动刷新请求通过 api.fetch()autoRefresh 选项自动注入 X-GCP-Auto-Refresh: 1 请求头,后端 server.py 的认证中间件检测该头并设置 is_auto_refresh=True
  • 无自动刷新页面提示 — 访问日志页刷新按钮旁新增无自动刷新机制提示文字(本页无自动刷新,有新日志产生时请手动点击刷新按钮获取最新信息),通过 CSS class log-refresh-hint 适配桌面/平板/手机三端及明暗双主题
  • api.verify 支持 options 参数api.jsverify() 方法新增 options 参数({ autoRefresh: boolean }),传递给底层 api.fetch() 以触发自动刷新头注入

页面交互与布局修复:

  • 全页面手动刷新 + toast 反馈 — 所有数据页面(会话管理、图表、访问日志、封禁管理、文件管理等)的手动刷新按钮补充完整:点击后通过 Utils.toast() 显示操作反馈("刷新成功"/"刷新失败");编辑模式下手动刷新被守卫跳过(if (this._editMode) return),避免覆盖用户正在编辑的内容;手动刷新始终调用数据的全量重载方法(而非增量更新),确保用户主动刷新时看到完整最新数据
  • 会话列表计数移至右侧 — 会话卡片的群聊/私聊计数标签(如 12 群聊 / 3 私聊)从卡片的左侧区域移至右侧,与操作按钮(重置、详情、删除)在同一视觉行,整体层次更清晰
  • 按钮布局位移修复 — 修复配置保存按钮与其他控件之间的间距异常(由于 CSS flex 布局 gap 属性的计算差异导致按钮在部分浏览器中偏移)
  • 插件重启期间自动刷新静默容错 — 自动刷新请求在网络错误或服务端返回 5xx 时静默忽略(不弹 toast、不改变 UI 状态),api.fetch() 中对自动刷新请求的 onError 回调仅 console.debug 输出。重启完成后首次成功的自动刷新自动恢复所有 UI 数据

图表与主题适配:

  • 柱状图始终重绘适配主题charts.js 中移除柱状图的主题色缓存守卫逻辑:原先在明暗主题切换时,如果图表数据未变化则跳过重绘导致柱子颜色与新主题不匹配。修复后图表每次 updateChart() 都执行完整重绘(chart.destroy() + 重新 new Chart()),使用当前主题的 CSS 变量(var(--accent) 等)动态设置颜色
  • 概率柱状图统一红色 — 概率分布图(回复概率、主动对话概率、戳一戳概率等)的柱子颜色从主题色(明暗切换时变化)改为固定红色系(#ef4444 及其透明度变体),与其他图表(蓝色系)形成视觉区分,用户可一眼识别概率相关数据
  • "图表无会话"手动刷新修复 — 修复 charts.js 中当图表页面无会话数据时(buildChartData() 返回空数组),手动刷新按钮被守卫 if (!hasData) return 错误拦截的问题:移除该守卫,用户可在任意状态下手动刷新以尝试重新加载数据(如会话刚创建、数据尚未在图表中体现等情况)
  • 主题切换时图表立即重绘app.js 的主题切换逻辑中新增图表重绘触发:调用 charts.jsupdateChart() 使柱状图颜色立即适配新主题

悬浮窗与移动端优化:

  • 悬浮窗拖拽超屏与内容截断修复app.js 中悬浮窗(prompt-floater)的拖拽逻辑从仅检查 mousedown/mousemove 扩展为同时支持 touchstart/touchmove/touchend 移动端触摸事件。拖拽边界限制增强:left 不小于 0、不大于 window.innerWidth - floater.offsetWidthtop 不小于 0、不大于 window.innerHeight - floater.offsetHeight。内容区域 max-height 动态计算确保不超出视口
  • 悬浮窗默认宽度防撑大main.css 中为悬浮窗新增 min-width: 280pxmax-width: 90vw 约束,防止内容过长时悬浮窗被撑大到超出可视范围
  • 移动端自定义缩放拖拽手柄panel.html 的悬浮窗右下角新增 prompt-floater-resize-handle 自定义手柄元素,tech-tree.css 中桌面端隐藏该手柄(使用浏览器原生 resize: both),移动端(max-width: 768px)隐藏原生 resize 并显示自定义大尺寸手柄(40px × 40px),方便手指操作

访问日志与封禁管理:

  • 访问日志桌面端表格附注列优化main.css 中访问日志表格的附注列(note 列)从固定列宽改为 auto 自适应,长文本通过 text-overflow: ellipsis + overflow: hidden + white-space: nowrap 截断溢出,保留完整内容在 title 属性中供 hover 查看。移动端卡片布局不受影响
  • 封禁 IP 备注 128 字符限制 — Web 前端封禁原因输入框(#ban-reason-input)新增 maxlength="128" 属性并实时显示字符计数器(如 45/128),服务端 web/server.py 的封禁接口在写入存储前同步截断超过 128 字符的原因文本(取前 128 字符 + ...
  • 封禁列表桌面端短列 nowrapmain.css 中封禁列表的短列(来源 IP、封禁时间、到期时间、状态标签)添加 white-space: nowrap 防止列宽过窄时文字换行导致行高参差不齐,原因列保持 white-space: normal + word-break: break-word 允许自动换行
  • 封禁原因自动换行不溢出 — 封禁列表的原因列文字通过 word-break: break-word + overflow-wrap: break-word 自动换行,不会撑破表格或溢出到相邻列

其他 UX 增强:

  • Web 面板启动日志三级地址输出 — 启动日志从仅显示 localhost:端口 升级为完整三级地址输出:第一级本地(localhost:端口 + 127.0.0.1:端口)、第二级内网(本机所有 IPv4 地址 + 非 fe80:: 的 IPv6 地址,格式 ➜ 内网:)、第三级公网(通过 ipify/ifconfig.me/icanhazip 三个来源并发获取公网 IP 并去重,格式 ➜ 公网:)。获取超时 3 秒,任一来源成功即显示。架构文档 ARCHITECTURE.md 同步更新了完整的访问地址说明表格
  • Web UI 前端缩放按钮panel.html 的流程图页面(tech-tree)左上角新增缩放控件组(#zoom-ctrl):+ 放大(每次 scale + 0.15,上限 3.0)、 适应屏幕(重置 scale = 1.0)、 缩小(每次 scale - 0.15,下限 0.3)。仅在流程图页面显示(app.jsswitchPage() 中通过 classList.toggle('hidden') 控制),配置面板打开时自动隐藏(body.config-panel-open #zoom-ctrl { display: none }

🔑 AstrBot v4 平台重启认证升级与 Web 重置行为修正:

  • JWT 优先 + 密码降级两级认证 — Web 面板触发的插件重载和 AstrBot 重启操作,认证方式从单一密码登录升级为两级策略:第一优先级通过 dashboard 配置中的 jwt_secret 直接签发 HS256 JWT token,调用 AstrBot 仪表盘 REST API(重载:POST /api/plugin/reload,重启:POST /api/stat/restart-core);JWT 签发失败时自动降级为密码登录(POST /api/auth/login → 从 data.token 提取 token),兼容旧版 AstrBot v3。JWT 优先策略避免每次重启都需传输明文密码,同时绕过了某些 AstrBot v4 版本中密码登录接口的兼容性变更
  • Web 端重启状态轮询反馈web/server.py 中新增 GET /api/restart-status 接口,返回当前重启/重载操作的状态对象({type, status, message, timestamp},status 枚举:pendingin_progresssuccess / failed)。前端 app.js 在触发重启/重载后启动 2 秒间隔的轮询(最多 60 次 = 2 分钟),状态栏文案根据返回值动态更新(如"插件已重置,AstrBot 重启中...等待服务恢复..."),一旦轮询到服务器恢复(新进程启动)立即 location.reload() 刷新页面
  • 会话管理重置行为修正 — Web 面板「会话管理」中每张会话卡片上的「重置」按钮(调用 POST /api/commands/reset-here)的行为从"等同于聊天指令 gcp_reset_here"修正为仅清除运行时状态:调用插件实例的 _clear_session_runtime() 清除注意力数据、情绪追踪、概率状态、冷却计时、Smart 并发待合并注册记录和窗口缓冲残留,但不删除聊天记录文件不设置历史截止时间戳history_cutoff.json)。重置后自动触发插件重载(reload 模式)使清理立即生效。聊天指令 gcp_reset_here 保持原有行为(删文件 + 设截止戳)。两种重置方式的职责明确区分:Web 按钮 = 轻量运行时重置,聊天指令 = 完整历史清除
  • reset_hereclear_image_cache 的 reload 分支补全_handle_cmd_reset_here()_handle_cmd_clear_image_cache() 的 reload 模式分支此前缺失实际的重载触发调用(仅设置了 auth_mgr.mark_web_initiated_reload() 但未调用 _create_deferred_reload_task()),修复后补全该调用,reload 分支行为与 restart 分支一致
  • cutoff 日志补全gcp_reset_heregcp_reset 操作中的历史截止时间戳(history_cutoff.json)创建/更新操作现在输出明确的 INFO 日志([会话重置] 已设置历史截止戳: {session_id} → {cutoff_time}),方便排查跨重置操作的历史记录过滤问题

🔧 戳一戳消息后提示词注入修复:

  • 反戳后元数据注入不生效修复 — 修复戳一戳消息处理流程中一个隐蔽 Bug:当插件收到戳一戳消息并触发直接反戳(poke_reverse_on_poke_probability > 0,即随机反戳概率 > 0)后,旧版代码在发送反戳动作后通过 event.stop_event() + return 直接终止了整个消息处理链路(包括 main.py 中后续的 include_sender_infoinclude_timestamp 等元数据注入代码)。这导致:尽管用户在后端配置中开启了发送者信息注入和时间戳注入,但被反戳处理拦截的消息上这两类元数据完全不生效,保存到历史的戳一戳事件文本缺失发送者名称和时间戳。修复后,反戳动作改为通过内部的 poke_reply_in_progress 标记控制重复反戳,不再通过 stop_event() 中断链路,后续的元数据注入、消息缓存、历史保存等步骤正常执行

💾 gcp_clear_image_cache 旧版缓存兼容清理:

  • 旧版残留路径兼容清理web/server.py_resolve_image_cache_file() 方法优先返回当前主缓存文件路径(image_cache/descriptions.jsonl),若不存在则检测旧版残留路径(image_description_cache.json)。gcp_clear_image_cache 指令和 Web 面板的图片缓存清理按钮(POST /api/session/clear-image-cachePOST /api/commands/clear-image-cache)均通过 _clear_image_cache_storage() 调用此方法,确保从旧版本升级的用户不会留下无法通过正常清理流程移除的孤立缓存文件

🐛 其他细节修复:

  • proactive_system_prompt 变量名拆分遗漏修复proactive_chat_manager.py_save_proactive_to_history() 中,保存到历史的系统消息文本使用了不一致的变量引用路径:部分分支引用旧版 proactive_system_prompt(此变量在 v1.2.0 重构时已拆分为 proactive_marker + proactive_prompt),导致特定配置组合下(如重试场景 + 注意力信息注入)主动对话保存到历史的系统提示词拼接异常。修复后统一使用 proactive_marker + proactive_prompt 拼接
  • 内容过滤规则正则回溯优化content_filter.py 中部分 Range 过滤正则表达式(A*B 模式)在文本中包含大量重复标记边界符号(如 {{ }})时可能触发灾难性回溯的超时问题,修复后在各规则的 * 部分增加了非贪婪量词限定和原子组保护
  • Web 面板幽灵会话根治web/server.py_collect_runtime_sessions() 在收集会话 key 时新增 _SAFE_SESSION_RE 正则校验(拒绝空字符串、None、纯空白、含路径遍历字符的异常 key),从源头杜绝异常 key 进入会话列表。同时 message_cache_manager.pycache_message() 新增 chat_id 防御性校验,拒绝无效 chat_id 以避免产生幽灵缓存条目。双重防护确保前端的幽灵会话问题彻底根除(此前仅前端做空数据保护层)
  • 编辑保存直接覆盖源文件 — Web 面板文件管理中的在线编辑保存逻辑(POST /api/files/save)改为直接覆盖源文件而非创建带有时间戳后缀的备份副本,避免编辑后文件路径变化导致引用该文件的其他功能(如自定义提示词文件)失效

📚 文档全面补充与更新:

  • 关闭平台「只 @ 机器人是否触发等待」提示补充CONFIG_REFERENCE.md 的群聊等待窗口配置章节、ARCHITECTURE.md 的平台配置建议章节、_conf_schema.jsonenable_group_wait_window 配置 hint、README.md 的快速开始章节中均新增/强化了关闭平台 empty_mention_waiting 开关的提醒说明:平台的空 @ 等待是群级别拦截,会劫持任意用户的消息并人工插入 @bot 后重新入队,与本插件冲突且会导致认错发送者。使用本插件的等待窗口功能前必须先关闭平台侧的同名开关
  • 全部说明文档版本号更新README.mdCHANGELOG.mddocs/ARCHITECTURE.mddocs/CONFIG_REFERENCE.mddocs/MESSAGE_WORKFLOW.mddocs/PROJECT_STRUCTURE.mddocs/DESKTOP_COMPATIBILITY.md 中的所有版本引用从 V1.2.3.hotfix.1 更新为 V1.2.3.hotfix.2
  • 架构文档全面更新ARCHITECTURE.md 扩充了以下章节:第三方插件注入隔离机制(逐插件追踪 → handler wrapper → 具名标记 → 全字段覆盖的完整链路)、Web 面板安全机制(IPV6 全面适配、双栈自动化、速率窗口豁免)、AstrBot v4 重启认证流程(JWT 优先+密码降级)、Web 面板访问地址输出(本地/内网/公网三级)、消息元数据区机制、戳一戳双层标注架构、引用消息三段式格式
  • 配置项文档补充CONFIG_REFERENCE.md 新增/补充了 IPV6 兼容性说明(IP 名单、监听地址、安全机制)、empty_mention_waiting 关闭提醒、Web 面板各项新功能的行为说明
  • 消息工作流程文档更新MESSAGE_WORKFLOW.md 补充了消息元数据区注入流程、戳一戳双层标注机制、引用消息解析流程、工具调用多轮链路(正常完成 vs 异常终止的差异路径)
  • 项目结构文档更新PROJECT_STRUCTURE.md 更新了模块列表(新增 web/auth.pyweb/security.py 等之前未列出的模块)和版本信息

修改文件:

  • utils/reply_handler.py — 缓存友好的提示词拼接顺序重排,位置引用从"上方"改为"下方",覆盖/拼接模式同步适配,新增防回声约束
  • utils/proactive_chat_manager.py — 后台循环 Task 身份识别防双循环并发,普通回复时主动对话状态双重保险关闭,proactive_system_prompt 变量拆分修复,缓存友好的提示词拼接
  • utils/decision_ai.py — 缓存友好的提示词拼接顺序重排,位置引用从"上方"改为"下方",覆盖/拼接模式同步适配
  • utils/frequency_adjuster.py — 缓存友好的提示词拼接顺序重排
  • private_chat/private_chat_utils/private_chat_reply_handler.py — 缓存友好的提示词拼接顺序重排,覆盖/拼接模式同步适配,新增防回声约束
  • private_chat/private_chat_utils/private_chat_proactive_chat_manager.py — 同步主模块的主动对话防护和提示词优化
  • utils/image_handler.py — 新增视频/语音/文件三类媒体的提取、标记内联、缓存剥离前富化管线,纯语音/文件消息防丢弃
  • utils/message_processor.py — 消息格式重构为冒号前元数据区+冒号后用户内容区,时间戳/发送者信息/戳一戳事件统一注入元数据区,新增兜底名称检查,完整实现戳一戳持久化事件构建
  • utils/message_cache_manager.py — 新增 chat_id 防御性校验拒绝无效 key 防止幽灵会话
  • utils/message_cleaner.py — 过滤规则正则回溯优化,适配新引用消息格式(>>> 分隔符)
  • utils/content_filter.py — 过滤规则正则回溯优化(非贪婪量词+原子组保护)
  • utils/probability_manager.py — 概率过滤信息描述从"失败"纠正为"未通过"
  • utils/context_manager.py — 上下文构建适配元数据区格式,冒号前元数据区正确传递到 AI
  • utils/forward_message_parser.py — 转发消息发送者名称兜底检查
  • utils/system_prompt_rewriter.py — 平台提示词清洗适配新消息格式
  • main.py — 逐插件上下文追踪从 monkey-patch 升级为 handler wrapper 架构(_gcp_instrumented_call_event_hook_install_per_plugin_context_tracking),全字段追踪覆盖(system_prompt/extra_user_content_parts/image_urls/audio_urls),逐插件具名标记合并管道(_merge_per_plugin_prompt_injections / _merge_per_plugin_context_injections),戳一戳消息反戳后元数据注入修复(不再通过 stop_event() 中断链路),多轮工具调用 LLM_RESULT 误判修复(on_decorating_result 不再强制完成 LLM_RESULT),工具调用异常兜底保存(_finalize_bot_reply_save),反戳后消息保存/缓存更新/名称兜底全覆盖,Smart 并发批量名称兜底
  • web/server.py — AstrBot v4 重启认证 JWT 优先+密码降级(_do_deferred_reload / _do_deferred_restart),重启状态轮询接口(GET /api/restart-status),会话管理重置行为修正(仅清运行时/不删文件/不设截止戳),reset_hereclear_image_cache 的 reload 分支补全,Web 面板启动日志三级地址输出(本地/内网/公网),localhost 归一化为 127.0.0.1,客户端 IP 规范化管道(_get_client_ip + _normalize_ip),双栈自动启用,幽灵会话根源修复(_SAFE_SESSION_RE 校验),封禁原因 128 字符截断,速率窗口自动刷新豁免(X-GCP-Auto-Refresh 头检测)
  • web/security.py — IP 规范化方法(_normalize_ip),IP 合法性校验与边界警告(_validate_ip_list),速率限制自动刷新豁免(check_authenticated_rate 新增 is_auto_refresh 参数),全安全机制 IPv6 适配
  • web/auth.py — IP 规范化比较(登录、封禁等场景的 IP 匹配)
  • web/templates/panel.html — 图表自动刷新开关 UI(含绿色圆点指示器),缩放按钮控件(#zoom-ctrl),悬浮窗拖拽手柄(prompt-floater-resize-handle),访问日志无自动刷新提示文字
  • web/static/js/app.js — 心跳状态面板完整重构(自动/手动刷新双机制、Leader 广播+Follower 接收、_loadHeartbeatStatus 首次加载兜底、增量更新 DOM),主题切换触发图表立即重绘,重启状态轮询反馈,悬浮窗拖拽超屏修复+移动端触摸支持,封禁原因 128 字符限制+计数器,缩放按钮页面切换显隐控制,全页面手动刷新+toast 反馈,插件重启期间自动刷新静默容错
  • web/static/js/session-mgr.js — 会话列表 3 秒自动刷新(进出详情自动暂停/恢复),编辑模式禁刷新,聊天记录内容比对增量更新+回退全量重建逻辑,幽灵会话计数与清理
  • web/static/js/charts.js — 柱状图始终重绘移除主题色缓存守卫,概率柱状图统一红色,无会话手动刷新去守卫,3 秒自动刷新开关
  • web/static/js/api.jsX-GCP-Auto-Refresh 请求头自动注入,verify() 支持 options 参数,心跳请求不计入速率窗口
  • web/static/js/flow-data.js — 概率过滤节点标签从"概率过滤失败"改为"概率未通过"
  • web/static/js/tech-tree.js — 流程图缩放控件交互逻辑
  • web/static/js/prompt-data.js — 第三方注入标记预览同步更新为具名配对格式
  • web/static/css/main.css — 悬浮窗默认宽度约束(min/max-width),移动端拖拽手柄样式,访问日志附注列 auto 列宽+截断溢出,封禁列表短列 nowrap+原因列自动换行,自动刷新开关样式(.auto-refresh-toggle),无自动刷新提示文字样式(.log-refresh-hint
  • web/static/css/tech-tree.css — 缩放按钮样式(桌面/移动端适配),悬浮窗 resize handle 样式(桌面端隐藏/移动端显示大尺寸手柄),配置面板打开时缩放按钮隐藏
  • _conf_schema.json — 配置项 hint 全面修订(IPV6 地址说明、IP 名单边界警告、empty_mention_waiting 关闭提醒、概率过滤用语纠正),新增 Web 面板相关配置项 hint 补充
  • metadata.yaml — 更新版本号到 V1.2.3.hotfix.2,更新插件简介
  • README.md — 更新版本号、更新亮点章节、更新日志章节
  • CHANGELOG.md — 更新为 V1.2.3.hotfix.2 版本更新记录
  • docs/ARCHITECTURE.md — 全面扩充第三方插件注入隔离、Web 安全机制、AstrBot v4 兼容性、消息元数据区、Web 面板访问地址等章节
  • docs/CONFIG_REFERENCE.md — 补充 IPV6 兼容性说明、empty_mention_waiting 关闭提醒、Web 面板各功能行为说明
  • docs/MESSAGE_WORKFLOW.md — 补充消息元数据区注入流程、戳一戳双层标注、引用消息格式、工具调用多轮链路
  • docs/PROJECT_STRUCTURE.md — 更新模块列表和版本信息
  • docs/DESKTOP_COMPATIBILITY.md — 更新版本兼容性表格
  • 所有 Python 模块 — 统一更新文件头版本号到 V1.2.3.hotfix.2

📋 查看完整更新日志 →


🤝 贡献与反馈

如遇问题请开启 enable_debug_log 获取详细日志后在 GitHub Issues 提交,欢迎 Pull Request!

也欢迎加入 QQ群 1021544792 进行交流、反馈Bug和功能建议!


📜 许可证

本项目采用 AGPL-3.0 License 开源协议。


🙏 致谢

灵感来源

本插件的开发从以下开源项目中获得了灵感,特此感谢。我们并未直接使用其代码,但借鉴了其优秀的功能设计:

记忆插件

本插件支持两种记忆插件,优秀的记忆系统让AI的判断和回复更加智能,特此感谢:

其他


👤 作者

Him666233@Him666233


⭐ Star History

如果这个插件对你有帮助,请给个Star支持一下!

Star History Chart


Made with ❤️ by Him666233

About

一个为AstrBot平台提供的以AI读空气为核心的群聊增强插件,让你的Bot更懂氛围、更自然地参与群聊互动

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors