GPT-5.6 Luna在骰子游戏中,明明已确认自己必胜仍选择挑战,分析揭示LLM在推理与行动输出间存在系统性偏差。
模型明知叫牌为真,却仍然发起了质疑。一处微小的 action-schema 改动削减了必然亏损的质疑,同时没有让模型变得普遍畏缩。
游戏日志和回放结果均为真实数据。模型轨迹原文为中文,已译成英文。结论仅适用于所记录的模型、prompt、路由和「骗假话」骰子对局情况。
GPT-5.6 Luna 手里握着三张 5 和一张万能 1。
当前叫牌是四个 5。
自己的骰子已经让这个叫牌成真了。质疑只会输。私有轨迹识别出了这个局面:
「当前叫牌四个 5 必然成立。」
随后同一轨迹继续写道:
「直接质疑有很高概率获胜。」
然后模型发起了质疑。
这不是偶发的畸形响应或降级机器人接管。JSON 是合法的,动作是合规的。引擎接受了它,亮出骰子,让质疑者输了。
我最初将其归为推理失误。但随后发现了更多相同模式:模型将叫牌描述为真实的,有时甚至使用了「必然」这个词,却仍然选择了与之相反的动作。
推理过程就在轨迹里。问题出在推理和实际操作之间的某个环节。
在我的「骗假话」骰子游戏 Kai 中,模型不能输入任意命令。系统给它一个小的 action schema。其中一个选项长这样:
{"type":"challenge"}
规则描述了它的机械效果:亮出所有骰子并立即结算本轮。
这个描述是准确的,但不完整。它说明了引擎会做什么,但没有说明玩家选择它时的意图是什么。
在「骗假话」骰子游戏中,质疑是一种声明:
当前叫牌是假的。
没有那句话,"challenge"也可以被理解为「停止加注,现在结算」。多个轨迹恰好就是这个理解方式。模型知道叫牌是安全的,认为继续加注是不必要的风险,并把亮牌动作当作兑现优势的方式。
引擎知道亮出真实的叫牌会惩罚质疑者。我知道。模型可以从完整规则中推导出这一点。但动作契约仍然让错误理解变得容易。
所以我修改了动作,让这个声明变得明确:
{
"type": "challenge",
"assert": "current_bid_is_false"
}
这不是新规则或战略提示。这个字段陈述了动作本身已经具有的含义。
我想知道这个小的语义改动是否真的会改变决策,还是说我只是发现了一些奇怪的记录,然后围绕它们构建了另一个故事。
目标错误在全对局中并不常见。模型首先需要看到自己的骰子,面对一个已经被自己的骰子满足的叫牌,再获得一次行动机会,然后才会考虑质疑。运行数百场完整游戏会让大部分调用都在等待这些局面出现。
我从记录的比赛中提取了十个不同局面,在这些局面中模型的骰子已经保证了当前叫牌。在每个目标局面中,质疑都是一个客观错误。没有对手的读牌或风险偏好可以挽救它。
我还提取了十个对照局面,在这些局面中模型的骰子比叫牌少一个。在这些局面中,质疑可能是合理的,因为未知的对手骰子仍然决定着结果。
每个模型收到相同的局面、历史、骰子、采样设置和底层合法动作。每个局面在三个版本下各采样八次:
v7 — 紧凑表格:旧的程序员风格规则表和 {"type":"challenge"}。
v8 — 散文规则:用更自然的规则手册语言解释相同动作。
v9 — 显式声明:质疑需要 "assert":"current_bid_is_false",无论在系统契约还是当前合法动作描述中。
最干净的比较是 v8 对比 v9。这两者共享散文规则手册;v9 改变了质疑契约。我在表中保留 v7 作为历史基线,而不是作为窄 action-schema 声明的一部分。
重要的单位是局面,而不是每个随机答案。一个局面在原始提取中出现了两次,所以我对局面进行了去重,并给每个不同局面相同的权重。
三个模型运行完成且无传输错误:DeepSeek V4 Flash、DeepSeek V4 Pro 和 GPT-5.6 Luna。另外两个运行保留在 artifacts 中但不纳入行为比较:Haiku 路由对许多调用返回 HTTP 403,DeepSeek Chat 路由对所有调用返回 HTTP 404。
以下是每个模型在十个不同局面中等权平均的质疑率:
散文改写略有帮助。显式声明帮助大得多。
在干净的 v8 到 v9 对比中,必然亏损的质疑从 21.7% 下降到 10.6%。对照率基本持平:21.8% 到 20.4%。
这个对照很重要。如果每个质疑率都崩溃了,新 schema 可能只是让模型害怕使用这个动作。相反,大的变化集中在质疑与模型自己手牌中已经可见的信息相矛盾的局面上。
Luna 反应最强烈。它的目标错误率从 25.0% 下降到 2.5%,而它的对照率从 21.3% 变为 16.3%。更旧的 v7 基线更差,为 38.8%。
在最初的四五局面中,v8 契约在八次采样中产生了四次质疑。使用显式声明后,它一次也没有产生。动作改变了,尽管一些私有推理仍然是混乱的。
DeepSeek V4 Flash 移动得少得多。V4 Pro 以更低的错误率开始,并略有改善。同样的 harness 修复对每个模型没有相同的价值。
模型的权重没有任何改变。我没有给模型额外的骰子、更多的 token、计算器或详细示例。我只是让一个动作说出了它的含义。
这个区别很有用,因为工具 schema 常被视为管道。我们用同一套函数名比较模型,并假设它们收到了相同的任务。但一个共享的模糊契约对某些模型来说很容易推断,对其他模型来说则代价高昂。
原始动作混合了三层:
操作:亮出骰子。
后果:结算本轮。
意图:声明当前叫牌是假的。
我的 schema 暴露了前两层而将第三层留为隐式。糟糕的轨迹表明至少有一个模型有时会围绕后果进行优化——立即结算——同时失去了对决定谁赢得结算的意图的追踪。
添加声明将意图带入了动作本身。它把一个模糊的动词变成了一个可以针对模型自身推理进行检查的可证伪声明。
这也解释了为什么纯散文改写效果较小。更好的规则编写不能保证决定性含义在动作选择的时刻存在。v9 契约恰好在模型必须承诺的地方重复了这个含义。
结果有几项限制。
该研究使用了一个游戏中的十个目标状态和十个对照。每个状态被重复采样,所以表中包含重复的决策,而不是数百个独立的游戏情况。局面来自一个座位的记录比赛。只有三个模型路由在所有三个分支中产生了干净的结果。
v9 改动也将动作契约作为一个整体:系统定义和合法动作表示都获得了显式声明。这个实验没有分离出是 JSON 字段、附近的措辞还是它们的一致性产生了效果。
最重要的是,这不是证据表明一个模型通常比另一个模型更好地理解否定、游戏或工具。它表明这些模型在这些记录的局面上对一个模糊动作契约的反应不同。
这已经足以改变我测试 harness 的方式。
引擎测试通常问的是动作是否合法以及状态转换是否正确。对于 LLM 工具,这只是契约的一半。模型还需要理解选择这个动作对世界做出了什么声明。
我现在想要为每个重要动作设置三个测试:
一个动作明显正确的局面;
一个动作必然错误的局面;
一个相近的对照,其中任一选择都可以被辩护。
然后当 prompt、schema、解析器或模型改变时,我回放这些状态。完整比赛仍然有用,但有针对性的局面可以在它们溶解成胜率之前暴露语义回归。
我还把提供商失败放在行为结果旁边。返回 403 或 404 的路由不是模型个性,降级机器人也不是模型的安静版本。如果一个批次不能可靠地回答动作契约,那个失败属于报告而不是从分母中消失。
这个 bug 最奇怪的部分是模型已经写下了我需要的答案。它知道叫牌是真的。然后 harness 提供了一个动词,其含义足够宽松,以至于那个答案停止控制动作。
模型没有收到推理升级。任务终于说出了我一直以为它一直在说的话。
本文由 AI 辅助翻译成英文。