Imported from SugarMGP/MumuBot (
internal/agent/AGENTS.md). Install upstream withnpx skills add SugarMGP/MumuBot --skill agent. Copyright stays with the author.
AGENTS
本目录负责 MumuBot 的运行编排:把 OneBot 消息、话题工作记忆、长期记忆、学习系统、工具调用和模型思考循环连在一起。
入口与职责
react_agent.go:Agent 结构体、依赖创建、启动、停止和运行态查询。message.go:收到群消息后的主处理入口,包含同步解析、消息持久化、展示内容生成、消息缓冲和思考调度。sticker.go:从合适的图片消息中收集表情包。think.go:ReAct(观察、思考、行动)循环,决定发言、沉默或调用工具。context.go:为模型组装上下文,包含图片、视频、话题、记忆和群聊片段。shutdown是统一清理入口,新增资源时要接入这里,避免只在某条启动失败路径里清理。
编排边界
- agent 只做编排,不把话题归属、长期记忆入库、学习提取等核心逻辑塞回本目录。
- 收到消息后先持久化消息日志;空原文同时落为
no_topic,其他话题归属异步执行。后续链路按数据库真实状态推进,不等待或伪造话题结果。 - 给模型看的聊天上下文可以使用展示文本;检索、学习、摘要等语义输入必须从原始文本链路传递。
- 统一 Memory Agent 的启动由 agent 负责;后台直接读取单群整理水位之后的原文,话题模块不再创建模型或后台 worker。
- 工具调用上下文分别保存固定快照上界和本轮最后一条非自身消息:查询工具只能使用前者,证据写入只能使用后者,不得用一个通用消息 ID 混合两种语义。
- ReAct 只执行一次主
Generate,不拆 Planner/Replyer,也不增加回复前模型分类;普通触发由概率门控控制调用频率,进入 ReAct 后由stayQuiet决定是否保持沉默。 - 强提及、点名和回复机器人在群内没有 think 运行时直接进入 ReAct;普通触发保留概率门控。每群只允许一个 think 运行,运行期间的新触发由
ConcurrencyManager直接忽略,不创建 rerun;消息继续保存在缓冲区和数据库中,等待后续正常调度读取。 - think 使用固定消息快照;主 ReAct 失败时,只有工具已确认产生副作用才能推进已读水位。
- 话题和主动长期记忆检索必须共用固定快照中的原始消息混合查询;Agent 只负责选择已读尾部与当前批次,embedding、文本召回阈值和本群/跨群策略归各自模块管理。
onMessage的消息内容链路为同步:回复信息补全、合并转发内容解析、视觉解析、工具名屏蔽与展示内容生成都在消息回调内完成;标已读、成员画像更新只在消息落库成功且非机器人自身消息后执行。- 事件入口按到达顺序为每条群事件分配群内序号;解析(含视觉)全并行,完成后消息、戳一戳和撤回统一携带序号投入每群提交队列,提交协程按序号重排后顺序执行落库、撤回处理、入缓冲和思考调度;解析失败、无效事件和未启用群通过跳过项消费序号,保证重排器不会死等;提交队列满时背压,不静默丢弃。
- 撤回与同群消息共享序号流,按到达顺序在消息之后执行;撤回执行时原消息尚未落库(重连窗口、上游丢失或事件乱序)则登记有限 TTL 的待补偿记录,消息落库后补记撤回并同步缓冲展示,定期清理过期记录。
- 提交重排等待队列有上限,超限时丢弃等待队列中最接近水位的项并把水位推进越过它,被越过的序号(含仍在解析中的)到达时自然跳过,不记录、不留下永久缺口、内存有界;已等待项在水位到达后仍按序提交。
- 停机顺序:先停止 OneBot 接收并等待所有已分发事件处理完成,再取消 Agent 上下文并停止思考调度(等待所有 think 退出,此后不再有本地发言等生产者),最后关闭提交队列排空剩余消息;事件 goroutine、提交协程和后台任务都在等待范围内,避免 WaitGroup 竞态与 send on closed channel。排空阶段使用缓存的真实机器人账号识别自身消息。
- 消息思考防抖使用
GroupMessage.ReceivedAt作为起点,解析完成后按剩余窗口调度;解析耗时超过窗口时立即调度。 speak每次只发送一条消息,reply_to和mentions单条独立设置;多条内容通过多次调用表达。- 发言、戳一戳、贴表情、撤回和表情包只在远程 API 成功后标记已执行;只读工具和无法确认副作用的 MCP 工具不能推进失败快照。
修改注意
- 同一函数内重复使用配置、bot 自身 ID、消息缓冲区等值时,先取局部变量复用。
- 初始化失败路径和正常退出路径要保持一致,新增后台 goroutine 时要确认退出信号和日志。
- Agent 停机先让 OneBot 停止接收并排空已入队消息,再取消 Agent 上下文和其余后台任务。
- 停机时必须等待后台慢操作任务退出后再关闭其使用的缓存、话题管理器和 MCP 资源。
- 不要在思考循环中新增启发式兜底来保证“一定有回复”;保持沉默也是有效结果。