CUA-Gym: Scaling Verifiable Training Environments and Tasks for Computer-Use Agents
Paper: arXiv:2605.25624 Code: xlang-ai/CUA-Gym Code reference:
main@1e50b797(2026-05-26)
1. Motivation (研究动机)
当前 Computer-Use Agent (CUA) 的 RLVR 难点不是缺少 RL 算法,而是缺少可规模化、可执行、可验证的训练环境。数学、代码、terminal-use 中的 RLVR 通常只需要“题目 + 可判答案/测试”,但 CUA 任务必须同时具备三件互相一致的工程产物:自然语言任务 、可复现初始环境状态 、以及能返回 分数的 reward function 。只要其中一环不一致,RL 得到的就不是“完成用户任务”的信号,而可能是奖励漏洞、环境偶然状态或无法复现的 UI 副作用。
这个瓶颈在 GUI 场景中特别尖锐。桌面和网页任务往往依赖隐含文件、账号状态、窗口布局、附件、表格内容、历史邮件、项目管理条目等上下文;同一句“整理报告并导出 PDF”在不同初始状态下可能对应完全不同的可行路径和验证逻辑。若没有可 reset / inspect 的环境,训练 worker 之间会互相污染;若没有程序化 reward,RL 会被迫依赖高方差 judge;若 reward 只检查粗略视觉结果,又无法稳定区分“正确编辑文件”和“碰巧生成相似截图”。
论文指出现有路线各有短板:监督轨迹数据覆盖面较广,但只有 imitation target,没有 outcome reward;VLM-as-a-judge 能评任意 GUI 结果,但 reward noise 会让 policy optimization 不稳定;一些 browser mocking / programmatic reward 管线能给 deterministic reward,却常被限制在少量网页环境或小规模任务集。手工写一个 (task, environment, reward) tuple 需要专家花数小时,而且新应用会引入新的文件格式、UI 状态、验证 API 与启动流程,导致应用覆盖越广,人工成本越不可控。
因此这篇论文的动机不是“再做一个 CUA benchmark”,而是把 benchmark 式的少量人工任务升级为训练数据供应链:任务要来自真实知识工作分布,环境要能批量实例化不同初始状态,reward 要能被 RL 大规模调用且尽量低噪声。只有同时满足这三点,CUA 才可能复用 math/code 领域已经验证过的数据扩展规律。
CUA-Gym 要解决的具体问题是:如何自动合成大量适合 CUA 强化学习的 (t,s,r) 训练 tuple,并让 reward 足够可靠,能够支撑 GSPO 等 RLVR 训练。这个问题重要是因为 GUI/desktop/web agent 的能力上限很大程度上受限于可验证训练数据供给;如果能把环境、任务和 reward 一起规模化生成,就能像 math/code RLVR 一样把“数据规模”变成 agent 能力增长的主要杠杆。
2. Idea (核心思想)
核心洞察:CUA RLVR 数据不能把 task、setup、reward 分开独立生成再事后拼接,而应该从同一个 topic / context 同源共生成;同时,写 setup 的 Generator 与写 reward 的 Discriminator 必须被信息隔离,逼迫 reward 从任务语义和环境状态判断完成度,而不是反向读取 golden-state 构造脚本。
这个想法可以理解为“用对抗式数据工程替代人工验收”。Generator 擅长把自然语言任务转成可执行初始状态和 golden state,但它不可信任 reward;Discriminator 擅长写验证器,但不能知道 golden_patch 的内部实现细节。两者之间只通过 Orchestrator 的结构化反馈迭代,使 tuple 通过 initial=0、golden=1、reward integrity 等端点约束。然后再用 dataset-level filter 捕捉 loop 内看不出的歧义、不可解、trivial 与 reward/视觉不一致问题。
本文的关键创新是把 CUA 训练数据构造成一个“可验证环境生产线”:Generator 生成 initial_setup.py 与 golden_patch.py,Discriminator 只看任务与 state-only 视图来写 reward.py,Orchestrator 用五个 agreement conditions 驱动多轮修正;在 tuple 级一致之后,再用 LLM majority voting 与 teacher rollout 做 dataset-level filter。为了突破真实网站不可 reset / inspect / parallelize 的限制,论文还合成 CUA-Gym-Hub:94 个 mock web apps,加上 16 个 desktop apps,形成 110 个环境的可复用 RL training substrate。
从方法谱系上看,CUA-Gym 不是单纯 dataset scaling,也不是单纯 environment cloning,而是把“任务采样、状态注入、程序化验证、过滤和 RL 训练接口”统一成一套闭环。它的贡献更接近 infrastructure paper:让后续 CUA post-training 能反复消费同一批可控环境,而不是每做一轮实验都重新人工写任务和评测脚本。
与 WebArena-Infinity / InfiniteWeb 等偏 browser、偏固定 mock 的路线相比,CUA-Gym 的本质差异不是只多生成任务,而是同时扩展三层:任务 tuple 的 programmatic verification、mock web environment 的 state API、以及 desktop+web 的跨应用覆盖;与 Gym-Anything 这类 VLM reward 路线相比,它强调 code-native / state-native reward,目标是降低 RL 训练中的 reward noise。
3. Method (方法)
3.1 总体框架:同源 tuple 生成 + 信息隔离 + 两级过滤
论文把 CUA RLVR 数据定义为: 其中 是自然语言任务, 是可复现初始环境, 是 terminal state reward。难点在于三者必须共同指向同一个任务目标:任务要有足够上下文,初始状态要真的可执行,reward 又要验证最终状态而不是验证 setup 过程。
Figure 1 解读:这张图展示从 task/context 到最终 dataset 的完整闭环。Generator 负责准备 initial VM 与 golden VM:前者运行 initial_setup.py 得到任务开始状态,后者运行 golden_patch.py 得到理想完成状态。Discriminator 不能读取 Generator 的脚本,只能看到任务语义和两个 VM 的 state-only 结果,因此它写出的 reward.py 必须真正比较任务完成状态。Orchestrator 用五个条件检查 tuple 是否可用,之后再交给 Filter 做 majority voting 与 teacher rollout。
直觉上,这个设计把“reward hacking”提前移动到数据生产阶段处理。若同一个 agent 同时写 golden state 和 reward,它很容易写出只检查自己脚本痕迹的 reward;信息隔离后,reward 只能基于任务语义、文件内容、结构化状态 diff 或视觉 judge 来评分,虽然不能形式化保证完美,但显著减少了反向工程 shortcut。
3.2 Task generation:从 feature taxonomy 到 instruction-context pair
CUA-Gym 先为每个应用构建 feature taxonomy tree:内部节点代表功能簇,例如 libreoffice_calc → formatting → conditional_formatting,叶子代表 atomic UI capability。树来自官方文档与 web research,深度限制为 ,每个节点 branching factor ,避免既过浅又不可采样。任务不是单独的 instruction,而是 instruction-context pair : 是用户式任务描述, 列出实体、文件、账号状态、应用状态与任务所需素材。
采样矩阵有五个维度:platform(desktop / web / cross)、domain(10 个 O*NET-aligned categories)、difficulty(easy / medium / hard;easy \le 3 atomic actions,medium 3–10 steps,hard 需要 long-horizon planning)、scenario(commercial / educational / scientific / personal)与 task type(single-app / cross-app)。生成分三轮:Pass 1 做 breadth coverage,保证每个 taxonomy leaf 至少 25 个任务;Pass 2 做 gap-fill,补齐低覆盖 cell,尤其提高 cross-app 与 hard 任务;Pass 3 做 edge cases,专门覆盖边界条件、非常规应用顺序与稀有动作原语(drag、hotkey chords、multi-window navigation)。
3.3 Adversarial Generator–Discriminator loop
Generator 与 Discriminator 是两个隔离角色。Generator 读取任务、上下文和 domain SKILL.md,写出 initial_setup.py 与 golden_patch.py;Discriminator 运行在单独 sandbox 中,不能读这两个脚本,只能看 与通过 API 暴露的 initial/golden state,然后写 reward.py 与 REVIEW.md。一个 tuple 在 loop 内被接受,当且仅当五个条件同时满足:
- C1:
initial_setup.py在 initial VM 上无异常完成; - C2:
golden_patch.py在 golden VM 上无异常完成; - C3: ;
- C4: ;
- C5:
reward.py不含 forbidden patterns,例如常量成功、只检查文件存在、subprocess外部调用、注释式假检查等。
def adversarial_tuple_generation(task, context, domain_skill, max_rounds=5):
initial_vm = provision_vm(task.id, kind="initial")
golden_vm = provision_vm(task.id, kind="golden")
feedback = None
for round_idx in range(max_rounds):
initial_setup, golden_patch = setup_gen(
task=task,
context=context,
domain_skill=domain_skill,
previous_review=feedback,
)
initial_vm.run(initial_setup)
golden_vm.run(golden_patch)
reward_py, review = reward_gen(
task=task,
context=context,
domain_skill=domain_skill,
initial_state=initial_vm.state_only_view(),
golden_state=golden_vm.state_only_view(),
)
r_init = run_reward(reward_py, initial_vm)
r_gold = run_reward(reward_py, golden_vm)
forbidden = static_scan_forbidden_patterns(reward_py)
if r_init == 0.0 and r_gold == 1.0 and not forbidden:
return {"task": task, "initial": initial_setup,
"golden": golden_patch, "reward": reward_py}
feedback = review.with_scores(r_init=r_init, r_gold=r_gold, forbidden=forbidden)
return None这段伪代码对应 released repo 中 .claude/agents/orchestrator.md、.claude/agents/setup-gen.md、.claude/agents/reward-gen.md 与 scripts/batch_orchestrator.py 的实际分工:batch_orchestrator.py 并不自己写 setup/reward,而是并发调度 Claude subagents,检查 output/final/<task_id>/config.json、reward.py、initial_setup.py、golden_patch.py 是否生成,并支持 retry / timeout / resume。
3.4 Dataset-level filter:LLM majority voting + teacher rollout
Loop-level acceptance 只能说明 initial/golden/reward 三者在端点上一致,不能保证任务不含歧义、不是 trivial、也不能保证真实 agent rollout 中 reward 与视觉结果一致。因此论文加入两级 filter。
第一层是 LLM majority voting。每个 critic 接收 (t, s_init, s_gold, r),输出 verdict、severity、query_issues、setup_reward_risks、training_pool_fit、confidence、reasoning_summary、revised_query 等结构化字段。严重性分为 P0 reject、P1 modify-query、P2 keep-or-modify、P3 keep。严格多数 keep 或 modify_query 才进入下一层;若多数是 modify_query,采用最高置信的改写 query。
def majority_vote_filter(task_dir, critic_model="gpt-4o", votes=3, write=True):
bundle = load_task_bundle(task_dir) # config.json + setup + golden_patch + reward.py
critic_outputs = [call_critic_once(critic_model, bundle) for _ in range(votes)]
valid = [v for v in critic_outputs if v is not None]
if not valid:
return {"verdict": "keep", "train_poor_fit": False, "revised_query": ""}
counts = Counter(v.get("verdict", "keep") for v in valid)
best_verdict, best_count = counts.most_common(1)[0]
final_verdict = best_verdict if best_count > len(valid) / 2 else "keep"
revised_query = ""
if final_verdict == "modify_query":
candidates = [v["revised_query"] for v in valid
if v.get("verdict") == "modify_query" and v.get("revised_query")]
revised_query = Counter(candidates).most_common(1)[0][0] if candidates else ""
if write:
update_config_json(task_dir, reject=(final_verdict == "reject"),
revised_query=revised_query, vote_breakdown=dict(counts))
return {"verdict": final_verdict, "vote_breakdown": dict(counts)}论文公式与 released code 实现差异:论文 Appendix A.4.1 写的是“ties default to rejection”,但 released filter/majority_vote_filter.py 中 aggregate_votes() 在没有 majority 时把 final_verdict 设为 keep;默认 --votes 3 降低了平票概率,但如果有效票数不足或改成偶数票,这个实现会比论文描述更宽松。论文还描述 teacher rollout + VLM-as-a-judge 的第二层过滤,但当前 released repo 没有发现完整 teacher-rollout filter 脚本;filter/majority_vote_filter.py 只实现了 majority-vote 阶段,README 也把 teacher rollouts 描述为后续过滤/数据来源。
第二层是 teacher-model rollout verification:Claude-Sonnet-4-6 作为 teacher 运行任务,分别用 programmatic reward 与 VLM-as-a-judge 评分。若两者均在 且差异小于阈值 ,保留;若均为 0,认为可能不可解;若第一次就全为 1,认为可能过于 trivial 并下采样;若差异过大,则把 disagreement region 反馈给 Discriminator 修 reward。论文报告从 loop-accepted pool 中,majority voting 大约拒绝 3,100 个 tuple,teacher rollout 再拒绝 1,278 个,最终得到 32,112 verified tuples。
3.5 CUA-Gym-Hub:可 reset / inspect / parallelize 的 mock web environment layer
真实网站不适合作 RL 训练环境:认证、rate limit、第三方服务、随机状态与不可控网络都会破坏 reward 的可复现性。CUA-Gym-Hub 因此把真实软件的交互形态重新实现为 self-contained mock SPA,同时暴露统一 state API,让 setup、reward 与 rollout worker 都能稳定访问状态。
Figure 2 解读:Plan Agent 先做 web research、截图收集、feature inventory 和数据模型设计,产出 DESIGN.md、TODO.md、assets/README.md、assets/data_model.md;Dev Agent 根据这些文件实现 Vite + React SPA;Web Agent 用 Playwright 遍历 UI 元素并把 live DOM 与 specification 对比,发现按钮无效、状态未跟踪、视觉不一致等问题后反馈给 Dev Agent。最终产物不仅是网页,还包括 state API 与面向后续 task generation 的 SKILL.md。
CUA-Gym-Hub 的两个关键机制是 state injection 与 session isolation。POST /post?sid=<sid> 用于 set、set_current、merge、reset 状态;GET /go?sid=<sid> 返回 {initial_state, current_state, state_diff};GET /state?sid=<sid> 返回当前状态。每个 rollout 使用独立 sid,状态文件、上传与 reset 都按 session namespace 隔离,因此并行 RL worker 可以共享一个 mock backend 而不互相污染。
Figure 3a–3c 解读:三个 Gmail mock 截图使用同一个应用实现,但注入了三种不同 session state:空 inbox、项目 deadline 状态、休假后 backlog。对 RL 训练来说,这意味着环境多样性不必靠复制 94 套代码实现,而可以靠“同一 mock + 不同 task-specific initial state”产生大量可验证世界;reward 也可以直接读取 state diff,而不是依赖截图 OCR 或人工判断。
def web_mock_reward(base_url: str, sid: str, rubric: dict) -> float:
state = requests.get(f"{base_url}/go", params={"sid": sid}).json()
initial = state["initial_state"]
current = state["current_state"]
diff = state["state_diff"]
score = 0.0
if required_email_sent(current, rubric["recipient"], rubric["subject"]):
score += 0.4
if expected_attachment_uploaded(diff, rubric["attachment_name"]):
score += 0.3
if initial_preconditions_still_valid(initial, current):
score += 0.3
return min(score, 1.0)3.6 Long-horizon trajectory scaffold 与 GSPO objective
CUA rollout 包含大量 screenshot observation,直接做 sliding window 会丢失早期交互上下文,尤其会让后期成功/失败动作失去因果前缀。论文采用 trajectory slicing:保留 system/task prefix,把过旧 screenshot collapse 成确定性 <image collapsed> placeholder,只保留最近 multimodal observation 与 assistant actions。每隔 traj_slice_interval = 10 turn-pairs 生成一个 slice;prompt token 与 user/tool token 不计算 loss,assistant token 计算 loss;每个 slice 继承父 trajectory 的 episode reward。
Figure 4 解读:上方 sliding window 看似节省 context,但会把后续动作依赖的旧截图与状态直接截断;下方 trajectory slicing 则把旧视觉信息压成 deterministic placeholder,保留可复用 prefix 与近期完整多模态上下文。这样做的工程价值是同时解决 144K context cap、late-turn supervision、以及 policy log-probability 计算中的 KV-cache reuse。
训练使用 Group Sequence Policy Optimization (GSPO)。给定任务 与初始状态 ,旧策略采样 条轨迹 ,每条轨迹得到 。论文主文的 surrogate objective 是:
其中 是 sequence-level importance ratio, 是 clip range, 是 KL penalty。论文公式与 reported-run 配置差异:主文写 ,但 Appendix C.3.3 明确说 reported runs 使用 group-wise ,并设置 divide_by_std=False;Table 6 也设置 ,不加载 reference policy。因此实际报告结果更接近“mean-centered advantage + no KL reference”的 GSPO 变体。
3.7 Released code mapping
Code reference:
main@1e50b797(2026-05-26) — pseudocode and mapping based on this commit
| Paper Concept | Source File | Key Class/Function |
|---|---|---|
| Batch orchestration / resume / concurrency | scripts/batch_orchestrator.py | load_tasks(), run_task(), main() |
| Orchestrator dual-VM protocol | .claude/agents/orchestrator.md | dual-environment mode, output/final contract |
| Generator setup/golden scripts | .claude/agents/setup-gen.md | initial_setup.py, golden_patch.py generation rules |
| Discriminator reward synthesis | .claude/agents/reward-gen.md | reward.py, REVIEW.md, information-barrier rules |
| Majority-vote filter | filter/majority_vote_filter.py | load_task_bundle(), call_critic_once(), aggregate_votes(), process_task() |
| Critic rubric prompt | filter/critic_prompt.py | SYSTEM_PROMPT, build_user_prompt() |
| Reward helper for LLM/VLM judge | utils/reward_judge.py | call_llm_judge(), call_vision_judge(), fixed model/temperature guard |
| Dataset endpoint materialization | scripts/materialize_dataset_urls.py | replacement_map(), materialize(), main() |
| Mock web environment contract | hub/README.md | /post, /go, /state, session isolation, state diff |
| Mock synthesis agents | hub/.claude/agents/{plan,dev,playwright}.md | Plan / Dev / Playwright contracts |
Released repo 主要覆盖数据合成 pipeline、filter、dataset materialization 与 CUA-Gym-Hub;没有发现 GSPO trainer launch script / experiment YAML / verl config。因此本文训练超参只能锚定到论文 Appendix C.2–C.4,而不能像 pipeline 组件一样锚定到 released training config。
4. Experimental Setup (实验设置)
Dataset 与环境规模
- 完整 CUA-Gym corpus:32,112 verified RLVR tuples,覆盖 110 environments(16 desktop applications + 94 synthesized mock web applications)。任务按 category、difficulty、cross-app complexity 做平衡;hard 占 44.6% / 45% 左右,cross-app 约 38.3%。
- RLVR training set:主实验采样 10,858 verified tuples,覆盖 80+ environments。
- SFT warm-up corpus:Claude-Sonnet-4-6 在同一 task pool 上每 task 采样 4 条 rollout,保留 的成功轨迹;约 50% 被过滤,最终 3,578 trajectories。
- Environment scaling distillation set:narrow = 10 envs / 3K trajectories / 300 per env;mid = 80 envs / 3K trajectories / 38 per env;broad = 80 envs / 6K trajectories / 75 per env。
Figure 6a 解读:环境覆盖横跨 DevOps、analytics、communication、project management、CRM/finance、HR、e-commerce、content、healthcare/legal/realty、Chinese / international apps,以及 desktop apps。它强调 CUA-Gym-Hub 不是单一 browser benchmark,而是试图覆盖知识工作中常见的软件生态。
Figure 6b 解读:32,112 个任务在 domain 上相对分散,单一 category 不超过 21%;difficulty 分布偏向 hard(45%)与 medium(约38%),single-app 约56%,cross-app 约38%。这与论文目标一致:训练 CUA 不是只做单应用短任务,而是覆盖跨应用、多步骤、状态跟踪密集的任务。
Baselines
OSWorld-Verified / WebArena 主表包含 proprietary 与 open-source baselines:Claude Sonnet 4.6、Claude Opus 4.7、GPT-5.5、EvoCUA-8B、EvoCUA-32B、OpenCUA-32B、OpenCUA-72B、Step-GUI-8B、Kimi-K2.6,以及 Qwen3.5-35B-A3B / Qwen3.5-397B-A17B base。CUA-Gym 模型是 CUA-Gym-A3B 与 CUA-Gym-A17B。
Evaluation metrics
- OSWorld-Verified success rate:在 OSWorld-Verified desktop/software tasks 上的任务成功率;主表按总体与 domain 细分。
- WebArena success rate:browser benchmark 的 held-out transfer 评估;用于检查 CUA-Gym-Hub/web mock 训练是否能迁移到非训练环境。
- Training reward:GSPO rollout 中 programmatic reward 的均值;在 Figure 7 中与 OSWorld-Verified success curve 同时观察,用来判断 reward 是否与真实 benchmark 改善解耦。
- Tool calls per model step:平均每个 model step 发出的 primitive tool calls 数,用于衡量 RL 是否学会 multi-action batching / trajectory compression。
Training config
SFT warm-up(Appendix C.2):AdamW;peak LR ,cosine decay 到 ;weight decay 0.01;batch size 512 prompts;1 epoch;sequence length 256K;trajectory slicing 与 RL 保持一致;bf16 mixed precision + FP8 matmul path;512 GPUs。
GSPO RL(Appendix C.3 / Table 6):group size ;over-sampling target ,保留前 16 条 valid rollouts;clip ;,不加载 reference policy;LR constant schedule、no warmup;AdamW ;weight decay 0.01;outer batch 128 prompts;mini-batch 32 prompts;PPO epochs 1;total steps 1000;rollout temperature 1.0;eval temperature 0.6;top-p 0.95 / top-k unconstrained;max new tokens per turn 2048;max context length 144K;max prompt length 8K;Chinese-token penalty coefficient 0.5;entropy bonus 0;format/language/endless penalties disabled;group filtering disabled。
Infrastructure(Appendix C.4):RL runs 使用 NVIDIA H200 SXM 141GB;Qwen3.5-35B-A3B 对应 turbo cluster 192 GPUs / 24 nodes;Qwen3.5-397B-A17B 对应 plus cluster 512 GPUs / 64 nodes。训练与 rollout subclusters 均分,基于 verl disaggregated trainer;dispatch ratio 2.35;最大 policy-version skew 4 steps;TP=2、EP=8、CP=4;PP=2(turbo)/ PP=8(plus);rollout serving TP=8、DP replication factor 4、fa3 attention backend、sglang serving、speculative decoding 3 steps / 4 draft tokens。OSWorld rollout 后端有 2,000 parallel VM instances。1000-step A3B run 约 5 天 / 23,040 GPU-hours;A17B run 约 5 天 / 61,440 GPU-hours。
5. Experimental Results (实验结果)
5.1 Main results:OSWorld-Verified 与 WebArena 均提升
Figure 5 解读:图中按 OSWorld-Verified domain 展示 base 与 CUA-Gym RL-trained 模型的差异。A3B 总体从 54.5 到 62.1(+7.6 pp),multi_apps、libreoffice_calc、vs_code 是主要提升来源;A17B 总体从 62.2 到 72.6(+10.4 pp),writer、calc、impress、gimp、chrome、multi_apps、os 多数提升,但 thunderbird 出现 -13.3 pp regression。说明 CUA-Gym 不是只提升小模型,较大 MoE scale 也仍能从 verified RLVR 数据中获益。
主结果精确值:
| Model | OSWorld-Verified | WebArena |
|---|---|---|
| Claude Sonnet 4.6 | 72.9 | 65.6 |
| Claude Opus 4.7 | 78.0 | – |
| GPT-5.5 | 78.7 | – |
| EvoCUA-8B | 46.1 | – |
| EvoCUA-32B | 56.7 | – |
| OpenCUA-32B | 34.8 | – |
| OpenCUA-72B | 45.0 | – |
| Step-GUI-8B | 40.2 | – |
| Kimi-K2.6 | 73.1 | – |
| Qwen3.5-35B-A3B base | 54.5 | 40.8 |
| Qwen3.5-397B-A17B base | 62.2 | 54.0 |
| CUA-Gym-A3B | 62.1 | 44.5 |
| CUA-Gym-A17B | 72.6 | 56.0 |
A3B 的关键解释是:CUA-Gym-A3B 以约 10× 更少 active parameters,达到接近 Qwen3.5-397B-A17B base 的 OSWorld-Verified 水平(62.1 vs. 62.2)。WebArena 上 A3B 从 40.8 到 44.5,A17B 从 54.0 到 56.0,说明从 CUA-Gym-Hub / desktop+web verified data 学到的策略能迁移到 held-out browser benchmark。
5.2 Dataset scale:更多 verified tuples 提高 RL ceiling
Figure 7 解读:1.4K、3K、12K verified tuples 的三条 GSPO 曲线在同一 SFT checkpoint 上起步。12K 曲线更早离开 SFT init 0.53 基线,并在 OSWorld-Verified score 与 training reward 上保持更高 band;3K 与 1.4K 更接近 baseline。更重要的是,training reward 与 OSWorld score 没有明显 decoupling,也没有 collapse / oscillation,支持“信息隔离 reward 足够稳定,能支撑 RL”这一论点。
论文的主要结论不是“12K 已够”,而是“12K 仍未饱和”:Figure 7 中 12K 曲线没有出现明显向平台收敛的 inflection。这说明 CUA-Gym pipeline 扩展数据量仍可能继续带来收益。
5.3 Environment scale:环境多样性与轨迹数量是互补轴
Figure 8 解读:环境 ablation 用 teacher distillation 而不是 RL 来降低成本。narrow(10 envs / 3K traj)得到 57.8,mid(80 envs / 3K traj)得到 58.8,broad(80 envs / 6K traj)得到 60.7。固定总轨迹数时增加环境带来小幅提升;固定 80 env 时增加轨迹量带来更大提升。它说明环境多样性不是轨迹数量的替代品,而是互补轴:CUA-Gym-Hub 提供 reusable environment diversity,CUA-Gym tuple 则把这些环境实例化成可训练数据。
5.4 Emergent multi-action batching:RL 学会压缩确定性动作链
Figure 9 解读:SFT-initialized policy 大约每 step 发一个 tool call;RL 后稳定在 1.4–1.9 tool calls / step。论文解释是:在固定 step budget 与 group-normalized advantage 下,能把 deterministic sub-sequences 打包进同一 turn 的轨迹更容易完成任务并获得相对优势,于是策略自发学会 batching。它不是显式优化目标,却体现了 RL 在 GUI agent 中可能带来的效率行为。
Appendix D 对 A17B-scale RL checkpoint 在 OSWorld-Verified test split 的 1,105 rollouts 做解析,共 22,361 model steps,平均 1.41 tool calls / step;分布为 69.6% single-call、26.7% two-call、2.4% three-call、0.8% four-call、0.5% five-or-more-call。最常见 batched sequences 是 type → key(3,942 steps)与 mouse_move → scroll(1,052 steps),二者占 batched steps 约 75%。反过来,right_click、double_click、triple_click、left_click 的 solo rate 分别为 98.0%、94.8%、94.6%、90.6%,说明策略倾向于单独执行会改变 UI 状态、需要重新观察的动作,而把机械手势和确定性链条合并。
5.5 数据集结构与对比
CUA-Gym 与已有 GUI agent training datasets 的对比:GUI-Genesis 969 / 1 env / mobile / programmatic / not open;WebArena-Infinity 1,260 / 10 envs / web / programmatic / open;InfiniteWeb 600 / web / programmatic / partially promised;UltraCUA 17,000 / 9 envs / desktop / programmatic / partially promised;Gym-Anything 7,277 / 193 envs / desktop / VLM reward / open;CUA-Gym 是 32,112 / 110 envs / desktop+web / programmatic / open。
Appendix F 的 distribution 进一步说明任务构成:Table 10 总计 easy 5,684、medium 12,103、hard 14,325;Cross-Desktop 7,528、Spreadsheet 5,572、Document Editing 4,116、Presentation 3,167、System & OS 2,809、Code Editing 2,480、Desktop × Web 2,001。12,311 个 cross-app tasks 占 38.3%;高频 application pairs 包括 pdf + writer 3,173、calc + writer 3,129、impress + writer 2,056、calc + impress 1,576、impress + pdf 1,381、calc + pdf 1,003。指令长度 mean 54.1 words、median 41、90% 小于 108 words,最长 390 words。
5.6 Limitations 与阅读结论
作者明确承认三类限制。第一,reward 只验证 terminal environment state,不验证完成过程;如果 agent 用破坏性路径重建同一最终状态,reward 可能无法区分。第二,information barrier 与 forbidden-pattern scan 只是降低 reward hacking,不能形式化消除过松 semantic checks 或与成功相关但不充分的 state proxies。第三,CUA-Gym-Hub mock environments 仍是近似真实应用,认证、第三方集成、网络延迟、rate limits、罕见服务端 failure states 不在当前表面内;最大 RL runs 因成本只报告 single seed。
总体而言,CUA-Gym 的贡献不是提出新的 agent architecture,而是把 CUA RLVR 的瓶颈重新定位为“可验证任务与可控环境的供应链”。如果论文的曲线能在更大规模、多 seed、更真实环境中复现,那么它提示 GUI agent 的下一阶段进展可能更多来自 environment/task/reward infrastructure,而不只是模型结构或推理 prompt。