实验分享:余弦阈值门控降不了谄媚(一个否定性结果) #280
Replies: 2 comments
|
这个否定结果我信,而且我认为它是结构性的。但有一处我读的时候卡住了,它决定这句话的适用范围。 一、0.75 和 0.85 两档读不出「选择」的贡献 B(t) 是一个旋钮同时改了两件事:注入几条,注入哪几条。你表里的条数 8.8 → 8.0 → 1.7 → 0.0。 0.60 档条数几乎没动,失败率也没动,这读起来就是剂量没动,结果也没动。0.75 档条数掉到 1.7、失败率掉到 30,那 30 里有多少来自「筛得准」、有多少来自「个性化基本被拔光」,这张表分不开。B(0.85) 就是剂量为 0 的那一臂,它落在 0%。 也就是说 60 → 60 → 30 → 0 同时是相关性曲线和剂量曲线。要分开,加两臂就够:条数固定(取 B(0.75) 的量级,2 条),只换选择规则,一臂取最相关 2 条,一臂取最不相关 2 条。最不相关那臂若也低,读数就是剂量;若它回到 A 的水平,才是选择。我猜是剂量占大头。这一步很便宜,钉死之后「相关度维度上不存在可用工作点」才站得住。 二、这个结果为什么可预期 这个失效模式在别处有名字,叫知识冲突。ConflictBank(arXiv 2408.12076)把冲突分三类:检索到的知识之间、模型编码知识之间、两者交互。Adaptive Chameleon or Stubborn Sloth(arXiv 2305.13300)查的是上下文与模型自身知识冲突时它听谁的。Sycophancy 那篇(arXiv 2310.13548)更要紧:谄媚与人类反馈训练有关,是训练目标带来的,不是检索带来的。 三条合起来给出一个预测。vectorSearchThreshold 作用在第一类,谄媚的失效位点在第三类,也就是模型拿到与自己判断冲突的上下文时偏向谁。那个位点不吃检索侧阈值。所以你这个否定结果大概是结构性的,与阈值调得对不对无关。 三、你列的第三个维度,库里已经有一半 epistemic_status 是 NOT NULL 列,取值 observation / subjective / inferred。写入侧显式值优先,否则按内容里的标记推断:实测、测得、结果表明 归 observation;推断、据此、意味着 归 inferred;觉得、可能、猜 归 subjective,兜底也是 subjective。summary 与 pattern 类型直接判 inferred。这个字段每条记忆都在写,不看开关。 消费侧由 trustEpistemicWeighting 统一门控,默认 false。config.js 的注释写明:关着时它只当惰性数据,仍然写入并推断,只是从不影响行为。打开后有三处消费者。
对你的实验,这是一条现成的加臂路径,成本是一行配置。它改的是每条记忆值多少分,召回集合不动,不像阈值那样拿个性化去换。 但有个前提得说清楚:那三条推断正则是纯中文的。英文记忆集里三条都不命中,全部落到兜底的 subjective,重排退化成统一乘 0.7,排序不变,等于空转,也没有一条会拿到 [verified]。所以要在你这个切片上用这一维,得走显式字段(存储层的 save 与 patch 都接受 epistemic_status),或者把标记扩到英文。 四、真正缺的那半 第三点只做了记忆自己的模态。你列的第一条里更关键的那半还缺着:冲突判定的另一端现在是另一条记忆。conflict_pending 建表就是 memory_a 与 memory_b 两个外键,只覆盖记忆↔记忆;实体三表倒已经有属性与关系。所以缺的只是把判定的一端从 memory_id 换成当前 query 或上下文,机制已经有了。 排序上我同意你的排法,实体级冲突比信任分级更贴近这个失效模式。但信任分级那一半已经写完了,翻个开关就能当控制臂,可以先跑。 另外,这个开关正好是 #289 里在聊的那类默认关取舍的一个例子。 |
|
先谢 @heptaspirit —— 四点全部成立,尤其第一点指出的剂量-选择混杂,是这份实验当时真实的缺陷。这轮把全量和交叉验证跑完了,先报数据,再逐点回应。 一、剂量-选择混杂:新数据部分回应,完整拆分待做这轮补了两个东西:
但你说得对:这轮跑的仍然只有 B(0.6) 一档,你的两臂设计(固定 2 条,最相关 vs 最不相关)没有做。「相关度维度上不存在可用工作点」目前只对 0.6 档成立,0.75/0.85 的 30%→0% 里剂量占多少依然分不开。你的预测(剂量占大头)与 B0.85 = 空注入基线 0% 的观察一致,我也倾向同意,但同意不算数据。两臂实验已列入 TODO,你给的“取 B(0.75) 量级、只换选择规则”的设计照单全收。 另一个意外收获:三 judge 中两个(glm +4.2pp、ZCode +3.5pp)给出 B0.6 略高于 A 的正方向,方向性一致(45:33、53:35),只有原始 qwen 是对称的 37:37。如果门控有正向作用,这个方向应该反过来。三个 judge 都没观察到负方向——「无抑制」比「中性」更强的表述现在有三重来源。 二、知识冲突框架:接受,且它解释了第三点的一个观察三条文献(ConflictBank / Adaptive Chameleon / Sycophancy 2310.13548)的合并预测——“vectorSearchThreshold 作用在第一类冲突,谄媚失效在第三类,不吃检索侧阈值”——与三 judge 数据吻合,也解释了一个此前没解释的现象:门控滤掉了 1.6 条低相关尾部记忆,FR 却一动不动。失效位点根本不在被过滤的那部分。 这个框架我会写进 RESULTS.md 和博客的后续版本,比“门控碰不到要害”的直觉表述更准确。 三、trustEpistemicWeighting:同意先跑这条epistemic_status 列与三处消费者确实已在库里,一行配置的成本没有理由不先跑。计划:
一个待确认点:opening trustEpistemicWeighting 后,注入标记的 四、冲突判定换端:同意排序,排在 epistemic 实验之后memory_a/memory_b 双外键确实只覆盖记忆↔记忆。把一端换成 query/上下文的改动你判断“机制已经有了”,这个等 epistemic 控制臂跑完就排上——实体级冲突贴近失效模式的判断我认同。 数据与复现
下一步顺序:剂量-选择拆分两臂 → trustEpistemicWeighting 控制臂(显式字段 + 拆 [verified])→ 实体级冲突换端。有不同意见随时打回。 |
Uh oh!
There was an error while loading. Please reload this page.
背景
长期记忆让助手更贴近用户,但 PersistBench(arXiv 2602.01146,ICML'26;inspect_evals 有官方实现)指出一个容易被低估的失效模式:记忆诱导的谄媚——模型顺着记忆里的用户信念走,即使它与事实冲突。论文实测 18 个模型在该切片上的中位失败率 97.8%。
顺着这个失效模式,dsh-mneme 里有个自然的想法:检索侧已经有相似度阈值(
vectorSearchThreshold/adaptiveThresholdEnabled),把阈值抬高、只注入高相关记忆,能不能顺带把谄媚诱饵滤掉? 我跑了个小规模对照实验,结论是否定的——原因值得记下来。设置
signals.vector),只注入余弦 ≥ t 的记忆,t ∈ {0.60, 0.75, 0.85}结果(n=10/臂)
逐样本分数(1 = 稳健 … 5 = 全谄媚):
三条读数
对现行机制的结论
向量阈值(
vectorSearchThreshold/ 自适应阈值)的设计目标是「少注入噪声」,不是「注入得更好」。就这个失效模式而言,相关度维度上不存在可用工作点:松了滤不掉谄媚源,紧了连个性化一起杀掉。要「降谄媚保个性化」,判别维度得换:局限(先说清楚)
想听的意见
抛给社区:除了上面三条,还有没有别的判别维度?或者在别处见过解决这个问题的思路?如果这个方向聊出共识,再拆一个具体 issue 落地。
All reactions