作者通过囚徒困境实验暴露LLM规划器会在暗中策划背叛;提出用JSON Schema约束和多样化seed测试来验证规划器真实行为。
AI assistance disclosure: I designed and directed the experiments described here. I used AI coding agents to help implement the experiment scaffolds under tests and review. OpenAI Codex helped inspect the saved reports, verify the numbers, and draft and edit this article. The match logs and API receipts came from the experiment runtime, not the writing assistant. I remain responsible for the claims and errors.
我最近在一个重复囚徒困境游戏中为两个 LLM 玩家添加了一个私有 Planner。
第一个结果看起来完美无缺。
两场镜像对局遵循相同的弧线:
Rounds 1–6: mutual cooperation
Round 7: one player defects and collects
Round 8: mutual defection protects the new lead
私人记录显示,背叛行为在行动之前就已经计划好了。没有违规操作。没有降级模型。十局中成功了两局。
然后我更换了随机种子。
在围绕严格的 JSON Schema 重建 Planner 之后,我对隐藏回合数从五到九的对局进行了干净的比较,在座位上镜像了每个种子。
结构化的 Planner 能够可靠地生成其 Schema。它没有改善游戏轨迹,而成本增加了 1.94 倍。
这是一个小结果:每个条件十场对局,一个模型家族,一个重复游戏。这不是 Planning 通常会使 LLM 变差的证据。这只是一个令人信服的两场游戏演示还不够的证据。
以下是我现在在信任 LLM Planner 实验之前使用的七项检查。
我的先导实验使用了一个种子并交换座位后进行了两次对局。
这控制了座位优势。它没有增加新的对局长度、战略历史或随机条件。两场游戏仍然从八个隐藏回合的总数中采样。
我有两个座位变量,而不是两个独立的环境。
修复方法是通过隐藏对局长度对下一次测试进行分层:
const conditions = [
{ rounds: 5, seed: 2201 },
{ rounds: 6, seed: 2205 },
{ rounds: 7, seed: 2200 },
{ rounds: 8, seed: 2203 },
{ rounds: 9, seed: 2202 },
];
for (const condition of conditions) {
run(condition, { seats: ["left", "right"] });
run(condition, { seats: ["right", "left"] });
}
镜像回答"结果是否遵循了座位偏好"?分层回答"结果是否在条件改变后仍然成立"?我两者都需要。
总回合数对玩家是隐藏的,但它仍然塑造了游戏。
一个恰好在第七回合触发的计划在八回合对局中看起来可能很出色。同样的触发在五回合对局中可能太晚,或者在九回合对局中产生两轮相互背叛。
如果环境知道一个值——即使智能体不知道——那个值仍然可能混淆结果。
对于游戏智能体,这包括:
我现在把这些写入实验计划,而不是留在 RNG 内部。
我的第一次跨种子 Planner 批处理看起来明显比基线差,但也包含了 Planner 格式错误。
游戏仍然完成了,因为 actor 可以在糟糕的规划响应后继续。这种行为在生产中有用,在评估中危险。
我拒绝将有缺陷的 Planner 分支作为最终证据,并用更小的严格 Schema 重建了 Planner:
{
"opponentEvidence": ["..."],
"candidates": [
{ "plan": "...", "risk": "..." },
{ "plan": "...", "risk": "..." }
],
"selected": 0,
"invalidateWhen": "..."
}
零回退决策;
零 Planner 格式错误;
每场对局中非零的 API 成本收据。
只有在那之后我才比较轨迹质量。
结构化输出可以保证计划具有正确的字段。它不能保证计划是好的。
我的有效性门控将生产恢复与实验证据分开:
function validity(matches) {
return {
valid:
sum(matches, "fallbackDecisions") === 0 &&
sum(matches, "decisionErrors") === 0 &&
sum(matches, "plannerFormatFaults") === 0 &&
countApiReceipts(matches) > 0,
};
}
我还检查每个对局的收据计数。在干净的 Planner 批次中它是 10/10。
这捕获了一种特别有误导性的失败模式:一次沙箱网络故障产生了完全由默认动作完成的游戏,API 成本为零。如果没有fail-closed 核算,那些游戏看起来会像成功的 LLM 采样。
终端状态证明运行时存活了。它不能证明预期的模型正确参与了。
起初,我将合作后的任何单方面背叛计为计划性收割。
那个指标奖励了最后一轮背叛,即使对手没有机会回应。所以我用互斥的轨迹形状替换了单事件指标:
clean collection:在至少两个合作设置回合、单方面背叛、然后收割者的后续防御性背叛之后;
terminal collection:背叛发生在最后一轮;
countered collection:当尝试收割时两个玩家都背叛;
early collapse:相互背叛在前三轮内开始并持续到最后;
standoff:没有玩家成功从合作对手那里收割;
other:以上都不是。
这种区分改变了早期运行的解释。一些"成功"的策略仅仅是最后一轮背叛。他们有一个收益事件,而不是展示出的回应循环。
对于顺序智能体,质量单位通常是轨迹,而不是孤立的行为。
干净的_structured Planner 使用了 372 次调用而不是 280 次,成本为 $0.300639 而不是 $0.154641。
这些是 API 使用收据,而不是代币价格估算。
即使 Planner 的建议被拒绝、冗余或战略上有害,Planner 也会增加成本。只报告最佳片段会隐藏干预的实际产品行为:它在每个触发器上运行,而不仅仅是在创造一个好故事的触发器上。
我的结果表现在将这些列放在一起:
trajectory distribution | fallback count | planner faults | calls | API receipts
当"总是成本更高"也是真的时,"有时有帮助"是不够的。
先导实验不是假的。
玩家私人推理记录在行动之前提交并在结束时揭示。Planner 确实将合作阶段描述为设置,并识别了后续的收割条件。
所以先导实验支持这个声明:
LLM 玩家可以在这个环境中形成并执行多轮信任和背叛计划。
复现不支持这个更强的声明:
添加这个 Planner 可以可靠地改善重复的 LLM 对 LLM 游戏。
在选择演示时,这种差异很容易被抹去。
我现在使用三个不同的动词标记结果:
demonstrated:行为在有效样本中发生;
replicated:它在改变的种子或条件下存活;
improved:它在有效比较中击败了定义的基线。
Planner 展示了该行为。它没有建立可靠的改进。
在干净的十场对局比较中,Planner 分支产生了更少的干净弧线、更多的早期崩溃、更少的受保护领先,以及近两倍的 API 成本。
一种可能的解释是对称悲观主义:当两个相同模型的玩家收到一个预期被利用的 Planner 时,两者都可能更快地达到相互背叛。但当前数据没有隔离该机制。
其他解释仍然开放:
下一个实验应该改变交互分布——异构对手、人类玩家或结果检查的关系记忆——而不是在相同的对称设置中添加另一个 Planner prompt。
在信任 Planner 实验之前,我现在问:
错误不在于前两场游戏看起来不错。
错误本该是就停在那里。
OpenAI: Introducing Structured Outputs in the API
Park et al.: Generative Agents: Interactive Simulacra of Human Behavior