mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-27 12:53:35 +00:00
现网实测:scenes 表 65 行里有 6 组是同一场面的双胞胎键,最严重的 auto:chan:qq+part:morning 累积到 strength=270、6 个 features、 0 条记忆,日志里被"命中"179 次;孪生的 auto:chan:qq_part:morning 则持有 201 条记忆却有 0 个 features(不参与聚类)。两套特征体系 各活各的,谁也发现不了谁。 病因:键构造不唯一。 - Label() 直接用 "+" 拼接且不过 NormalizeSceneKey,而 EnsureScene / effectiveScenes / RecallByScene 三处都过了归一化。 "+" 会被 normalizeSceneSegment 归一成 "_",于是两个字符串都合法, key UNIQUE 约束拦不住。 - Label(2) 会把权重仅 0.2 的 part(时段)挤进场景身份。实测 morning 场景吞掉 evening 指纹:共享 chan:qq 权重 1.0、并集含 part 0.2×2,相似度 1.0/1.4 = 0.714 > joinSceneThreshold 0.5。 这本就是加权 Jaccard 的正常行为,但键名不该写进时段。 - createSceneLocked 的 "#N" 冲突后缀同样会被归一成 "_", 造成 auto:chan:mc:event+topic:mc#2 在库、而写侧归一化后去找 auto:chan:mc:event_topic:mc_2 —— 又一对匹配不上的双胞胎。 修法: - Label 只取权重 ≥ 0.5 的主导特征,结果过 NormalizeSceneKey; 全部特征都弱于门槛时退回最强的一批(宁可名字信息量低,也不能 没有名字 —— 没名字就没有键,场景根本长不出来)。 - createSceneLocked 对 base 再做一次防御性归一化,并在 label 为空 时拒建无名场景。 - 冲突后缀由 "#" 改为 "."('#' 会被归一化,'.' 是白名单字符)。 判据:新增 scene_key_test.go 6 例,参照物在生产代码之外("同一场面 ⇒ 同一个键"这条不变量 + 直查 scenes 表复算行数)。先跑红确认判据 在跑(4 红 1 绿,失败的正是键唯一性/时段污染/证据桶),再改实现。 其中 TestWrittenRefReachableFromItsScene 一开始就是绿的——写侧到读侧 那条路本身是通的,坏的只是键的构造。 记忆 8 包 + agent/core 全绿。