fix(channelbridge): 冷避优先于「@她必回」——群成员也能让她少说话
M18(主人 2026-10-14 裁决「给」)。病灶是**顺序**:`shouldRespond` 把 `ruleLightJudge`(指向她本人 / 高价值关键词)排在参与度引擎之前,@她的消息 在规则层就 return true,永远走不到 `engageDecision` 的冷避判定——群成员说 「少说点」只换来一句口头答应,行为零变化(2026-10-14 00:27 群 531082168 报障)。 - light.go:新增冷避闸位次 —— 非主人**群**消息在廉价规则之前先过 `coldShoulderGate`,命中负面态度即进 COOLDOWN、冷却期内一律静默(仍登记)。 边界:私聊不受影响(冷避是群机制)、owner 车道更早分岔不受影响、 与是否装配参与度引擎无关。shouldRespond 的判定顺序写进函数注释。 - engage.go:把冷避判据抽成唯一实现 `coldShoulderLocked`(engageDecision 仍调用 它,作纵深防御),命中时补一条带 source 的 INFO(群 / 发送者 / 冷却到何时)。 - engage.go 词表:依真机原话补「减少文本输出」(覆盖「减少文本输出量」)与 「文本输出调到最少」;刻意不取「减少 / 输出 / 最少」等短泛词(子串匹配会误伤)。 - 测试:新增 engage_coldshoulder_test.go(主断言修前红/修后绿、登记进上下文的 端到端守卫、私聊与 owner 边界护栏、词表误伤护栏、INFO 可见性); engage_test.go 更新旧口径「@ 打断冷却」为「@ 不得作废冷避」。 验收:go build ./... + go vet ./... + go test -count=1 ./... 全绿(windows 本机 与 darwin/arm64 交叉编译均通过);channelbridge / channel / cmd/cyrene 单独跑亦绿。
This commit is contained in:
1 parent
6432088586
commit
fe53e029ea
4 files changed
+499
-24
No files matched your search
@@ -174,12 +174,19 @@ func isStrangerPrivate(sess session.Session) bool {
|
||||
|
||||
// shouldRespond 实现入站消息的最小打扰分级
|
||||
// (设计/12 §6 策略一/二 + design/18 §2/§4/§5/§11)。它返回该消息
|
||||
// 应驱动完整 agent 循环并回复,还是只登记并静默。
|
||||
// **主人消息**由此处的 owner 车道分支处理(design/18 §11「乙 = C」):
|
||||
// 主人私聊恒回;主人群消息按「指向她本人」的结构化判据与每群旋钮决定说不说
|
||||
// (见 ownerlane.go);因此主人私聊与主人在群里的 @/@全体仍必回,
|
||||
// 而主人群里不对她说的消息改为**进上下文不回**。sess 是
|
||||
// 该消息解析出的隔离群聊/陌生人会话绑定,使参与度
|
||||
// 应驱动完整 agent 循环并回复,还是只登记并静默。判定顺序(M18 后的**权威顺序**):
|
||||
//
|
||||
// ① owner 车道(`actor.IsOwner()`,design/18 §11「乙 = C」):主人私聊恒回;
|
||||
// 主人群消息按「指向她本人」的结构化判据与每群旋钮决定说不说(见 ownerlane.go)——
|
||||
// 冷避不适用于主人,主人的 @/@全体仍必回。
|
||||
// ② 平台/系统噪声 → 只登记。
|
||||
// ③ 陌生人私聊 → 正常聊天(唯一闸门是流控)。
|
||||
// ④ **非主人群聊:冷避闸**(design/18 §5,M18 新增位次)——负面态度 → COOLDOWN、
|
||||
// 冷却期内一律静默;**优先于第 ⑤ 步的「@她必回」**,与是否装配参与度引擎无关。
|
||||
// ⑤ 廉价规则:指向她本人 / 提及主人显示名 / 高价值关键词 → 必回。
|
||||
// ⑥ 规则无结论 → 参与度引擎(design/18)或旧轻量判定车道(design/12 §6)。
|
||||
//
|
||||
// sess 是该消息解析出的隔离群聊/陌生人会话绑定,使参与度
|
||||
// 引擎探测时能读到群的近期上下文;a 是收到该消息的账号适配器,
|
||||
// 用于取该账号的流控闸门(陌生人私聊的强制限流)。
|
||||
func (b *Bridge) shouldRespond(ctx context.Context, msg adapter.UnifiedMessage, actor adapter.Actor, sess session.Session, a adapter.PlatformAdapter) (bool, string) {
|
||||
@@ -219,6 +226,21 @@ func (b *Bridge) shouldRespond(ctx context.Context, msg adapter.UnifiedMessage,
|
||||
// 「参与度触发 / 概率」那一档(未触发则只登记)。**安静时段只作为信号**(inQuiet)
|
||||
// 继续往下传,规则层不再因为它静默(裁决②)。
|
||||
inQuiet := b.inQuietHours(b.now())
|
||||
|
||||
// design/18 §5 冷避**先于**「@她必回」(M18,主人 2026-10-14 裁决「给」:
|
||||
// 群成员也能让她少说话):非主人**群**消息先过冷避闸 —— 命中负面态度就进
|
||||
// COOLDOWN,冷却期内一律静默(两者都只登记、不进循环)。顺序上必须排在下一条
|
||||
// 规则判定**之前**,否则 @她 / 高价值关键词会在规则层直接 return true,
|
||||
// 群成员刚说的「少说点」被随后的任何一次 @ 立刻作废(2026-10-14 报障病灶)。
|
||||
//
|
||||
// 闸的适用面在冷避闸自己身上写死:只对群聊(私聊与 owner 车道在更早处已分岔)
|
||||
// 且与是否装配参与度引擎无关 —— 旧轻量判定车道的部署同样得到这个顺序。
|
||||
if sess.IsGroup {
|
||||
if quiet, reason := b.coldShoulderGate(msg, actor); quiet {
|
||||
return false, reason
|
||||
}
|
||||
}
|
||||
|
||||
if b.ruleLightJudge(msg) == verdictRespond {
|
||||
return true, "rule signal: worth responding"
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user