# 第 5 集 · 仓储调度 这一集不打对战,比的是改代码。12 个模型分成 6 支"主程 + 测试手"的双人队,接力优化一份又慢又乱、还藏着 5 个必须保留的怪行为的 C++ 仓储机器人调度仿真程序:主程先在输出逐字节不变的前提下提速,测试手给别队的代码找反例,然后测试手接手本队主程的代码,实现需求变更并继续优化。五份成功的终版比原始代码快了约 400~2700 倍,快到碰到了 Windows 计时精度的下限。 比赛内部文件(成绩表、矩阵、裁判脚本和它们的文件名、第 1 轮的提示词和任务说明)里,"测试手"写作"攻手","找反例"写作"击穿"或"攻击","没找到"写作"守住","抗反例"写作"抗击穿"。这些是改名前的旧称,说的是同一件事;这些文件是比赛原件,没有改。改名是因为原来的说法(攻防、击穿)被 Claude 和 OpenAI 的安全机制当成网络攻击任务拦下过,经过见 `CONDITIONS.md`。 ## 规则速览(完整规则见 `workspace/TASK.md` 和 `packages/`) - **分队**:主办方把 12 个模型分成两档,一档 6 个当测试手,另一档 6 个当主程,两档之间随机配对(种子 20261006,名单和抽签程序见 `referee/抽签.py`)。 - **第 1 轮 · 主程**(建议 30 分钟,45 分钟强制停止):拿到原始代码(`workspace/baseline/`,下文叫基线)、过时的旧文档和 5 组公开负载,任意改写 `src/`。对任何合法输入,输出都必须和基线逐字节相同。交卷前写一份给队友的交接文档 `HANDOFF.md`。 - **第 2 轮 · 测试手**(上限 45 分钟):拿到另外 5 队主程的代码,构造合法输入找反例。输出不同、异常退出、60 秒内没结束都算。每份代码最多交 3 个用例,按"缺陷点"计分,越少人找到的越值钱。 - **第 3 轮 · 测试手**(新会话,上限 45 分钟):接手本队主程的代码,修好别人找到的反例,实现需求变更(订单老化、载货耗电、报表多一个字段,见 `packages/round3/workspace/CHANGE.md`),然后尽量优化。 - **基线里的陷阱**:取消失败也计数、救援只充一半电、充到 90% 就离开充电桩、距离相同选编号大的机器人、平均延迟四舍五入。旧文档和代码注释写的都是另一回事,只有和基线对拍才能发现。 - **计分**:输出错误的负载速度分为 0,正确率另计;速度按对数加速比计分。团队 100 分 = 主程速度 15 + 抗反例 10 + 主程盲评 5 + 找反例 20 + 接手正确 20 + 接手速度 20 + 终版盲评 10。另有主程榜和测试手榜。 - **赛后**:三个参赛模型当裁判,盲评 12 份匿名代码的可维护性(计分);终版复测和终版体检不计分。 ## 成绩 团队总分(各分项都是 0~100,按上面的权重加权): | 名次 | 队 | 主程(工具) | 测试手(工具) | 总分 | 主程速度 | 抗反例 | 主程盲评 | 找反例 | 接手正确 | 接手速度 | 终版盲评 | |---:|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:| | 1 | 队F | MiMo V2.6 Pro(OpenCode) | GPT-6 Astra(Codex) | 90.8 | 99 | 59 | 70 | 100 | 100 | 94 | 78 | | 2 | 队C | Gemini 3.8 Flash(Antigravity 命令行) | GPT-6.1 Sol(Codex) | 77.9 | 99 | 0 | 48 | 79 | 100 | 98 | 52 | | 3 | 队A | Kimi K3(Kimi Code) | Sonnet 5.5(Claude Code) | 71.4 | 96 | 96 | 57 | 22 | 100 | 71 | 60 | | 4 | 队D | DeepSeek V4.1 Flash(dsh) | Opus 5.5(Claude Code) | 70.3 | 45 | 27 | 45 | 60 | 100 | 100 | 65 | | 5 | 队B | 豆包 Seed 2.1 Turbo(OpenCode) | Fable 5.1(Claude Code) | 56.4 | 46 | 0 | 35 | 35 | 100 | 72 | 63 | | 6 | 队E | GLM 5.3(ZCode) | Grok 4.7(Grok Build) | 20.4 | 39 | 8 | 48 | 33 | 0 | 0 | 48 | 主程榜(第 1 轮的速度、被几位测试手找到反例、盲评): | 名次 | 主程 | 工具 | 得分 | 隐藏负载平均加速 | 被几人找到反例 | |---:|---|---|---:|---:|---:| | 1 | Kimi K3 | Kimi Code | 89.4 | 88 倍 | 0 | | 2 | MiMo V2.6 Pro | OpenCode | 80.8 | 102 倍 | 2 | | 3 | Gemini 3.8 Flash | Antigravity 命令行 | 57.6 | 101 倍 | 5 | | 4 | DeepSeek V4.1 Flash | dsh | 39.3 | 8 倍 | 2 | | 5 | GLM 5.3 | ZCode | 30.2 | 一组超时 | 4 | | 6 | 豆包 Seed 2.1 Turbo | OpenCode | 28.7 | 8 倍 | 5 | 测试手榜("增值"是同一批数据上终版比主程原版快多少倍,括号外是换算后的分数): | 名次 | 测试手 | 工具 | 得分 | 找到的缺陷点 | 终版 9 组隐藏负载 | 接手速度 | 增值 | |---:|---|---|---:|---:|---|---:|---:| | 1 | GPT-6 Astra | Codex | 86.2 | 6 | 全部正确 | 94 | 53(31 倍) | | 2 | Opus 5.5 | Claude Code | 84.8 | 4 | 全部正确 | 100 | 100(629 倍) | | 3 | GPT-6.1 Sol | Codex | 79.1 | 4 | 全部正确 | 98 | 60(48 倍) | | 4 | Fable 5.1 | Claude Code | 65.3 | 2 | 全部正确 | 72 | 63(54 倍) | | 5 | Sonnet 5.5 | Claude Code | 55.1 | 2 | 全部正确 | 71 | 32(8 倍) | | 6 | Grok 4.7 | Grok Build | 15.4 | 2 | 全部出错 | 0 | 0 | - **每个模型每轮只跑了一次**,这是"这一场"的结果,不是能力排名。组队是抽签的,团队分里的接手速度大半继承自主程,增值又是接弱主程的测试手更容易拿高,三张榜都受队友影响。 - **第 2、3 轮是重赛**:第一次的第 2、3 轮因为提示词没讲清楚、各家条件不一致,整体作废后用新提示词、新包、新计分重跑,所以所有测试手都是第二次见到这道题。第 1 轮也是作废一次之后的重跑。 - **Grok 4.7 用的是官方账号**(经账号池调度,地址不公开)。它第 3 轮用满 45 分钟,交上来的代码一行没改,终版全部出错。这一轮的表现很反常,我们怀疑账号当时被官方降智,但无法从记录证实。成绩按规则计算,不代表它正常状态下的水平。 - **另有一支人工队**:两位人类选手各自做了第 1 轮主程的任务,拿到的选手包和 AI 相同。成绩是赛后在同一台机器上另测的,不计入上面三张榜。代码、交接文档和成绩见 `appendix/human/`。 - 完整成绩(逐组用时、相对基线的倍数、盲评、7 个缺陷点、终版复测和体检)见 `results/最终成绩.md`;工具、渠道、思考档、用时、所有作废和事故见 **`CONDITIONS.md`**。 ## 马上看 / 马上玩 **看成绩和过程**: - `results/最终成绩.md`:全部成绩表。其中"快到碰到计时精度下限"一节对比了初测和精确重测:前三名在轻负载上只用 0.03~0.05 秒,也就是 2~3 个计时刻度,好几组数字完全相同,所以正式成绩改用连跑多遍取平均的办法重测了一次。 - `results/round2/缺陷点归类.md`:第 2 轮找到的 7 个缺陷点。四家主程犯了同一种毛病(把基线"用到才算"的寻路改成提前算好缓存起来),随机对拍测不出来。 - `submissions/`:每个模型交的代码、交接文档、反例和说明,都是原样。 - `notes/`:赛前狠话和 12 个模型的赛后复盘。 **自己优化一遍**(需要 Python 3 和 g++,Windows 推荐根目录 README 里说的 w64devkit): ```bash cd workspace python tools/bench.py --baseline # 编译 src/,跑 5 组公开负载,和基线比对并报告加速比(基线第一次约 40 秒) ``` 先读 `workspace/TASK.md`,然后改 `src/`。这就是第 1 轮主程拿到的全部东西。 Windows 如果只把 w64devkit 放进仓库的 `tools/`、没有加入 PATH,请先在仓库根目录的 PowerShell 中运行 `$env:CXX = (Resolve-Path .\tools\w64devkit\bin\g++.exe).Path`,再进入 `warehouse/workspace/` 运行上述命令。复制工作区到别处后,同一终端里的设置仍有效。 **拿某个模型的代码来跑**:先把 `workspace/` 复制到别处,再把 `submissions/round1/<模型>/` 里的文件放进副本的 `src/`,运行 `python tools/bench.py`。要跑第 3 轮的终版,按下面的办法拼出接手包: ```bash cp -r workspace ~/warehouse-takeover cp -r packages/round3/workspace/. ~/warehouse-takeover/ rm -rf ~/warehouse-takeover/src cp -r submissions/round3/deepseek-v4.1-flash__opus-5.5 ~/warehouse-takeover/src cd ~/warehouse-takeover python tools/bench2.py # 查对错:4 组小负载 + 30 个边界用例 python tools/bench2.py --big # 看快慢:3 组大负载,显示相对参考实现的加速比 ``` `--big` 显示的加速比用的是比赛电脑上测的参考实现用时(`workloads2/big/reference_cpu.json`),换一台电脑只能看个大概。历史边界用例中有 6 个不满足合法性检查器的参数约束,保留原件用于复现;正式合法输入的范围和体检覆盖限制见 [审计补充](CONDITIONS.md#开源审计补充)。 **复现正式评测**:见 `referee/README.md`。隐藏负载、参考实现和裁判脚本都在 `referee/` 里。 ## 目录 | 路径 | 内容 | |---|---| | `workspace/` | 第 1 轮选手包(原样):任务说明 `TASK.md`、过时的旧文档 `SPEC.md`、基线代码、5 组公开负载、本地测试工具 | | `packages/` | 第 2、3 轮的包里固定的部分,以及赛后终版复测和盲评的说明(见 `packages/README.md`) | | `prompt.md` | 每一轮发给模型的提示词原文 | | `submissions/round1/` | 6 个主程交的代码和交接文档 | | `submissions/round2/` | 6 个测试手交的反例和说明,按"测试手 / 被测的主程"分目录 | | `submissions/round3/` | 6 份接手后的终版,目录名是"主程__测试手" | | `results/` | 最终成绩、逐组评测结果、初测结果、缺陷点归类、盲评、终版复测、终版体检(见 `results/README.md`) | | `notes/` | 赛前狠话、12 个模型的赛后复盘(见 `notes/README.md`) | | `referee/` | 裁判程序、参考实现、隐藏负载、出题时的可行性验证,以及复现办法(见 `referee/README.md`) | | `appendix/human/` | 人工队:两位人类选手的三份第 1 轮代码和交接文档,以及赛后另测的成绩(不计入正式成绩,见 `appendix/human/README.md`) | | `CONDITIONS.md` | 比赛条件与异常记录 | ## 和比赛时的差别 - **目录名**:比赛时主办方的目录是中文名(`裁判/`、`赛事/` 等),仓库里换成了英文骨架;除下面列出的开源修复和说明补充外,比赛材料内容没有改。所以成绩文件和裁判脚本里提到的 `赛事/…`、`裁判/…` 路径在仓库里要换一下,对应关系见 `referee/README.md`。这些文件里的"第 5 期"就是这里的"第 5 集","攻手"就是"测试手","抗击穿""攻击""击穿"就是"抗反例""找反例""找到反例","守住"就是没找到反例。 - **选手包**:`workspace/` 和第 1 轮发出去的 `workspace.zip` 内容相同(没有放压缩包本身)。第 2、3 轮每队拿到的包是用脚本现拼的,仓库里放的是固定部分和各队的回归用例,拼法见 `packages/README.md`。 - **裁判脚本**:除 `referee/评测.py` 增加续评版本校验和补跑内存检查、`referee/进度.py` 去掉一处本机目录名外,放出来的脚本和比赛时逐字节相同;`README.md` 和 `还原目录.py` 是开源时新增的文件。评测修复没有重算历史成绩,细节见 `referee/README.md`。有三个脚本没有放:`开跑.py`(命令行席位的启动脚本)、`查用量.py`、`隔离测试.py`,里面是本机各工具的安装位置、密钥文件位置和账号池的模型名。另外拿掉了 5 个比赛当时的内部脚本(`夜间彩排.py`、`夜间审计.sh`、`夜间评测.sh`、`赛后流水线.sh`、`计分_个人赛版.py`):前四个是把评测步骤串起来的批处理和彩排脚本,依赖本机已编译的程序和计时日志,单独跑不通;最后一个是早先个人赛赛制的计分,这一集没有用。评测、判定和计分不用它们。 - **模型产物没有改**:`submissions/`、盲评评分、复测说明、复盘回复都是逐字节原样,换行符不统一也原样保留。检索过本机用户名、邮箱、密钥和网址,没有命中,所以一处都没有替换。 - **没有放进仓库的**:各模型的原始会话日志;作废的各次开局和第一次比赛(第 2、3 轮)的数据;工具和密钥的配置说明原文(内容改写进了 `CONDITIONS.md` 的选手表);编译产物;第 1 轮赛后的预审反例。 - `notes/赛前狠话.md` 是按主办方的记录重排的,狠话本身是原话。