RealtimeCUA Bench · 本地原型已实现 · v0.4.0

rcua_ticket_002

国际票务站形态的定时开售抢票任务。rcua_ticket_001 测的是单点反应速度——开售后一秒内能不能提交;这一题测的是压力下的流程完整性与克制:十二步主线、三类阻断、五类干扰,外加一个只有打开开关才看得见的预算陷阱。

12 步主线 90 个冻结 episode 54 个编号分区 3 档难度 71 项契约测试 评分 1.0 / 0.6 / 0

01概览

页面就绪后三十秒开售,三百四十个竞争买家按冻结的时间表吃掉库存。agent 要在目标区售罄之前,为两位指定观演人买到两张 Floor GA 票,含费总价不超过 760 美元。

三件事决定了这题是否成立:deadline 必须有物理意义(售罄时刻由竞争者时间表事后决定,不是谁拍板定的数字)、预算是含费总价而列表默认显示面价、浏览不持票(选中一条票不构成占位,只有进入结账才有三十秒持票)。最后一条看起来像细节,但它正是实时性的来源——详见第五节。

判分不看截图。评分逐条重放服务端事件日志:事件序号与时间单调、竞争者时刻与冻结时间表一致、库存账本逐笔自洽、费用算术、订单与某次 pay 动作对得上。模型自报完成不算成功。

02流程与界面

七个页面,形态照大型国际票务站的购票流程:演出详情 → 排队室 → 票务页 → 实名观演人 → 验证滑块 → 结账 → 订单确认。站名、艺人、场馆、观演人和订单全部虚构,品牌中性。

场馆图:54 个编号分区围成碗形,舞台一侧敞开,内场六个分区已变灰
场馆图。54 个编号分区围成碗形,舞台一侧敞开。这一局制作方撤走了 Floor,六个内场分区整块变灰。
内场 C1 分区的座位级视图,含费开关已打开
座位级视图。Floor 的 C1 分区,八排十四座。深蓝是够凑成两连座的块,浅蓝灰是只有零散座位的,浅灰不可售。含费开关已打开,两张 $526.10。
选中 Lower 109 分区 D 排后整块座位变绿
选中。点一个座位,它所在的整块变绿,右侧对应的票档高亮。这一块是 Lower 109 的 D 排 1–3 号。
实名观演人选择页
实名观演人。三人里恰好选对 Wei Zhang 和 Nina Li;数量对、人不对一样判 0。
拖动滑块验证页
验证滑块。容差 4%,拖错重抽目标位置。
结账页:持票倒计时与费用明细
结账。三十秒持票倒计时,Floor GA 的 H 排,含费 $526.10;支付有 30% 概率抛 High demand。

场馆图与座位级视图

五十四个编号分区:内场 A1–C2(6)、下层 101–118(18)、上层 201–224(24)、包厢 S1–S4(4)、无障碍 ACC W/E(2)。能买的是同一排相邻座位组成的块,不是单个座位,所以找到目标意味着先认出分区、再认出排。

页面只公布当前打开的那一个分区的座位,不会同时给出所有分区的座位数——把它们加起来就是剩余库存,也就是 deadline。一个分区的票卖完或被撤走,整块在图上变灰。

售罄按连座算。一个区在再也凑不出整组连座时才算没了。一张没人要的散票不会让 deadline 悬着——这一条是做座位图时才发现必须改的:按座位数归零算的话,有的 episode 会永远不售罄。

03七项机制

每一条都是这类网站的真实机制,不是装饰。橙色是阻断——不处理就过不去;灰色是干扰——踩中不扣分,但单列误触发率。

阻断

排队室

自动前进,但刷新会打回队尾。页面上明写着别刷新。

阻断

滑块验证

拖动容差 4%,拖错则重抽目标位置。

阻断

插页浮层

开售后 0.5–6 秒随机出现,不关则全局锁死。

陷阱

含费价格开关

默认关。预算 760 美元是含费总价,列表却只显示面价。

陷阱

持票计时

结账三十秒倒计时,超时座位退回库存池。

陷阱

高需求支付错误

30% 概率,是真重试不是假失败。

陷阱

转售放货 / 制作方扣票

转售加价 1.45 倍容易撞破预算;扣票直接撤走整个 Floor 区。

干扰

开售前的按钮

点了罚 2.5 秒冷却。

干扰

cookie 条 / 推荐轮播

开场即在,整局不消失。

干扰

插页上的 Subscribe

和必须点的 × 并排。

干扰

upsell toast

每个停留六秒,每局 2–5 个。

04一局的时间线

t2 标准档。横轴是服务端单调时钟的秒数;把指针移到任一标记上看它是什么。

色带是 Floor 区售罄时刻在三十个 episode 中的分布(第 10 百分位到最大值)。分布很窄且偏右:十一个 episode 的 Floor 被制作方提前撤走,所以 p10 比中位数早得多,其余局的售罄时刻挤在中位数附近。

05实时性从哪来

早先的版本沿用了项目更早的原型的一条规则:竞争者拿不走 agent 已经选中的票。写出来才发现这条规则把整题掏空了——开售瞬间随便点一张 Floor 票,之后慢慢做一百秒照样赢。

第一次完整跑浏览器流程时就撞上了:

deadline_ms            110433     ← 预测 Floor 110.4 秒售罄
order_committed_ms     131278     ← 我 131.3 秒才下单,仍然买到
want_zone_sold_out_ms  131278     ← Floor 最后一批是被我自己买走的

真实站点是到结账才持票,选中不等于占住。改成只有结账持票期间受保护之后,参考解的失效点整体前移了一档,三档难度也因此重新标定了一轮。

代价是票会在犹豫时被买走。为了让这份压力可见而不是无声——一个静静变灰的按钮,截图 agent 很难察觉——服务端会清空选择、给出提示,并记一条 selection_lost 事件,计入 selections_sniped。

06评分与指标

1.0

买到 + 含费总价 ≤ 760 美元 + 2 张 + 恰好是 Wei Zhang 和 Nina Li + Floor GA

0.6

同上,但换了别的区。制作方扣票撤走 Floor 时,这就是正解——三十个 episode 里有十一个是这种局。

0

没买到 / 超预算 / 票数不对 / 勾错人 / 重复下单 / 超时

超预算订单不会被服务端拦截。真实站点不知道你的预算;拦了的话 agent 立刻得到反馈改选,陷阱就不存在了。订单照常成交,评分判 0。

另报、但不进 score 的指标

指标含义
false_trigger_rate踩中的干扰项 ÷ 该局实际出现过的克制机会
fees_revealed整局是否打开过含费开关
deadline_margin_ms目标区售罄时刻 − 下单时刻
selections_sniped选中的票被竞争者买走的次数
blockers_shown / cleared排队室、滑块、插页各出现与清除几次
hold_expirations持票超时次数
high_demand_retries真重试次数
early_attempts开售前点按钮的次数

读结果必须同时看 score 和误触发率:一个见什么点什么的 agent 完全可能拿到高分。

07难度标定

脚本参考解既是可解性证明,也是标定工具:它在假时钟上每个动作收固定的思考时间,于是「这档能不能解」变成一个可测量的问题。下面的数字来自三十个种子的实测。

每步延迟 → 三档得分

拖动,或点一个实测模型
1.40 s
t1 宽松 t2 标准 t3 紧张
t1 与 t2 在 1.4 秒及以下完全重合,图上 t2 画在 t1 之上。上限是 0.907 而不是 1.0——每档各有十一局被扣票撤走 Floor,那些局的正解本来就是 0.6。
每动作延迟t1t2t3

参考解是 oracle。它直读滑块目标、选票最优、零感知误差。这是上界,不是对真实模型的预期;难度是对着它标的,不是对着真实模型标的。

08演示回放与完成情况

真实运行,按实际节奏重建:每张截图停留到下一张截图出现为止,所以模型想得慢,画面就停得久。红框是点击位置。下面的步骤表和视频同步,点任意一行可以跳到那一步。

GPT-6.1 Sol · t1 / ep00

0 分 · no_orderreasoning low单局样本

服务端日志:开售前 5.8 秒点了一次 Find Tickets(被拒,计一次误触发);开售后 36.3 秒进入票务页,随即弹出插页,直到 65.4 秒才关掉(其间有一次 25.7 秒的推理尖峰);73.5 秒打开含费开关,80.0 秒打开分区,84.3 秒选中第一块,89.5 秒到观演人页。第一个竞争买家在 91.2 秒到达,此后它选中的票被抢走 4 次(93.5、103.2、110.2、139.3 秒),竞争者购买的中位时刻是 123.2 秒。Floor 在 124.6 秒售罄,它在 146.7 秒放弃。n = 1,不能据此说 GPT 在 t1 得 0 分。

脚本 oracle · t1 / ep07

1.0 分 · correct_order不是模型每步 1.4 s

读 DOM 的脚本,不看截图,每步扣 1.4 秒假装推理延迟。它存在是为了证明流水线和任务可解,不能放进任何模型成绩表。Floor GA 两张,Wei Zhang + Nina Li,$573.30,deadline 余量 69 秒,误触发 0/8。

GPT-4o · t1 / ep00

0 分 · no_order无 reasoning单局样本

开售前老老实实等了约 28 秒,只点了 cookie 的接受;32.3 秒第一次点 Find Tickets,点在了 (219, 441) 像素,按钮的范围是 x 88–278、y 466–522,落在按钮上沿上方 25 像素。之后同一个坐标又点了 24 次,一次都没点中,也没有调整。整局没有进过票务页,一直耗到 episode 结束,没有主动 finish。同一套坐标换算下 GPT-6.1 Sol 点中了同一个按钮,所以这不是 harness 的偏差。n = 1。

GPT-6.1 Sol · 2528 harness · 第一局

0 分 · no_order2528 harness单局样本

走得最远的一局:清掉排队室和插页,打开含费开关,三次到滑块页才过(前两次都因座位被抢被送回),162.7 秒进入结账。但结账持的那一块只剩 1 个座位,付款被拒(“Those seats are gone”),没有订单。第 41 步和第 61 步是先 mouse_move 到滑块把手、再 left_click_drag 的两步拖动。这一局跑在引擎修复之前,见下文。

GPT-4o · 2528 harness

0 分 · no_order2528 harness无 reasoning单局样本

这一次点中了 Find Tickets(36.2 秒进入票务页),过了排队室,然后在插页上点了 4 次 Subscribe、一次都没点 ×,被插页挡到 episode 结束,没有进过选座。这正是插页上“Subscribe 与 × 并排”的设计在起作用。

视频是用保存的截图和动作时间戳重建的,不是屏幕录制。横条上的蓝线是开售,橙线是目标区售罄,橙色粗刻度是推理超过 8 秒的那几步。

各步完成情况

下面是两个模型这一局各自做到了哪一步,来自服务端事件日志,不是模型自述。✓ 是真的发生了,✗ 是没有。

GPT-6.1 SolGPT-4o
开售前后
开售前按兵不动✗ 5.8 秒点了一次 Find Tickets,被拒,计一次误触发✓ 等到约 28 秒,32.3 秒才第一次点
别碰 cookie 条✗ 点了接受✗ 第一个动作就点了接受
点中 Find Tickets 进入票务页✓ 36.3 秒✗ 点了 25 次,全部落在按钮上方
票务页
排队室(没有刷新)✓ 自动通过—
关掉阻断插页(用 ×,不点 Subscribe)✓ 65.4 秒,挡了约 29 秒—
数量改成 2✓—
打开含费价格开关✓ 73.5 秒—
找到 Floor 分区并选中座位✓ A1 分区,84.3 秒选中—
之后的步骤
到达观演人页✓ 两次,每次都因座位被抢被送回—
勾选 Wei Zhang 和 Nina Li✗ 0 次—
滑块 / 结账 / 支付✗ 没到—
订单00
结局与成本
结局146.7 秒自己发出 finish,此时未买到票耗到 episode 结束,没有 finish
误触发2 / 91 / 7
选中的票被抢走4 次0 次(从没选过)
推理延迟 p50 / 最大4.1 s / 25.7 s4.1 s / 5.6 s
步数 · 输入 token29 · 256,58244 · 280,431

GPT-6.1 Sol 的失败是被抢:流程走到了第三页,输在插页耽误的时间和竞争者到达之后反复被抢。GPT-4o 的失败是点不中:时序判断没问题(它等到了开售才动手),输在把按钮的位置判断错了,并且 25 次重复同一个错误坐标。前一种和这道题的设计直接相关(插页、选座被抢);后一种是对按钮位置的判断,和题目设计无关,换一道题也可能出现,这里没有做对照。

两个单局样本,不是成绩。每个模型各只跑了 t1 档的 ep00 一局,没有重复,不能据此排名,也不能说 GPT-4o 比 GPT-6.1 Sol 差。Qwen 没有跑。

换成 2528 的通用 harness 之后

你们站上 2528 的 harness(rcua_realtime_harness_2528.zip,40 KiB,已原样存进仓库的 harness_2528/,记了压缩包的 SHA-256)里,真正通用的只有一小块:realtime_runtime.py 规定了“WAIT 只表示这一轮不操作,不 sleep,下一张截图立刻开始”,再加上它的 EvoCUAAgent 提示词与历史、以及“流里一出现第一个完整动作就截断并执行”的选择器。这三块我原样导入,没有改。

跑法本身是 001 专用的,我只替换了它写死的部分:任务启动与评分(001 没有难度档和冻结 episode)、时间预算(001 是 100 步 / 90 秒外加固定睡 62 秒,002 用 episode 自己的时长,然后等世界走完)、模型入口(它走的是内部网关和密钥文件,这里换成任何 OpenAI 兼容地址加环境变量里的 key),以及拖动:它的 gui_executor.py 对 dragTo 直接抛错(001 没有拖动),而 002 的滑块必须拖。EvoCUA 的 left_click_drag 只有终点,所以模型要先 mouse_move 到把手,我在执行器里记住指针位置来补上。

GPT-6.1 Sol 第一局GPT-6.1 Sol 第二局GPT-4o
开售前后
开售前别点按钮✗ 4.3 秒点了,被拒✗ 2.8 秒和 8.9 秒点了,被拒✓ 没点
点中 Find Tickets✓ 32.1 秒✓ 32.3 秒✓ 36.2 秒
排队室✓ 34.4 秒通过✓ 34.6 秒通过✓ 38.5 秒通过
关掉插页(用 ×)✓ 37.4 秒✓ 43.0 秒✗ 点了 4 次 Subscribe,从没关掉
票务页
打开含费开关✓ 48.0 秒✓ 51.5 秒(来回开关了 3 次)✗ 没打开
开分区、选座✓✓✗ 被插页挡住,没进过
到观演人页✓ 77.3 秒,共进入 4 次✓ 69.8 秒,共进入 2 次✗
观演人页的勾选动作4 次3 次0 次
之后的步骤
过滑块✓ 162.7 秒(第 3 次到滑块页才过)✗ 没到✗ 没到
到结账页✓ 162.7 秒,持的块只剩 1 个座位✗ 没到✗ 没到
支付✗ 被拒(座位已被买走)✗ 0 次✗ 0 次
订单000
结局与成本
选中的票被抢走5 次5 次0 次(没选过)
误触发2 / 9(开售前按钮、cookie)2 / 9(同左)1 / 9(插页上的 Subscribe)
结局172.2 秒自己 finish148.5 秒自己 finish耗到 episode 结束
步数665278
推理延迟 p50 / 最大2.5 s / 4.2 s2.5 s / 10.7 s2.2 s / 3.1 s

三局都是 t1 档的 ep00,都是 0 分。GPT-6.1 Sol 两局都走过了排队室、插页和含费开关,输在选中的票被反复抢走。GPT-4o 输在插页:点了 Subscribe 而不是 ×。第一局跑在下面第一个缺陷修复之前,第二局和 GPT-4o 跑在修复之后。

更正上面“点不中”那一条。GPT-4o 在我自己写的 harness 下对 Find Tickets 点了 25 次、全部落在按钮上方;换成 2528 的提示词和 agent 之后一次就点中了。所以那个“定位不准”的结论至少有一部分是我自己 harness 的产物,不是 GPT-4o 的稳定特性。这也是为什么要换成通用 harness。

跑真实模型暴露的两个缺陷

  • 半买的块仍算选中(引擎):GPT-6.1 Sol 选中的块有 3 个座位,竞争者先买走 2 个,只剩 1 个。引擎只在整块买光时才判选择失效,所以它带着一块凑不齐两连座的票走完观演人、滑块,到结账付款才被拒。现在座位数一低于份数就判失效,并把已经走到观演人页或滑块页的人送回选座页。
  • 评分器与引擎对“持票保护”的理解不一致(评分器):付款被拒后引擎清空了选择,保护随之消失,竞争者随后买走了那一块;评分器却认为保护要到离开结账页才解除,于是把这份合法的日志判成非法。现在选择丢失或付款被拒都视为保护结束。那份真实日志已存成回归夹具。

这两个缺陷都是单靠脚本参考解和离线测试找不到的:前者要有人在半买的块上继续往前走,后者要有人走到结账再付款失败。

和 001 的 2528 数字的可比性,现在好了一些,但仍不是同一个实验。运行时语义、提示词、历史(4 轮)、流式取第一个完整动作都和 2528 一致。仍然不同的有:GPT 走的是 api.openai.com 的 Responses 接口,不是 AI Hub 的 Azure;任务不同(002 比 001 长、多拖动);和 2528 一样,指令里每一步都带“已用时间”;流在第一个完整动作处被截断,所以拿不到 token 用量。三局都是单局,不是成绩,Qwen 没有跑。

09与大麦版 rcua_ticket_001 的对比

两题是同一条赛道上的两个难度。001 的失败只可能来自反应时间:GPT 第一轮的失败是 58.25 秒取图、63.18 秒才执行提交,错过了 60–61 秒的窗口。002 里失败可以来自许多别的地方:没打开含费开关、刷新了排队室、点了插页上的 Subscribe、认错了座位、勾错了人。一个只有时序压力,一个把时序压力放进了一整条流程里。

rcua_ticket_001 · 大麦rcua_ticket_002 · TicketVault
形态与来源
站点与语言大麦风格,中文;周杰伦演唱会上海站,虚构场馆。参考了大麦公开页面与官方购票指南,参考记录里有四个实际访问过的 URL。国际票务站形态,英文;ECHO NOVA 巡演,虚构场馆。没有打开过任何真实票务站点,参考记录里没有 URL,只有项目自己的原型。
考点单点反应速度:开售后一秒内能不能提交订单。压力下的流程完整性与克制:十二步主线,三类阻断,五类干扰,一个预算陷阱。
一局发生什么
页面四个界面:项目详情选场次 / 票档 / 数量 → 订单确认选观演人 → 提交订单 → 待支付结果。七个页面:演出页 → 排队室 → 票务页(含场馆图与座位级视图)→ 观演人 → 验证滑块 → 结账 → 订单确认。
必需步数约 5 步(设计估计,未实测)。12 步(浏览器参考流程实测)。
开售页面就绪后 60 秒。开售前可进入订单确认页预填信息,只有最终提交才竞争库存。页面就绪后 30 秒。开售前可浏览、选区,但选中不占座,只有进入结账才有 30 秒持票。
库存2 场次 × 3 票档 = 6 个 SKU,每个 12 张,共 72 张,一张票对应一个竞争买家。54 个编号分区,约 272 个 listing(同一排相邻座位的块),340 个竞争买家。
购买单位一个 SKU(场次 × 票档)。一块相邻座位。先认分区,再认排,才找得到目标。
数量与观演人1 张,林小雨。2 张,必须恰好是 Wei Zhang 和 Nina Li(三人里选二)。
预算总价 ≤ 680 元,等于单价,没有额外费用。含费总价 ≤ $760。列表默认只显示面价,打开 Prices with fees 才看得到含费价。预算陷阱。
时间与 deadline
竞争者首个在开售后 0.18 s 到达,最后一个恰在 1 s 处到达,中间时刻由固定种子生成。到达时刻由对数正态时间表决定,随 episode 冻结。
deadline配置直接规定:sellout_window_s = 1。事后重放得到:目标区售罄的时刻。t1 / t2 / t3 的中位数分别是开售后 95.5 / 41.0 / 25.3 秒。
难度单一配置。三档(t1 宽松 / t2 标准 / t3 紧张),只改竞争者节奏,机制不变。
会让人失手的东西
阻断无。排队室(刷新回队尾)、滑块验证(容差 4%)、阻断式插页。
干扰无。引擎里没有任何干扰项事件。开售前的按钮、cookie 条、推荐轮播、插页上的 Subscribe、upsell toast;误触发率单列。
其他扰动无。转售放货(加价 1.45)、制作方扣票(撤走整个 Floor)、30% 高需求支付错误、持票超时。
评分与证据
分数二值 0 / 1。三档 1.0 / 0.6 / 0:换区买到也在预算内算 0.6;另报 false_trigger_rate 等副指标,不进分数。
评分器重放服务端日志。23 条断言,9 种事件。重放服务端日志,逐个 listing 跟踪库存并重新推算每个竞争者该买哪一块。59 条断言,23 种事件。
episode单个 scenario + 固定种子 20261018。90 个冻结 episode(3 档 × 30)+ MANIFEST,评测集固定前 5 个。
工程
代码行数engine 197 · app.js 92 · reward 122。engine 660 · app.js 590 · reward 356 · 另有 episode.py 349。
测试12 项后端契约测试。101 项(后端契约 71 + 评测 harness 30)。
开售时刻支持 --release-at 指定带时区的绝对开售时间。没有这个选项,只有页面 ready 后的相对时间。
OSWorld 入口把整份配置内联成字符串字面量,并钉 bundle 哈希。钉死 tier、episode id 和 config / episode 两个哈希,世界本体走资源包。
模型评测已跑:原始 Qwen3.5-4B 0/5(prompt v2 为 1/5)、GPT-6.1 Sol 0/5,另有逐局回放与成功样本视频。只有 1 局 GPT-6.1 Sol 样本,0 分,下面有回放。Qwen 和其余档位没跑。

有意保持一致的部分

  • 服务端权威时钟,与模型推理和浏览器轮询无关;刷新不重置。
  • 评分只看服务端事件日志的重放,截图和页面文字不是输入;模型自报完成不算成功。
  • 幂等的 request_id,换标识也不会重复生成订单。
  • 没有对 agent 开放的 reset、改时钟、改库存或读评分的接口。
  • 仅标准库 + 浏览器,无 CDN、无外部素材。

002 比 001 少的东西

  • 没有绝对开售时间(--release-at)。
  • 没有真实站点的参考记录:001 记了四个访问过的 URL,002 老实写的是没有。
  • 几乎没有模型评测:001 有 Qwen、GPT 各 5 局和成功样本视频,002 只有上面这一局。

可比性。002 的 GPT 样本用的是自己写的 harness,只近似 001 评测所用的 realtime-back-to-back-v1(背靠背截图、wait 不额外等待、世界不暂停),没有实现“收到第一个完整动作就执行”。所以它能和之后用同一个 harness 跑出来的 002 数字比,不能直接和 001 页面上那些已发布的数字比。

10冻结 episode 集

三档各三十个 episode,共九十个,加一份 MANIFEST.json。只存种子是不够的——生成器改一行,已发表的数字就悄悄变成关于另一个世界的数字。

MANIFEST 记录每局的文件 sha256、journal 会写入的规范化 episode sha256、以及该档的 config sha256。评测集固定前五局,其余二十五局 held-out。

python3 tools/make_episodes.py --verify

六项验收:文件哈希 · 规范化哈希 · 每局仍能由自己的种子逐字节重建 · 各档 config 仍与当前 scenario 吻合 · 九十局 deadline 全部有限 · 十五个评测 episode 各跑两遍世界逐事件相同。另外独立生成两遍比对,九十个文件逐字节相同。

按 id 启动时会再核对一次哈希。磁盘上被改过一个字段的 episode 会被拒绝启动,服务端根本起不来,而不是跑完九十秒再在评分时发现世界不对。

一个 episode 文件里有什么

以 t1/ep00.json 为例(44 KiB)。整场竞争在开始前就排定了,下面是它的全部内容,数字都取自这个文件。

字段内容
competitors340 条 [时刻, 目标分区, 张数],例如 [91.1871, "Lower", 2]、[92.9641, "Floor", 3]。到达时刻、偏好分区和张数都是排定的,不是运行时随机,这是实时场景能复现的关键。具体买走哪一块,由当时的库存按规则推出(先本区、买能凑够人数的最小块、不动结账正在持有的座位),所以 agent 的选择会影响哪一块被买走。
listings272 条原价票,每条带 section / row / seat_from / 座位数 / 价格,例如 {"id": "LFL00", "kind": "standard", "price_cents": 21000, "row": "E", "seat_from": 2, "seats": 2, "section": "A1", "zone": "Floor"}
resale_listings51 条转售票(加价 1.45 倍),只在转售放货时上架
disruptions这一局会出哪些扰动、什么时刻出:
queue: true, queue_init: 96 开售后进排队室,前面 96 人,每秒放行 45 人,刷新排到队尾
slider: true, slider_target: 0.738 要把滑块拖到 73.8% 的位置,容差 ±4%
interstitial: "app", interstitial_at: 34.451 第 34.45 秒弹出 App 推广插页
toasts: [31.706, 33.347, 37.129, 38.28] 加 toast_texts:4 条升级 / 酒店套餐的推销浮层,每条停留 6 秒
resale_at: null, hold_at: null 这一局没有转售上架,也没有分区被撤走
ground_truth各分区的真实售罄时刻(Floor 124.6 秒,目标区 deadline)、最优合预算总价($514.30)、干扰机会数(9)。评分和标定用,页面上不会出现:模型看不到剩余票数、episode 时钟、售罄时刻。
seeds两个独立种子:err 管支付“高需求”报错,slider 管拖错后重抽的滑块目标。它们依赖 agent 的行为(第几次支付、拖错几次),没法提前排定,所以和世界生成分开。
{
 "tier": "t1",
 "seed": 0,
 "onsale_s": 30.0,
 "episode_len_s": 180.0,
 "competitors": [
  [
   91.1871,
   "Lower",
   2
  ],
  [
   92.9641,
   "Floor",
   3
  ],
  [
   93.4824,
   "Floor",
   2
  ],
  "… 共 340 条"
 ],
 "listings": [
  {
   "id": "LFL00",
   "kind": "standard",
   "price_cents": 21000,
   "row": "E",
   "seat_from": 2,
   "seats": 2,
   "section": "A1",
   "zone": "Floor"
  },
  "… 共 272 条"
 ],
 "resale_listings": "… 共 51 条",
 "disruptions": {
  "hold_at": null,
  "interstitial": "app",
  "interstitial_at": 34.451,
  "queue": true,
  "queue_init": 96,
  "resale_at": null,
  "slider": true,
  "slider_target": 0.738,
  "toasts": [
   31.706,
   33.347,
   37.129,
   38.28
  ]
 },
 "ground_truth": {
  "deadline_s": 124.5676,
  "sellout_s": {
   "Accessible": 140.7196,
   "Floor": 124.5676,
   "Lower": 132.1264,
   "Upper": 146.3028,
   "VIP": 124.6856
  },
  "n_distractors": 9
 },
 "seeds": {
  "err": 1112038970,
  "slider": 2087043557
 }
}

页面看不到,不等于磁盘上看不到。ground_truth 在 episode 文件里,episode 文件在 VM 的资源包里,服务端还会把 deadline 写进 record.json。当前的防护是动作空间只给截图和鼠标键盘、任务规则禁止读服务端文件,不是文件权限。一个有 shell 的 agent 读得到。这对只用 GUI 的评测没有影响,但如果将来开放终端,要先把 ground_truth 从 VM 里的 episode 文件中拿掉,只留在评测侧。

11交付与 OSWorld

任务包按站上已实现 sample 的格式交付:task.json、dependencies.json、provenance.json、reference_notes.md、README.md、checksums.sha256、OSWorld 入口与冻结评分器、单题清单、VM 资源包。打包脚本用固定时间戳与权限写 zip,同一棵树重复打包字节相同。

入口钉死两个哈希

更早的那题把整个配置内联成字符串字面量;这对四十五 KiB 的冻结 episode 不适用,所以改成世界走资源包、身份走哈希:

TIER           = 't2'
EPISODE_ID     = 'ep00'
CONFIG_SHA256  = 93ea1c4691d302c5eae33a7ce1b6ad40238b3535b484c7065f0143ee5ee9518a
EPISODE_SHA256 = 50189fc893f2727ee958c20a88c227a49224790d8b345606b1aaf2c192be1f72

evaluate 把 record、effective_config、effective_episode 三份都拉回评测侧,先确认两个哈希与钉死值一致再判分。为什么钉两个而不是一个:config 与 episode 若被成对换掉,二者彼此自洽,单钉一个查不出来。

12边界

  • 没有访问、抓取或复刻任何真实票务站点,因此没有可列的 URL。更早的那题记录了四个实际访问过的页面;这一题没有对应记录,不应被引用为任何真实平台的复刻。
  • 场馆图是几何规则生成的原创布局:椭圆碗加等分角度的分区,不对应任何真实场馆的分区表,也没有真实场馆那种不规则的看台形状与视线遮挡。座位级视图只有单个分区的行与座号。
  • 难度对着脚本参考解标定,没有用真实模型标过。
  • 真实浏览器走通了 1.0 与 0.6 两条正确路径,两次运行的竞争者购买都经过了 listing 级重放;超预算、票数错、勾错人、超时、重复下单由契约测试覆盖,未在界面中逐条复现。
  • 真实 OSWorld VM 的 setup / evaluate 尚未运行;模型闭环评测尚未进行。
  • 所有时间参数都是本实验配置,不代表任何真实票务平台的参数。支付为模拟,不执行真实付款,不收集支付信息。