feat(channels): 陌生人私聊正常聊天(跳概率门)+ 强制流控 6条/分与回合槽位 + 安静时段不再硬静默 + 受限车道边界行前置
- 陌生人私聊:不再走「值不值得回」的概率门,唯一闸门 = 每发送者 6 条/分滑窗 + 同会话 1 个在跑回合 - 被限流只登记不回,且留带 source 的可见告警(不静默) - 安静时段在回复侧只作信号(规则层不再静默),群聊取消夜间静默 - 锁定流控常量:FlowDirectDefault 加字面量钉桩测试(放大它 = 静默关流控,且会让额度循环跑百万轮)
This commit is contained in:
1 parent
c6f5c3fea0
commit
7ae4298871
10 files changed
+654
-118
No files matched your search
@@ -181,17 +181,18 @@ func (b *Bridge) processFrom(ctx context.Context, msg adapter.UnifiedMessage, a
|
||||
"session", sess.SessionID, "actor_role", sess.ActorRole,
|
||||
"env", sess.Env(), "mem_writable", sess.MemWritable)
|
||||
|
||||
// design/12 §6 策略一/二/五:面向非主人消息的最小打扰闸门。
|
||||
// 被廉价轻量判定认为不值得回复的非主人群聊/陌生人
|
||||
// 消息,只登记到其隔离会话日志并静默——绝不
|
||||
// 驱动完整 agent 循环。主人消息绝不在此被拦,因此
|
||||
// 主人私聊与主人在群里的 @/高价值回复不受影响。
|
||||
// design/12 §6 策略一/二:面向非主人消息的最小打扰闸门。
|
||||
// 被廉价轻量判定认为不值得回复的非主人**群聊**消息,只登记到
|
||||
// 其隔离会话日志并静默——绝不驱动完整 agent 循环;**陌生人私聊**则
|
||||
// 一律走完整回合(裁决①,见 shouldRespond),只受流控约束。
|
||||
// 主人消息绝不在此被拦,因此主人私聊与主人在群里的
|
||||
// @/高价值回复不受影响。
|
||||
//
|
||||
// 由「传入前审查」放行的系统通知(notice.Applicable)不在此列:它们已由策略一
|
||||
// 的归一化/分类**终局判定**(高价值升级真会话、其余限定注入),若再走这道面向
|
||||
// 聊天消息的闸门,actor=system 会在 isLowValueEvent 处被第二次静默掉。
|
||||
if !actor.IsOwner() && !notice.Applicable {
|
||||
if ok, reason := b.shouldRespond(ctx, msg, actor, sess); !ok {
|
||||
if ok, reason := b.shouldRespond(ctx, msg, actor, sess, a); !ok {
|
||||
b.registerSilenced(ctx, msg, actor, sess, a)
|
||||
b.log.Debug("non-owner message silenced (minimal disturbance)",
|
||||
"platform", msg.Platform, "channel", msg.ChannelID,
|
||||
@@ -200,6 +201,21 @@ func (b *Bridge) processFrom(ctx context.Context, msg adapter.UnifiedMessage, a
|
||||
}
|
||||
}
|
||||
|
||||
// 裁决①的第二个流控(主人 2026-10-05):陌生人私聊虽然一律回答,但
|
||||
// **同一发送者同时最多 1 个在跑的回合**。槽位复用同一个 flowgate 的
|
||||
// 会话计数(AcquireTurn/ReleaseTurn,键口径与限流一致);已有回合在跑时
|
||||
// 这一条只登记、不回,并留可见告警 —— 一个陌生人无法用并发消息占满循环。
|
||||
if isStrangerPrivate(sess) {
|
||||
if gate := b.gateFor(a); gate != nil {
|
||||
if !gate.AcquireTurn(msg) {
|
||||
b.registerThrottled(ctx, msg, actor, sess, a,
|
||||
"stranger private: a turn is already running for this sender")
|
||||
return
|
||||
}
|
||||
defer gate.ReleaseTurn(msg)
|
||||
}
|
||||
}
|
||||
|
||||
b.runInboundTurn(ctx, msg, a, text, actor, sess)
|
||||
}
|
||||
|
||||
@@ -397,7 +413,8 @@ func deviceIDFor(msg adapter.UnifiedMessage) string {
|
||||
// RoleUser 消息**上 —— 用户内容只进用户角色消息是项目红线。
|
||||
//
|
||||
// 历史转录**不在本函数里**:它由 seedTurnTranscript(transcript.go)在本函数返回之后
|
||||
// 前置到列表最前面,与网关编排器的播种同序(转录在前、本次消息在后)。因此本函数只负责
|
||||
// 插入到列表中(主人私聊前置在最前;受限车道插在**最前的系统框架行之后**,
|
||||
// 于是来源行 + 第三方边界仍在最前、转录居中、当次消息在最后)。因此本函数只负责
|
||||
// **本回合自己的**消息(来源行 + 当次用户消息),受限车道的形状在有无转录时保持一致。
|
||||
func (b *Bridge) buildLoopMessages(_ context.Context, text string, env loop.SessionEnv, actor adapter.Actor, senderName string, src adapter.UnifiedMessage) []model.Message {
|
||||
// design/12 §6 策略一补充:经传入前审查放行的系统通知走「限定注入」——只把剥离后的
|
||||
|
||||
Reference in new issue
Block a user