refactor ai_auto_response plugin architecture

This commit is contained in:
liuwei
2026-04-09 17:46:30 +08:00
parent cc65378544
commit f580c69736
39 changed files with 4347 additions and 1979 deletions

View File

@@ -0,0 +1,248 @@
# 小牛统一响应决策流设计
当前实现备注:线程策略已废除,现网决策流不再选择 thread只围绕“当前发言”处理一个话题。
文中出现的 `selected_thread_id``thread_summary` 等字段属于历史设计残留,不再作为实现目标。
## 1. 目标
统一响应决策流的目标,是把当前分散在:
- trigger
- planner
- flow
- cooldown
- 本地防御
- LLM should_reply
这些地方的判断,收敛成一条稳定、可观察、可调试的主链路。
---
## 2. 当前问题
当前系统的主要问题不是没有决策层,而是决策点太多。
结果就是:
- 某些消息还没进模型就被提前跳过
- 某些消息是否回复很难解释清楚
- 日志中虽然有很多阶段,但决策责任分散
- 后续优化容易陷入“哪里有问题就补一个规则”
---
## 3. V2 决策流原则
V2 应坚持两条原则:
### 3.1 本地只做硬边界和成本控制
例如:
- 自己发的消息不处理
- 非群消息不处理
- prompt attack 静默忽略
- 非 @ 编码代劳静默跳过
- 限流
- 去重
### 3.2 模型负责高语境的人类式判断
例如:
- 当前接哪条线
- 这次是否值得回
- 应该用什么回复强度
- 最终回复内容
---
## 4. 统一决策流分层
建议将决策流分成五步。
### 步骤 1硬过滤
如果命中以下任意条件,直接结束:
- 非群消息
- 来自自己
- 空内容
- 明显攻击
- 非 @ 编码代劳
- 重复消息
### 步骤 2轻特征识别
提取轻量信息:
- 是否问句
- 是否引用
- 是否明显对机器人说
- 是否技术倾向
- 是否延续句
这一步只做信号准备,不做最终决策。
### 步骤 3线程和记忆装配
准备:
- 候选线程
- 当前成员记忆
- 关系记忆
- 群事实记忆
- 向量候选
### 步骤 4本地粗筛
本地只回答一个问题:
`这条消息值不值得送模型?`
如果不值得,直接跳过。
如果值得,进入模型。
### 步骤 5单次模型统一决策
模型输出结构化结果:
- `selected_thread_id`
- `thread_summary`
- `should_reply`
- `reply_mode`
- `style_profile`
- `reply`
---
## 5. 为什么不建议完全本地决策
本地规则有三个优点:
-
- 便宜
- 可控
但它最大的问题是:
- 很难像人一样判断复杂语境
例如:
- “没有 token 了,这日子怎么过啊”
- “真的假的”
- “那你这个就不对了”
这些句子在群聊里可能是:
- 问题
- 吐槽
- 接熟人话
- 等人接梗
本地规则很难稳定分辨。
---
## 6. 为什么也不建议完全模型决策
如果每条消息都打给模型,会带来:
- 成本问题
- 延迟问题
- 稳定性问题
- 高噪声场景下无意义请求增多
所以最合理的方式是:
`本地粗筛 + 模型统一判断`
---
## 7. 模型输出格式建议
建议固定为结构化输出,而不是纯文本。
至少包括:
- `should_reply`
- `selected_thread_id`
- `thread_summary`
- `reply_mode`
- `reply`
可选增加:
- `style_heat`
- `style_sharpness`
- `style_density`
- `reason`
这样本地不仅能发回复,还能记录清晰日志。
---
## 8. reply_mode 的职责
建议 `reply_mode` 只负责“输出强度”,不再承担是否回复的责任。
例如:
- `social_short`
- `qa_fast`
- `qa_with_context`
这样职责更清晰:
- `should_reply`
决定回不回
- `reply_mode`
决定怎么回
---
## 9. 日志设计建议
统一决策流必须可观测。
建议重点记录:
- 消息是否被硬过滤
- 是否进入模型
- 当前候选线程数量
- 最终选中的线程
- `should_reply`
- `reply_mode`
- 最终回复文本预览
最重要的是:
要能清楚看出来“没回是因为本地挡了,还是因为模型判断不回”。
---
## 10. 决策流的阶段性改造顺序
### 第一阶段
- 统一日志出口
- 区分本地 skip 与 LLM no reply
### 第二阶段
- 明确本地粗筛边界
- 减少过度的本地场景式跳过
### 第三阶段
- 所有拟人化相关判断逐步收敛到模型输出
---
## 11. 最终原则
统一决策流的最终原则是:
`安全和成本由系统守住,像不像真人地该不该开口,尽量交给统一的高语境决策层。`

View File

@@ -0,0 +1,276 @@
# 小牛群事实与群文化记忆设计
## 1. 目标
群事实与群文化记忆层,解决的是“小牛为什么不像一个长期混群的人”这个问题里的另一半。
它关注的不是单个成员,也不是成员之间的关系,而是:
- 这个群长期在聊什么
- 这个群有什么稳定背景
- 这个群有哪些固定梗
- 这个群有哪些默认共识
- 这个群里哪些角色长期存在
---
## 2. 群事实记忆和群画像的区别
### 2.1 群画像
当前已有的群画像更偏整体风格:
- 技术群还是闲聊群
- 幽默强度
- 嘴硬程度
- 领域偏置
### 2.2 群事实记忆
群事实记忆更偏具体内容:
- 这个群长期在聊 OpenClaw
- 群里经常吐槽 token
- 某人是固定答疑位
- 某个梗反复出现
- 某件项目背景大家默认知道
可以理解为:
- 群画像解决“这个群是什么味道”
- 群事实记忆解决“这个群长期记得什么”
---
## 3. 群事实记忆的内容范围
建议先关注四类群事实。
### 3.1 长期主题事实
例如:
- 这个群长期在聊机器人、插件、部署
- 这个群长期在聊 OpenClaw 接入
- 这个群长期在聊 Dota 和比赛理解
### 3.2 群内角色事实
例如:
- 谁是固定答疑位
- 谁是整活位
- 谁是项目推进位
- 谁是管理/组织位
### 3.3 稳定梗/稳定共识
例如:
- 群里常提某个梗
- 某类吐槽反复出现
- 某个约定俗成的说法大家都懂
### 3.4 项目/背景事实
例如:
- 这个群默认在用哪套项目
- 当前长期卡在哪类问题
- 群里默认哪些背景不用每次重讲
---
## 4. 群事实的来源
### 4.1 最近中期消息样本
建议用:
- 最近 48 小时
- 不足时回看 7 天
作用:
- 发现当前正在固化的群事实
### 4.2 历史消息摘要
例如当前已有的:
- `t_message_summary`
作用:
- 让群事实不只看最近一两天
- 避免全部依赖原始消息
### 4.3 线程摘要
如果某类线程反复出现,就有资格上升为群事实候选。
例如:
- 几天内重复出现“token 不够”
- 反复出现“OpenClaw 接入”
### 4.4 人工配置
某些群事实可以人工固化,例如:
- 这个群就是 OpenClaw 群
- 这个群就是机器人群
人工配置应具有更高优先级。
---
## 5. 群事实的提炼方式
### 5.1 不建议全量逐条保存
群事实不是把群聊天记录无限堆起来。
建议方式:
- 从消息中提取候选事实
- 对候选事实做去重、聚合、压缩
- 保留“长期有效、反复出现”的事实
### 5.2 群事实候选形成
一个候选群事实通常来自:
- 高频出现主题
- 反复出现的人物角色
- 持续多天的固定抱怨/固定梗
- 项目背景类信息
### 5.3 群事实稳定条件
可以作为群事实写入的内容,建议满足至少一个:
- 连续多天出现
- 多人反复提及
- 在线程层中被多次沉淀
- 与群配置知识域高度一致
---
## 6. 群事实的数据结构建议
建议每条群事实至少包含:
- `fact_id`
- `chatroom_id`
- `fact_type`
- `summary_text`
- `topic_tags`
- `related_members`
- `confidence`
- `stability`
- `evidence_count`
- `created_at`
- `last_seen_at`
### 6.1 fact_type 建议
- `group_theme`
- `group_role`
- `group_joke`
- `project_background`
- `shared_context`
### 6.2 稳定性建议
- `high`
非常稳定,不容易变
- `medium`
中期稳定
- `low`
可能是阶段性热词
---
## 7. 群事实如何用于回复
### 7.1 正向用途
- 让小牛更自然地理解当前群的默认语境
- 避免每次都从零推断群背景
- 让小牛更像“本来就在这个群里”
### 7.2 不能做的事
群事实不应该:
- 被原样念出来
- 被用来强行显摆“我知道你们以前聊过”
- 在无关话题里强插
群事实最好的使用方式是:
作为理解背景的隐性支撑,而不是显式播报。
---
## 8. 群事实与线程/关系的关系
三者关系如下:
- 线程层
管现场
- 关系层
管谁和谁
- 群事实层
管这个群长期记得什么
三层叠加后,小牛的群友感会明显提升。
---
## 9. 与统一记忆权重体系的关系
群事实记忆也必须接入权重机制。
不是什么群事实都能在所有场景使用。
例如:
- “这个群长期在聊 OpenClaw”
在项目/部署场景权重高
- 在“今晚吃什么”场景权重应很低
因此群事实也应具备:
- `applicable_domains`
- `invalid_domains`
- `confidence`
- `stability`
---
## 10. 最小实施路线
### 第一阶段
- 复用现有群摘要
- 先抽长期主题和群角色
### 第二阶段
- 从线程摘要中提取群事实候选
- 形成群事实池
### 第三阶段
- 让群事实进入上下文构建
- 接入统一记忆权重体系
---
## 11. 最终原则
群事实记忆的最终原则是:
`让小牛不是“看到当前消息才临时理解这个群”,而是本来就生活在这个群的长期背景里。`

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,281 @@
# 小牛群关系记忆设计
## 1. 目标
关系记忆层的目标,是让小牛从“记得每个人是什么样”,升级成“记得群里谁和谁是什么关系”。
这层能力决定小牛能不能真正表现出“混群很久”的熟悉感。
---
## 2. 为什么成员画像还不够
当前成员画像解决的是:
- 这个人平时关注什么
- 这个人说话什么风格
- 这个人适合怎么回
但群聊里真正强拟人感的信息还有另一半:
- 这个人经常接谁的话
- 这个人和谁常互怼
- 这个人通常找谁求助
- 哪两个人经常聊某类问题
- 哪几个人是一个小圈子
如果没有这层关系理解,小牛会:
- 记得“这个人懂技术”
- 但不记得“这个人每次都会找谁问”
这就是“记人但不记群”的根本原因。
---
## 3. 关系记忆的核心对象
关系记忆不是抽象社交图,而是服务于群聊回复的实用层。
建议先关注以下几类关系:
- `often_reply_to`
经常接对方的话
- `often_ask_help_from`
经常向对方求助
- `often_tease`
经常调侃/互损
- `project_partner`
经常围绕同项目讨论
- `stable_pairing`
群里固定搭子、固定同屏出现
- `familiar_friend`
熟人感强
- `group_role_dependency`
在群里有明显角色依赖,如答疑位、管理位
---
## 4. 建议的数据结构
建议新增结构化关系表,例如:
`t_group_member_relation`
推荐字段:
- `chatroom_id`
- `source_wxid`
- `target_wxid`
- `relation_type`
- `relation_strength`
- `topic_tags`
- `summary_text`
- `confidence`
- `evidence_count`
- `created_at`
- `last_observed_at`
- `meta_json`
### 4.1 source 和 target 的含义
关系建议先做有向边。
例如:
- `A -> B = often_ask_help_from`
- `A -> B = often_reply_to`
后续再在视图层聚合出双向关系。
### 4.2 relation_strength
建议用连续值,例如 `0.0 ~ 1.0`,而不是纯枚举。
这样便于:
- 关系渐进增强
- 长时间不互动时衰减
---
## 5. 关系信号来源
初期不用追求复杂 NLP可以先做“多证据累计”。
### 5.1 直接结构信号
- A 是否频繁紧跟 B 发言
- A 是否频繁引用 B
- A 是否频繁 @ B
- A/B 是否持续在同一线程共同出现
### 5.2 主题共现信号
- A 和 B 是否长期围绕相同话题高频互动
- 是否在特定域里重复同屏
例如:
- 总是在 OpenClaw 线程里一起出现
- 总是在游戏线程里互相接话
### 5.3 语气信号
这类信号可以后期接入:
- A 对 B 是偏请教、偏吐槽、偏玩笑还是偏正式
- 双方是否存在稳定互损风格
### 5.4 模型抽取信号
当某段线程比较明显时,可以让模型输出轻量关系摘要:
- “A 常向 B 问部署问题”
- “C 和 D 经常互相调侃”
模型抽取不直接当事实,而是作为候选证据。
---
## 6. 关系的形成与衰减
### 6.1 关系形成
关系不是一次产生,而是连续观测形成。
建议:
- 单次证据只做弱候选
- 多次观测后逐渐升权
- 达到阈值后进入稳定关系
### 6.2 关系衰减
如果长时间没有互动,关系强度应衰减。
但不同关系类型衰减速度应不同:
- `often_reply_to`
衰减较快
- `project_partner`
中等
- `familiar_friend`
衰减较慢
### 6.3 关系冲突
如果系统收到了互相冲突的关系证据,不应该立刻覆盖。
建议:
- 保留历史关系
- 用新证据逐步调整强度
- 保留 `confidence`
---
## 7. 关系记忆如何进入回复
关系记忆不是为了“把群里八卦都说出来”,而是为了让小牛的反应更自然。
### 7.1 正向用途
- 当前如果是 A 在问,且历史上 A 常找 B 求助
小牛可以更自然地判断这是“接技术线”还是“接熟人线”
- 如果 B 平时总和 A 互损
小牛可以适度理解当前语气不一定是冲突,而是熟人调侃
- 如果某两个人总在某个项目线程一起出现
小牛更容易把当前消息归到对的线程
### 7.2 负向用途
关系记忆不应该让小牛:
- 直接爆出“我知道你俩很熟”
- 原样复述长期观察结果
- 主动暴露系统在追踪关系
关系记忆的使用方式应该是:
像真人本来就“知道这些人平时怎么互动”,而不是像数据库查询结果。
---
## 8. 与线程层的关系
线程层解决“现在在聊哪条线”,关系层解决“这条线通常是谁和谁在聊,以及他们平时是什么关系”。
两者配合后可以显著提升:
- 线程归属准确度
- 回复语气自然度
- 群内熟悉感
例如:
- 当前线程是 OpenClaw 部署线
- 历史关系显示 A 总向 B 求助
- 当前 A 发一句“那这个咋整”
系统就更容易知道:
- 这是延续旧技术线
- 不是泛问
- 也不是闲聊
---
## 9. 关系记忆与权重机制
关系记忆也应接入统一记忆权重体系。
建议基础字段:
- `memory_type = relation_fact`
- `entity_targets = [source_wxid, target_wxid]`
- `topic_tags`
- `applicable_domains`
- `confidence`
- `stability`
在查询时,若当前 `query_profile` 属于关系相关或线程延续相关场景,则关系记忆升权。
例如:
- 当前在问“他最近又找谁搞 OpenClaw”
关系记忆权重高
- 当前在聊“晚上吃啥”
关系记忆权重应低
---
## 10. 最小实施路线
### 第一阶段
- 新增关系表
- 记录最基础的互动边
### 第二阶段
- 将线程共现、引用、跟随发言作为关系证据
- 形成初版 `relation_strength`
### 第三阶段
- 生成简短关系摘要
- 让关系记忆参与回复上下文构建
### 第四阶段
- 接入统一记忆权重体系
- 接入向量召回或摘要召回
---
## 11. 最终原则
关系记忆的最终原则是:
`不是让小牛“知道群里八卦”,而是让小牛像一个本来就在这个群里混了很久的人。`