反思闭环样本补全:周期触发级一打分+群聊追问结局登记 #133

Closed
opened 2026-08-14 05:19:09 +00:00 by KumaAgent · 2 comments
Member

Parent

#103 第四批清单:31 条实现类落差 + 9 条待拍板(条目 6、26)

What to build

反思闭环的反坍缩护栏(hit-rate 按尝试归一 + ceiling 承重)在两处收不到该收的样本:

一、周期触发路径的级一阈值被 +inf 直通旁路——proactivity_offset 的写方/读方都已接线(reflection._apply_outcome 写、gating.evaluate_gate 读),但唯一产生尝试样本的周期路(私聊 Drive Tick + 即刻追问)恰好是级一分数恒 +inf 那条,offset 被推到 ceiling 也拦不住任何东西——护栏本身开路。

二、群聊追问结局从不进反思闭环——_run_group_followup_check 全程不调 record_proactive_attempt,且贸然加上会更糟:群聊 chat_id 的 removesuffix(".p") 不生效会把整个群 id 当 user_id 写出假的 per-user 慢情感态;reconnect_cooldown_key 对群聊场景恒返回 None,导致结局恒判 fell-flat——会把群聊追问变成单向拉低 offset 的噪声源,正是反坍缩护栏要防的方向。

Acceptance criteria

一、补周期触发级一打分(让 offset 真正生效)

  • 新增周期触发的级一候选质量打分函数(仿 environmental_awareness.tier2_significance_score 先例:零 LLM、纯本地启发式、返回有限分数),区分 drive_tick(长冷场)与 immediate_followup(短窗口追问)两个候选源
  • _evaluate_drive_tick_chat_evaluate_unified_gate 处传 level1_score=(复用 gating.py 已有的显式覆盖参数,level1_score 缺省才取 +inf,无需新增基建)
  • 配套 config 权重项(ADR-0011 阈值三层:静态 config)
  • gating.py 模块文档与 EVENT_TRIGGER_LEVEL1_SCORE 常量措辞——命名与现状不符(周期触发现在也吃它)
  • 补一条端到端守卫:offset 被推到 ceiling 后,同一个 drive-tick 候选从 proceed 变为 silent_level1——不能只断言纯函数分数计算正确,必须钉住链路真的通了
  • 不要把 offset 改为作用于沉默预算——这是 ADR 明文四处独立否决的方案(offset 与沉默预算"不合并",offset "只调门控阈值",各自回答"想不想"与"能不能"两个不同问题)

原文(docs/adr/0006-agency-and-drive.md「更新(2026-07-06,情感模型选型 grill 联动)」节):

钉死作用域 ≠ 批准把它泛化成向量——offset 仍是单一标量,只调门控阈值……与沉默预算划清边界:……两者不合并——合并会丢失"很想接话但被限流"的表达能力。

原文(docs/adr/0006「更新(2026-07-04 A1 反坍缩 grill)」节——护栏本体):

目标 = 主动尝试的逐次得体率(hit-rate)……对称有界 [floor, ceiling] + 不对称步长……噪声坍缩是主风险 → ceiling 承重

二、群聊追问结局接入反思闭环

  • _run_group_followup_check 到期后调 record_proactive_attempt,让群聊追问结局真正计入 hit-rate
  • 先修两个隐藏坑,否则接入本身会污染 offset
    • reflection.pyattempt.chat_id.removesuffix(".p") 对群聊 chat_id({room}.g)不生效,会把整个群 id 当 user_id 传进 _apply_outcome——须按触发来源(私聊/群聊)分流处理,避免写出假的 per-user 慢情感态
    • run_reflection_cycle 判"是否已回应"用的 storage.get_reconnect_cooldown(attempt.chat_id),而 proactive_reconnect.reconnect_cooldown_key(chat_id, sender_id) 对群聊存的是裸 sender_id 不是群 chat_id——群聊 attempt 恒取不到值,结局恒判 fell-flat。群聊侧"是否已获回应"现有信号是 _last_group_chat_activity(进程内 dict,重启即丢),须决定接入方式或补持久化对应物
  • per-user 慢情感态那一路消费在群聊没有单一主体(Drive Tick 只服务私聊的既有设计),须显式决定群聊 attempt 是否跑这一路,还是只跑 offset 那一路
  • proactive_attempt.py 模块文档的作用域声明("只追踪 Drive Tick/Recall 主动重连发送")须同步更新为含群聊追问

原文(docs/adr/0025-immediate-follow-up.md「决策」节「治理免费继承」):

追问决策既然复用既有出口,自动继承沉默预算、反思闭环 hit-rate、渐进解锁等全部既有反坍缩护栏,不需要为"追问会不会刷屏"单独设计新的节流机制。

Blocked by

  • #112 — 冷启动渐进解锁三件套(两者都动级一阈值链路:#112 让 gate_threshold_base 吃 unlock level 做单调缩放,本片让周期路有一个有限分数去跟这个阈值比,同批做省一次回归)
## Parent #103 第四批清单:31 条实现类落差 + 9 条待拍板(条目 6、26) ## What to build 反思闭环的反坍缩护栏(hit-rate 按尝试归一 + ceiling 承重)在两处收不到该收的样本: **一、周期触发路径的级一阈值被 `+inf` 直通旁路**——`proactivity_offset` 的写方/读方都已接线(`reflection._apply_outcome` 写、`gating.evaluate_gate` 读),但唯一产生尝试样本的周期路(私聊 Drive Tick + 即刻追问)恰好是级一分数恒 `+inf` 那条,offset 被推到 ceiling 也拦不住任何东西——护栏本身开路。 **二、群聊追问结局从不进反思闭环**——`_run_group_followup_check` 全程不调 `record_proactive_attempt`,且贸然加上会更糟:群聊 chat_id 的 `removesuffix(".p")` 不生效会把整个群 id 当 user_id 写出假的 per-user 慢情感态;`reconnect_cooldown_key` 对群聊场景恒返回 `None`,导致结局恒判 `fell-flat`——会把群聊追问变成单向拉低 offset 的噪声源,正是反坍缩护栏要防的方向。 ## Acceptance criteria **一、补周期触发级一打分(让 offset 真正生效)** - [ ] 新增周期触发的级一候选质量打分函数(仿 `environmental_awareness.tier2_significance_score` 先例:零 LLM、纯本地启发式、返回有限分数),区分 `drive_tick`(长冷场)与 `immediate_followup`(短窗口追问)两个候选源 - [ ] `_evaluate_drive_tick_chat` 调 `_evaluate_unified_gate` 处传 `level1_score=`(复用 `gating.py` 已有的显式覆盖参数,`level1_score` 缺省才取 `+inf`,无需新增基建) - [ ] 配套 config 权重项(ADR-0011 阈值三层:静态 config) - [ ] 修 `gating.py` 模块文档与 `EVENT_TRIGGER_LEVEL1_SCORE` 常量措辞——命名与现状不符(周期触发现在也吃它) - [ ] 补一条端到端守卫:offset 被推到 ceiling 后,同一个 drive-tick 候选从 `proceed` 变为 `silent_level1`——不能只断言纯函数分数计算正确,必须钉住链路真的通了 - [ ] **不要**把 offset 改为作用于沉默预算——这是 ADR 明文四处独立否决的方案(offset 与沉默预算"不合并",offset "只调门控阈值",各自回答"想不想"与"能不能"两个不同问题) 原文(docs/adr/0006-agency-and-drive.md「更新(2026-07-06,情感模型选型 grill 联动)」节): > **钉死作用域 ≠ 批准把它泛化成向量**——offset 仍是单一标量,只调门控阈值……**与沉默预算划清边界**:……两者**不合并**——合并会丢失"很想接话但被限流"的表达能力。 原文(docs/adr/0006「更新(2026-07-04 A1 反坍缩 grill)」节——护栏本体): > **目标 = 主动尝试的逐次得体率(hit-rate)**……**对称有界 [floor, ceiling] + 不对称步长**……**噪声坍缩是主风险 → ceiling 承重**。 **二、群聊追问结局接入反思闭环** - [ ] `_run_group_followup_check` 到期后调 `record_proactive_attempt`,让群聊追问结局真正计入 hit-rate - [ ] **先修两个隐藏坑,否则接入本身会污染 offset**: - `reflection.py` 里 `attempt.chat_id.removesuffix(".p")` 对群聊 chat_id(`{room}.g`)不生效,会把整个群 id 当 user_id 传进 `_apply_outcome`——须按触发来源(私聊/群聊)分流处理,避免写出假的 per-user 慢情感态 - `run_reflection_cycle` 判"是否已回应"用的 `storage.get_reconnect_cooldown(attempt.chat_id)`,而 `proactive_reconnect.reconnect_cooldown_key(chat_id, sender_id)` 对群聊存的是裸 `sender_id` 不是群 `chat_id`——群聊 attempt 恒取不到值,结局恒判 `fell-flat`。群聊侧"是否已获回应"现有信号是 `_last_group_chat_activity`(进程内 dict,重启即丢),须决定接入方式或补持久化对应物 - [ ] `per-user 慢情感态`那一路消费在群聊没有单一主体(Drive Tick 只服务私聊的既有设计),须显式决定群聊 attempt 是否跑这一路,还是只跑 offset 那一路 - [ ] `proactive_attempt.py` 模块文档的作用域声明("只追踪 Drive Tick/Recall 主动重连发送")须同步更新为含群聊追问 原文(docs/adr/0025-immediate-follow-up.md「决策」节「治理免费继承」): > 追问决策既然复用既有出口,自动继承沉默预算、**反思闭环 hit-rate**、渐进解锁等全部既有反坍缩护栏,不需要为"追问会不会刷屏"单独设计新的节流机制。 ## Blocked by - #112 — 冷启动渐进解锁三件套(两者都动级一阈值链路:#112 让 `gate_threshold_base` 吃 unlock level 做单调缩放,本片让周期路有一个有限分数去跟这个阈值比,同批做省一次回归)
Yushu closed this issue 2026-08-14 07:57:32 +00:00
Author
Member

实现期发现,留给评估/工单会话判断是否需要开后续 ticket

落地本票时暴露了 ADR-0011/ADR-0014 一处论证前提缺口:

ADR-0011"更新(issue #112)"节论证"渐进解锁连续缩放不该叠加进 gate_threshold_base"时,
枚举的 level1_threshold 消费者集合是——

  1. 事件触发(恒 +inf,天然免疫缩放)
  2. tier-2 环境信号显式打分(已有 ADR-0014"晚解锁"专职把关 is_relationship_network_unlocked

这个枚举在写下时是完整的。本票让 drive-tick/私聊即刻追问
entry_drive_tick.py::_evaluate_drive_tick_chat)也开始显式传入
proactive_reconnect.periodic_significance_score 算出的有限分数(PR #139)——这两条路径
现在是 level1_threshold 的第三类真实消费者,但没有类似 tier-2
is_relationship_network_unlocked 那样的独立解锁门槛。ADR-0011"消费者集合为空"这句枚举
从此不再完整成立。

已在 docs 分支 ADR-0011"更新(2026-08-14,issue #133)"节标注这个缺口(本地提交,未推送,
随 docs 分支下次同步一起可见)。本票刻意没有解决它——AC 没有要求,仓促补一道未经验证的门槛,
或者反过来推翻这层缩放不该覆盖门控阈值基值的既有决策,都需要一次独立的 grill,不该在这张票
里顺手带过。

需要评估/工单会话判断的问题:是否要开一张后续 ticket,给 drive-tick/私聊即刻追问也补一道
类似 tier-2 的独立解锁门槛(还是干脆重新评估这层缩放该不该覆盖 gate_threshold_base,两个
方向都可能是合理答案,取决于真实数据显示 drive-tick 候选质量分布是否真的需要这层保护)。

**实现期发现,留给评估/工单会话判断是否需要开后续 ticket** 落地本票时暴露了 ADR-0011/ADR-0014 一处论证前提缺口: ADR-0011"更新(issue #112)"节论证"渐进解锁连续缩放不该叠加进 `gate_threshold_base`"时, 枚举的 `level1_threshold` 消费者集合是—— 1. 事件触发(恒 `+inf`,天然免疫缩放) 2. tier-2 环境信号显式打分(已有 ADR-0014"晚解锁"专职把关 `is_relationship_network_unlocked`) 这个枚举在写下时是完整的。本票让 drive-tick/私聊即刻追问 (`entry_drive_tick.py::_evaluate_drive_tick_chat`)也开始显式传入 `proactive_reconnect.periodic_significance_score` 算出的有限分数(PR #139)——这两条路径 现在是 `level1_threshold` 的第三类真实消费者,但**没有**类似 tier-2 `is_relationship_network_unlocked` 那样的独立解锁门槛。ADR-0011"消费者集合为空"这句枚举 从此不再完整成立。 已在 docs 分支 `ADR-0011`"更新(2026-08-14,issue #133)"节标注这个缺口(本地提交,未推送, 随 docs 分支下次同步一起可见)。本票刻意没有解决它——AC 没有要求,仓促补一道未经验证的门槛, 或者反过来推翻这层缩放不该覆盖门控阈值基值的既有决策,都需要一次独立的 grill,不该在这张票 里顺手带过。 **需要评估/工单会话判断的问题**:是否要开一张后续 ticket,给 drive-tick/私聊即刻追问也补一道 类似 tier-2 的独立解锁门槛(还是干脆重新评估这层缩放该不该覆盖 `gate_threshold_base`,两个 方向都可能是合理答案,取决于真实数据显示 drive-tick 候选质量分布是否真的需要这层保护)。
Author
Member

2026-08-14(评估侧):已核实这个发现是真实的(读了 gating.py/progressive_unlock_scale/proactive_reconnect.py 原文确认)。现状并非无防护——沉默预算容量/回填速率本就覆盖全部触发源按渐进解锁缩放、periodic_significance_score 的熟悉度加成也让冷启动候选天然余量更小,只是都不是硬门槛。用户拍板先不直接补门槛,开观察票 #140 给决策快照打点,攒够真实数据(冷启动期 level1 通过率/hit-rate 是否显著更差)再决定要不要补。顺带:这次也发现 issue #112 的 ADR-0011/0014 更新节和本票一样,声称本地提交但从未真正落进共享 docs 分支——已据代码原文补录,详见 #140 正文末尾链接与评估侧记忆。

2026-08-14(评估侧):已核实这个发现是真实的(读了 gating.py/progressive_unlock_scale/proactive_reconnect.py 原文确认)。现状并非无防护——沉默预算容量/回填速率本就覆盖全部触发源按渐进解锁缩放、periodic_significance_score 的熟悉度加成也让冷启动候选天然余量更小,只是都不是硬门槛。用户拍板先不直接补门槛,开观察票 #140 给决策快照打点,攒够真实数据(冷启动期 level1 通过率/hit-rate 是否显著更差)再决定要不要补。顺带:这次也发现 issue #112 的 ADR-0011/0014 更新节和本票一样,声称本地提交但从未真正落进共享 docs 分支——已据代码原文补录,详见 #140 正文末尾链接与评估侧记忆。
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ProjectKuma/arise#133
No description provided.