Alice 写代码、Bob 找 bug、混元当裁判:我让 3 个 hy3 在两个 Cube Sandbox 里互相找茬

Alice 写代码、Bob 找 bug、混元当裁判:我让 3 个 hy3 在两个 Cube Sandbox 里互相找茬 Alice 写代码、Bob 找 bug、混元当裁判我让 3 个 hy3 在两个 Cube Sandbox 里互相找茬为什么要做这件事前面第 3 篇用了 1 个 Agent N 个沙箱做数据分析这次我想试更刺激的东西——让 LLM 互相找茬一个 Agent 写解法Alice攻方另一个 Agent 看完代码后写 testcase 攻击Bob守方第三个 Agent 看完 3 轮交互做仲裁Judge这个模式有意思的地方在它不靠人类设标准答案——Bob 自己设计期望值。所以裁判要同时评价Alice 的代码对不对和Bob 的 testcase 答案算得对不对是一种自洽性测试。更刺激的是跑完三轮我才发现Bob 反复找到 bug但每次都是 Bob 自己算错了答案。这个反转过程恰好揭示了一件事LLM 写代码可能比 LLM 算心算更靠谱。1. 架构3 Agent × 2 Sandbox3 个角色各自独立的 OpenAImessages历史互不可见对方的思考过程只可见对方的产出角色看得到的输入产出在哪里跑Alicehy3-preview题目 上轮 Bob 的 testcase 失败明细Python 解法代码Cube Sandbox A/workspace/solution.pyimport 自测Bobhy3-preview题目 Alice 当前代码全文Python testcase 脚本Cube Sandbox B/workspace/{solution,test}.pyrunpy.run_path触发Judgehy3-preview题目 3 轮 transcript 3 轮 PASS/FAIL结构化 JSON 判决无沙箱纯文本题目我选了LeetCode #3 最长无重复字符子串——经典、边界条件多空串、Unicode、emoji、超长输入适合 Bob 设计攻击 case。2. Round 1Alice 出招Alice 拿到题目后直接给出经典滑动窗口实现主要骨架hy3 写的原样deflongest_unique_substring(s:str)-int:char_index{}leftmax_len0forright,chinenumerate(s):ifchinchar_indexandchar_index[ch]left:leftchar_index[ch]1char_index[ch]rightifright-left1max_len:max_lenright-left1returnmax_len时间 O(n)、空间 O(min(n, charset))、滑动窗口配 last-seen-index 哈希表——是个对中文/emoji/控制字符都没特殊处理需求的实现因为 Pythonstr迭代本来就是 codepoint。Bob 拿到这段代码后写了 12 个 testcase。runpy.run_path(/workspace/test.py, run_name__main__)在 Cube Sandbox B 里跑PASS 10/12 [FAIL] unicode chinese emoji [FAIL] spaces and punctuation—— Bob 发现两个问题。Alice 没看到 Bob 的 testcase也不需要看只看到失败的输入和 Bob 预期的答案然后修代码。3. Round 2 / Round 3每轮 Bob 都找到新 bugAlice 在 R2、R3 微调了字典初始化、注释等小处核心算法没变因为算法是对的。Bob 每轮都加新攻击 caseR213/15新增spaces and control chars和mixed case sensitiveR315/18新增surrogate pair、控制字符 标点组合等把三轮通过率画出来再把Bob 找到的所有失败逐项展开看真相最戏剧化的是 R3 这一轮。我把 Bob 在 Cube Sandbox B 里的真实运行 stdout 截下来[FAIL] control chars punctuation input: a\tb\nc d,e! expected: 8 actual: 10 [FAIL] mixed case sensitive input: AaAaBb expected: 3 actual: 4 [FAIL] surrogate pair repeat input: \ud83d\ude00\ud83d\ude00 expected: 1 actual: 2每个失败都看起来很专业。但我手算了一下输入Bob 期望Alice 输出实际算一下a\tb\nc d,e!81010 个 char 全不重复a,\t,b,\n,c,space,d,comma,e,! ✅ Alice 对AaAaBb34A,a,A,a,B,b区分大小写→ 最长aAaB或AaBb长 4 ✅ Alice 对\ud83d\ude00\ud83d\ude0012Pythonstr里这是 4 个 char两个 surrogate × 2最长前 2 个不重复长 2 ✅ Alice 对三个失败全部是 Bob 自己算错了期望值。Alice 的代码从 R1 到 R3 都没错过错的是 Bob 算心算。4. Judge 出场混元怎么看这场对决裁判看完 3 轮完整 transcript含每轮 Alice/Bob 代码 沙箱真实 stdout后返回结构化 JSONJudge 的核心结论原文照抄alice_score: 9, bob_score: 8, winner: alicealice_reviewAlice 的代码采用滑动窗口哈希表的标准解法时间复杂度 O(n)、空间复杂度 O(min(n,字符集))完全符合题目要求。代码正确性上对空串、单字符、全重复字符、经典 ASCII 用例、Unicode 中文/emoji、大小写敏感场景均能正确处理仅 Bob 设计的 3 个特殊用例控制字符组合、大小写重复、surrogate pair的预期值存在偏差实际输出符合最长无重复子串的定义代码本身无逻辑错误。bob_reviewBob 的测试用例设计覆盖度较好包含边界场景空串、单字符、全重复、经典用例、Unicode 中文/emoji、控制字符、空格标点、大小写敏感、surrogate pair 等多类场景攻击力度较强但存在 3 处预期值设计错误控制字符组合、大小写重复、surrogate pair 用例的实际最长无重复长度与预期不符说明对题目规则的理解存在偏差部分用例的预期值计算不准确影响了测试的有效性。verdictAlice 的代码实现完全符合题目要求逻辑正确且性能健壮Bob 的测试用例覆盖全面但存在部分预期值错误整体 Alice 表现更优。Judge独立看出来了那 3 个 case 是 Bob 算错——而且原因和我手算的一模一样。这是个挺重要的信号LLM-as-Judge 在这种看代码读 stdout 推断逻辑的任务上是可靠的前提是你把上下文代码 stdout一次性塞给它让它推理而不是检索。5. 为什么这个故事值得讲我开始这个实验时的预期是Alice 多多少少会被 Bob 抓到 1-2 个 bug3 轮后修通。但实际情况是 Alice 的代码从 R1 到 R3 没有错过——因为 hy3-preview 写经典 LeetCode 算法的稳定性比预想好反而是 Bob 在算 testcase 期望值时一次又一次手算翻车。这个反转给我两条挺反直觉的工程经验LLM 写代码 vs LLM 算心算写代码生成结构的稳定性 算心算一步一步推数字。如果你的 Agent pipeline 里两步都要做让代码跑、再读 stdout 比让 LLM 直接给数字稳得多。这正是 Cube Sandbox 在 Agent 里的价值定位给 LLM 一个『可以验算自己结论』的真实环境。多 Agent 自洽性测试有意义但要小心Alice 和 Bob 共用同一个 hy3-preview。理论上他们对题目的理解应该一致结果在 Unicode/surrogate pair 这类细节上居然出现分歧——这正是对抗式纠错暴露 LLM 知识表征不稳定的地方。Judge 这一层非常关键不能只看 PASS/FAIL要看代码逻辑和数据本身。而 Cube Sandbox 在这个架构里的作用很纯粹它不参与对错的判断它只负责让代码真实地跑起来。Alice 和 Bob 看到的都是真实 stdoutJudge 看到的也是真实运行结果——三方共享同一个事实底座。如果用 Docker 默认配置跑两人各自的代码会怎样参见我上篇 [Cube Sandbox 攻击对照实测]——tcp 172.17.0.1:22 OPEN那张图那就是另一个故事了。6. 工程总结可复用的 4 条经验每个 Agent 独立messages历史不共享上下文Alice 永远看不到 Bob 的思考过程只看产出Bob 也一样。这是模拟黑盒攻击的关键否则 Bob 看到 Alice 的我担心 emoji 边界内心 OS就少了一半攻击想法。每个 Agent 独立 Cube SandboxAlice 的代码不能污染 Bob 的运行环境万一 Alice 的代码改了全局变量万一 Bob 的 testcase 把solution.py改坏了。Cube 65 ms 冷启动让多沙箱在工程上完全免费。runpy.run_path(..., run_name__main__)触发 testcase直接import test_module不会执行if __name__ __main__块——这是我第一次跑时的坑3 轮 stdout 全空。改用runpy.run_path后正常。Judge 一定要拿到真实 stdout不能只拿 PASS/FAIL如果只告诉 Judge “R3 通过率 15/18”它没办法判断那 3 个失败究竟是 Alice 错还是 Bob 错。把 sandbox stdout 完整喂给 Judge让它自己推理。7. 接下来还能玩什么这个对抗式 仲裁的范式可以扩展到很多场景N 个解法竞赛让 hy3 想 5 种不同思路暴力 / 双指针 / DP / 贪心 / 数学在 5 个沙箱并行跑同一组 testcase按性能 内存排名跨模型对抗Alice 用混元、Bob 用 DeepSeek、Judge 用 GPT-4——是个有趣的LLM 互测基准多语言对抗题目同一个Alice 写 Python、Bob 写 Rust testcase——配合我上篇文章的多语言 sandbox 用法但这些都是后话。这一篇我想说的最核心一件事是当你给 LLM 一个真实的代码运行环境比如 Cube Sandbox它从『会说』升级到『能验证自己说得对不对』整个 Agent 体系就开始有趣了。附录 A完整可复现代码scripts/debate.py~200 行。跑法exportOPENAI_API_KEYsk-...# TokenHub 的 keyexportOPENAI_BASE_URLhttps://tokenhub.tencentmaas.com/v1exportE2B_API_URLhttp://127.0.0.1:3000exportE2B_API_KEYdummyexportCUBE_TEMPLATE_IDtpl-...exportSSL_CERT_FILE/root/.local/share/mkcert/rootCA.pem python3 scripts/debate.py3 个角色的 system prompt、3 轮 transcript、Judge JSON 全部归档在transcripts/和logs/02_result.json。附录 B参考链接Cube Sandboxhttps://github.com/TencentCloud/CubeSandboxe2b-code-interpreter SDKhttps://github.com/e2b-dev/code-interpreter混元 OpenAPIOpenAI 兼容腾讯云 TokenHub本文 Alice、Bob、Judge 三个角色全部由腾讯混元 hy3-preview 扮演共享同一个 TokenHub API key、独立 messages 历史两个 Cube Sandbox 跑在 OpenCloudOS 9.4 PVM 内核上所有 stdout、判决 JSON、3 轮 transcript 均可独立复核。