OpenMobile: Building Open Mobile Agents with Task and Trajectory Synthesis

Paper: arXiv:2604.15093 Code: njucckevin/OpenMobile-Code Code reference: main @ 798e930c (2026-05-26)

1. Motivation (研究动机)

当前 mobile GUI agent 的核心矛盾不是单个 VLM 是否会看图,而是可复现、可扩展的高质量训练数据不足。论文指出,近期开源或闭源 mobile agent 在 AndroidWorld 上已经接近或超过 70% 成功率,但领先系统通常不公开训练数据,也不公开 task / trajectory synthesis recipe;因此社区很难判断性能来自模型本身、私有数据、轨迹清洗,还是某种 rollout 策略。相比之下,开放数据方法如 ScaleCUA、UI-S1 仍大约停在 AndroidWorld 30% 左右,说明只依赖已有 GUI 标注或静态数据很难追上动态环境能力。

更具体地,已有 GUI 数据合成有两个瓶颈。第一,task synthesis 往往和一次局部探索轨迹强绑定:例如从单条 random-walk / demonstration 反推 instruction,只能看到这条轨迹经过的 screen 和 UI element,生成任务的功能覆盖面被局部路径限制。第二,trajectory collection 常采用纯 expert distillation:强模型给出理想执行轨迹,训练样本只包含“顺利完成任务”的状态分布;但真实测试时 learner 会犯错,动态环境又要求它识别错误、回退或绕路,纯模仿数据缺少这种 error-recovery signal。

OpenMobile 要解决的问题是:在开放环境和开源代码下,自动合成既 grounded 又多样的 mobile task instruction,并收集包含错误恢复信息的 agent trajectory。这个问题值得做,因为它直接决定 open mobile agents 能否从“只会复现静态标注”转向“能在真实 emulator 中长程执行、犯错后恢复、跨 app 泛化”。如果数据合成过程可复现,后续研究就可以在同一套 open recipe 上比较 base model、RL、trajectory filtering、memory retrieval 等因素,而不是只比较封闭 leaderboard 数字。

2. Idea (核心思想)

OpenMobile 的核心 insight 是:先把环境探索得到的碎片轨迹组织成全局、可检索的 environment memory,再用这份 memory 合成任务;收集轨迹时让弱 learner 先行动、强 expert 在偏离时介入,而不是只收集完美 expert demo。前者把 instruction generation 从单条轨迹中解耦出来,后者把训练分布从“全是正确步骤”扩展到“错误之后如何恢复”。因此,OpenMobile 不是简单扩充数据量,而是改变了数据的两个结构性属性:task instruction 覆盖更多 app-level functionality,trajectory supervision 覆盖 learner 在动态环境中会遇到的 off-policy / recovery states。

关键创新可以压缩为两个互补模块:一是 scalable task synthesis,将探索屏幕去重、聚类、标注功能,并构造 short-term / long-term memory 来生成复杂多步 instruction;二是 policy-switching rollout,用 monitor 判断 weak policy 是否 off-track,一旦偏离就切换到 strong policy 纠偏,并最终只保留 strong / expert 步骤作为监督目标,同时把 learner 的错误历史保留在上下文中。这个组合让数据既有“任务覆盖面”又有“恢复轨迹”:前者解释为什么 OpenMobile 在 fixed 1.5K trajectories 的 synthesis Ablation 中高于 OS-Genesis / coupled pipeline,后者解释为什么 error-intervention rollout 比 expert distillation 和 random switch 有更多 Avg. ER。

它和 OS-Genesis / coupled reverse synthesis 的本质差异在于:OS-Genesis 更像“从一条探索路径回看这条路径能解释成什么任务”,OpenMobile 则先建立 app-level functionality landscape,再从局部邻居和远距离相似功能中组合任务。它和纯 expert distillation 的差异在于:expert distillation 只教 learner 模仿理想动作;OpenMobile 的 error-intervention switching 刻意让 learner 暴露错误,再由 expert 从错误状态接管,因此训练样本能学习“识别当前状态已经偏离后该如何继续推进”。

从研究定位看,这篇论文更像一个 open data recipe,而不是只提出单个 agent policy。它把探索、memory construction、task filtering、rollout switching、trajectory conversion、SFT config 全部开源,使后续工作可以分别替换 exploration strategy、retriever、judge、monitor 或 RL stage,并观察每个环节对动态 mobile benchmark 的真实影响。

3. Method (方法)

3.1 Overall framework:OpenMobile 两阶段数据合成框架

Figure 2 解读:图 2 展示了 OpenMobile 的两条主线。左侧是 scalable task synthesis:先探索 Android app,得到许多 screen-action-screen transition;再通过 screen deduplication 和 functionality annotation 构建全局 memory;最后从当前 screen、邻居 screen 和语义相关的远处 functionality 中生成 task instruction。右侧是 policy-switching rollout:weak learner 先执行,monitor 发现偏离后触发 strong expert intervention,轨迹中因此包含“错误发生—诊断—专家修复”的片段。

直觉上,OpenMobile 把 mobile task 数据合成拆成“知道 app 能做什么”和“知道 agent 在动态执行时会怎么失败”两个问题。前者避免单条轨迹视野太窄,后者避免 expert demonstration 过于干净。二者合在一起,训练样本既覆盖更多 app 功能,又让模型看到真实测试时常见的偏离状态。

3.2 Environment exploration:用简单 random walk 收集状态转移

论文强调框架不依赖复杂探索策略;实现中采用 OS-Genesis 风格 random walk。每个 session 执行 10 步,从当前 screen 的 accessibility tree 中随机选择 interactable element,执行 click 或 type,并维护 non-interactable blacklist 来减少重复无效操作。探索阶段的目标不是直接生成任务,而是最大化 app state / functionality 覆盖,为后续全局 memory 提供原材料。

代码中这一步对应 AndroidWorld/random_walk_aw.py 和 README 的 “Explore AndroidWorld Screens” 命令。raw exploration trajectory 会被 AndroidWorld/process_explore.py 转成 state_transfer_explore.json,后续 task_synthesis/pipeline.py 的 Step 1 读取它并生成 unique screen JSON。

3.3 Global Environment Memory:屏幕去重、功能标注、语义检索

论文将全局环境记忆定义为: 其中 是去重后的 unique screens, 是从所有探索轨迹聚合出的邻居关系, 是由强 VLM 标注出的 UI functionality 描述。

实现细节如下:

  • Screen deduplicationtask_synthesis/screen_transition_index.py 使用 perceptual hash(pHash)为截图建索引,默认 hash_size=16similarity_threshold=0.95。两个 screen hash 的 Hamming distance 被归一化为 similarity,超过阈值就被视为相同或近似相同 screen。
  • Neighborhood aggregation:同一 unique screen 可能在多个 trajectory 中出现,代码通过 screen_before_index / screen_after_index 聚合它作为前驱或后继的 transition,从而形成
  • Functionality annotation:论文写明使用 Gemini-3.1-Pro-Preview 标注 screen 上的 UI element 语义,并区分 app-provided functionality 与 user-generated data。代码中 task_synthesis/process_transfer.py 负责 unique screen 到 with-elements 的处理。
  • Semantic indextask_synthesis/process_context.py 收集每个 app 的 functionality descriptions,计算 embedding 并保存 app-level retrieval pool;get_related_functionalities(..., m=30, similarity_threshold=0.8) 会为当前 screen 的 functionality 检索候选,再用 pairwise cosine similarity <0.8 做多样性过滤。

论文公式与 released code 实现差异:论文和附录写 semantic embedding 使用 openai/text-embedding-3-large;released task_synthesis/pipeline.py 的 CLI 默认值是 all-MiniLM-L6-v2,但 --context_embedding_model 明确支持 openai/text-embedding-3-large。因此若要复现实验设定,需要显式传入 paper 中的 embedding model,而不是直接使用默认 README 命令。

3.4 Memory-Augmented Task Synthesis:短期邻居 + 长期功能组合

对每个候选 screen ,OpenMobile 构造三部分上下文:

  • :当前 screen screenshot 和它的 annotated functionalities,作为生成任务的 focal point。
  • :short-term memory,来自 transition graph 中的局部邻居。附录和代码都给出默认结构:1 个 predecessor screen,以及最多 3 个 successor screens。
  • :long-term memory,来自同一 app 内语义相关但不一定相邻的 functionality。附录写明检索 30 个语义相关功能,并用 pairwise similarity <0.8 保证多样性。

task_synthesis/process_task.py 的 prompt 明确要求生成 long-range tasks,避免单步点击任务;并引导模型生成 question-answering、multi-step operation 等更复杂 instruction。生成后,eval_task.py / process_task_refine.py 进行质量过滤:LLM 以 complexity、clarity、reasonableness 三个 1–5 分维度评估;clarity <4 或 reasonableness <4 的 instruction 被丢弃;剩余样本按质量排序后做 embedding greedy dedup,阈值为 0.8;最终每个 app 最多保留 100 条,以避免少数 app 支配训练集。

def build_global_memory(transitions, screenshots, vlm, embedder, tau=0.95):
    unique_screens = []
    for screen in collect_screens(transitions):
        h = phash(screen.image, hash_size=16)
        if all(hash_similarity(h, s.hash) < tau for s in unique_screens):
            unique_screens.append(ScreenRep(image=screen.image, hash=h))
 
    for s in unique_screens:
        s.neighbors = aggregate_reachable_screens(s, transitions, unique_screens)
        s.functionalities = vlm.annotate_ui_functionalities(
            screenshot=s.image,
            previous_screen=s.prev_image,
            incoming_action=s.incoming_action,
        )
 
    for app in group_by_app(unique_screens):
        funcs = [f.description for s in app.screens for f in s.functionalities]
        app.index = build_vector_index(embedder.encode(funcs))
    return GlobalMemory(screens=unique_screens)
def synthesize_and_filter_tasks(memory, generator, judge, max_per_app=100):
    raw_tasks = []
    for screen in memory.candidate_screens(max_num=1000):
        context = {
            "current": screen,
            "short_term": memory.transition_neighbors(screen, predecessors=1, successors=3),
            "long_term": memory.related_functionalities(screen, top_m=30, diverse_below=0.8),
        }
        raw_tasks.extend(generator.generate_tasks(context, require_long_range=True))
 
    scored = [judge.score(task, keys=["complexity", "clarity", "reasonableness"])
              for task in raw_tasks]
    kept = [x for x in scored if x.clarity >= 4 and x.reasonableness >= 4]
    kept = sorted(kept, key=lambda x: (x.clarity == 5 and x.reasonableness == 5,
                                      x.complexity, x.clarity + x.reasonableness), reverse=True)
    deduped = greedy_embedding_dedup(kept, text=lambda x: x.task, threshold=0.8)
    return per_app_topk(deduped, k=max_per_app)

3.5 Policy-Switching Rollout:让 learner 犯错,再由 expert 修复

给定 instruction 、expert policy 、learner policy ,每步观测当前 screen 和历史 ,动作由 switching variable 决定: 随机切换的弱点是:mobile task 往往存在多条有效路径,learner 与 expert 行为不同不一定代表错误;频繁切换还会破坏任务连续性。OpenMobile 因此采用 error-intervention switching:rollout 从 learner 开始;monitor 观察最近 action history 和截图,如果判断 weak agent 已经偏离任务,就切换到 expert;expert 至少连续执行若干步,把轨迹拉回可完成状态。

released code 在 AndroidWorld/android_world/agents/seeact_v.py 中实现 Qwen3VL_Switching。关键参数和论文一致:monitor_num_recent_screens=2max_interventions=2strong_min_steps_after_intervention=3。monitor prompt 要求输出 JSON:should_intervenereasonsummary。当 should_intervene=true 时,代码把 monitor summary/reason 注入 strong actor prompt 的 “Intervention context”,然后 strong actor 从当前 screen 接管。

def policy_switching_step(agent, instruction, screenshot, history):
    monitor_output = {"checked": False, "should_intervene": False}
 
    if (agent.current_policy == "weak"
        and agent.should_monitor_next_step
        and agent.intervention_count < agent.max_interventions):
        monitor_output = agent.monitor_judge(
            instruction=instruction,
            history=history,
            recent_screens=agent.recent_screens[-2:],
        )
        if monitor_output["should_intervene"]:
            agent.pending_intervention_feedback = format_feedback(monitor_output)
            agent.current_policy = "strong"
            agent.intervention_count += 1
            agent.strong_steps_since_intervention = 0
            agent.should_monitor_next_step = False
 
    if agent.current_policy == "strong":
        response, action = agent.strong_actor.act(
            instruction, screenshot, history,
            intervention_feedback=agent.pending_intervention_feedback,
        )
        policy_source = "strong"
    else:
        response, action = agent.weak_actor.act(instruction, screenshot, history)
        policy_source = "weak"
 
    execute(action)
    if policy_source == "strong":
        agent.strong_steps_since_intervention += 1
        if agent.intervention_count == 1 and agent.strong_steps_since_intervention >= 3:
            agent.current_policy = "weak"
    else:
        agent.should_monitor_next_step = True
    return {"response": response, "policy_source": policy_source,
            "monitor_output": monitor_output}

3.6 Trajectory post-processing:只监督 expert step,但保留错误历史

实验设置中,OpenMobile 从 policy-switching trajectory 中只保留 expert steps 作为 training target,同时在 prompt history 中保留 learner errors。这个设计很重要:如果把 weak 错误动作也作为 assistant target,会教模型模仿错误;但如果删除错误历史,模型又看不到“为什么当前 screen 是一个恢复场景”。

代码路径为 AndroidWorld/process_trajs.pyAndroidWorld/process_refine.pyAndroidWorld/convert_traj.pyprocess_trajs.py 合并成功 trajectory,并统计 weak_steps / strong_stepsconvert_traj.py 在构造 ShareGPT 样本时,如果 step 含 policy_source 且不是 strong,就增加 policy_filtered 并跳过该 step。换言之,released code 的 training target 确实来自 strong/expert steps,而 weak steps 主要作为 history context 保留下来。

def convert_switching_trajectory_to_sft(trajectory, image_root, prompt_template):
    samples = []
    for i, step in enumerate(trajectory):
        history = build_history_from_previous_steps(trajectory, cur_idx=i)
        user = prompt_template.format(instruction=trajectory.goal, history=history) + "<image>"
 
        if step.get("is_valid", True) is False:
            continue
        if ("policy_source" in step) and step.get("policy_source") != "strong":
            continue  # keep weak behavior in history, but do not imitate it as target
 
        thinking, tool_call = parse_assistant_response(step["response"])
        samples.append({
            "id": f"{trajectory.save_dir}_step{step['step']}",
            "messages": [system_prompt(), {"role": "user", "content": user},
                         {"role": "assistant", "content": format_assistant(thinking, tool_call)}],
            "images": [str(image_root / step["image"])],
        })
    return samples

3.7 Code-to-paper mapping

Code reference: main @ 798e930c (2026-05-26) — pseudocode and mapping based on this commit

Paper ConceptSource FileKey Class/Function
Environment exploration / random walkAndroidWorld/random_walk_aw.py; AndroidWorld/process_explore.pyrandom walk trajectory collection; conversion to state_transfer_explore.json
Screen deduplication and transition graphtask_synthesis/screen_transition_index.pyScreenTransitionIndex, compute_hash_distance, query_transitions
Task synthesis pipeline orchestrationtask_synthesis/pipeline.pystep1_state_transfer_to_unique_screen, step4_synthesize_tasks, step5_eval_tasks, step6_final_refine_and_add_task_id
Memory context retrievaltask_synthesis/process_context.pyget_transition_sources, get_transition_targets, get_related_functionalities, get_context
Prompted task generationtask_synthesis/process_task.pybuild_user_prompt, synthesize_tasks, parse_result
Instruction quality filtering / deduptask_synthesis/eval_task.py; task_synthesis/process_task_refine.pyevaluate_tasks_file, filter_by_eval, greedy_dedup_by_embedding, per_app_topk
Policy-switching rolloutAndroidWorld/android_world/agents/seeact_v.py; AndroidWorld/run_diy.pyQwen3VL_Switching, _run_monitor, _run_strong_actor, _run_weak_actor, --agent_name qwen3vl_switching
Trajectory merge and strong-step filteringAndroidWorld/process_trajs.py; AndroidWorld/convert_traj.py_is_success_terminal, build_sharegpt_samples, policy_source != "strong" filtering
SFT reference configLlamaFactory/qwen3vl_full_sft.yamlfull SFT, Qwen3-VL-8B-Instruct, LR / epochs / cutoff / Deepspeed config

4. Experimental Setup (实验设置)

4.1 Dataset and synthesized data scale

OpenMobile 在 AndroidWorld emulator infrastructure 上实例化,但论文明确不使用 benchmark test instructions 参与合成。最终合成数据包含约 2,800 instructions、约 34K action steps、覆盖 20 Android apps;平均 trajectory length 为 12.2 steps,每步平均 chain-of-thought reasoning 为 129 words。policy-switching rollout 中,learner 是 early-stage fine-tuned checkpoint,expert 是 Gemini-3.1-Pro-Preview;step-level reasoning 还会由 expert rewrite 以提升监督质量。

4.2 Evaluation benchmarks

  • AndroidWorld:116 tasks,覆盖 20 个真实 Android apps;通过 Android emulator 和 parameterized task templates 提供可复现实验。
  • AndroidLab:138 tasks,覆盖 9 个 apps,支持 language-only 和 multimodal agent;论文使用它测试不同环境和 app 上的泛化。
  • MobileWorld:201 tasks,覆盖 20 个 apps;更强调 long-horizon 和 cross-app workflow。论文使用 GUI-only subset。

评价指标为 Pass@1Pass@3。Pass@1 是单次执行成功率;Pass@3 表示同一任务跑三次,只要任一次成功就算 solved,用来反映动态环境中的性能上界。论文说明每个 benchmark 跑三次,报告 mean 以及 half-range,即 ,因为动态执行本身有非平凡随机性。

4.3 Baselines and compared systems

主表包含三类 baseline:commercial models(GPT-4o、Gemini-3-Pro),open-weight GUI / VLM agents(Qwen2.5-VL-7B、Qwen3-VL-8B、UI-Venus-7B、Step-GUI-4B/8B、MAI-UI-8B、UI-Venus-1.5-8B、MobileAgent-v3.5-8B),以及 open-data models(UI-S1-7B、ScaleCUA-7B)。附录还比较 OS-Genesis、HATS、AutoPlay、MobileGen 等 data synthesis methods。

4.4 Training config and implementation settings

论文训练两个 base models:Qwen2.5-VL-7BQwen3-VL-8B。正文写明使用 LLaMA-Factory 做 supervised fine-tuning,batch size 32、learning rate 、训练 3 epochs

released config LlamaFactory/qwen3vl_full_sft.yaml 给出可复现细节:model_name_or_path=Qwen/Qwen3-VL-8B-Instructstage=sftfinetuning_type=fullfreeze_vision_tower=truefreeze_multi_modal_projector=truefreeze_language_model=falsedeepspeed=examples/deepspeed/ds_z3_config.json,dataset 为 openmobile_split1openmobile_split4template=qwen3_vlcutoff_len=32768per_device_train_batch_size=1gradient_accumulation_steps=4learning_rate=1.0e-5num_train_epochs=3.0lr_scheduler_type=cosinewarmup_ratio=0.03bf16=true。论文和 released repo 没有明确给出 GPU 型号/数量;如果要把 config 的 per-device batch 推导成论文的 global batch 32,需要知道实际训练进程数,不能仅从 YAML 得出。

RL 实验包括 step-level RL 和 trajectory-level agentic RL。step-level RL 遵循 UI-R1,用 format reward、action type reward、grounding reward,并采用 GRPO;trajectory-level RL 使用 OS-Themis 的多 emulator rollout infrastructure 和 multi-agent critic,从 early checkpoint 出发,只保留该 checkpoint 失败而 expert 成功的 244 条合成 instructions。

5. Experimental Results (实验结果)

5.1 Main results:OpenMobile 明显提升开放数据训练效果

Figure 1 解读:图 1 把论文主结论压缩成三部分:左侧是三个动态 mobile benchmark 的成功率对比,中间是 AndroidWorld 上随 synthesized instructions 增加的 data scaling 曲线,右侧是 error correction capacity 对比。它强调 OpenMobile 的收益不是只来自更多 demo,而是来自可扩展 instruction 覆盖和包含错误恢复信号的 trajectory。

主结果表的关键数值如下:

MethodBase ModelAndroidWorld Pass@1 / Pass@3AndroidLab Pass@1 / Pass@3MobileWorld Pass@1 / Pass@3
GPT-4o30.6 / —31.2 / —— / —
Gemini-3-Pro60.3 / 75.0— / —51.3 / —
Qwen2.5-VL-7B25.5 ± 2.6 / 34.910.6 ± 1.8 / 15.27.7 ± 0.9 / 10.3
Qwen3-VL-8B47.6 ± 2.2 / 62.143.5 / —9.4 / —
Step-GUI-8BQwen3-VL67.7 / 80.2— / —— / —
MAI-UI-8BQwen3-VL70.7 / —— / —27.5 / —
UI-Venus-1.5-8BQwen3-VL73.7 / —55.1 / —17.1 / —
MobileAgent-v3.5-8BQwen3-VL71.6 / —— / —33.3 / —
UI-S1-7BQwen2.5-VL34.0 / —— / —— / —
ScaleCUA-7BQwen2.5-VL27.2 ± 2.2 / 36.230.0 ± 1.1 / 37.77.7 ± 0.4 / 8.6
Ours-7BQwen2.5-VL51.7 ± 1.7 / 68.122.7 ± 0.4 / 37.014.8 ± 1.3 / 21.4
Ours-8BQwen3-VL64.7 ± 3.2 / 78.051.5 ± 0.7 / 62.317.7 ± 2.2 / 24.8

最重要的结论是:同一 base model 上,OpenMobile 数据带来大幅提升。Qwen2.5-VL-7B 从 AndroidWorld 25.5 ± 2.6 提升到 51.7 ± 1.7;Qwen3-VL-8B 从 47.6 ± 2.2 提升到 64.7 ± 3.2。虽然 OpenMobile 数据在 AndroidWorld 环境中合成,它在 AndroidLab 和 MobileWorld 也有泛化收益,说明它没有只记住 AndroidWorld test instruction。

5.2 Task synthesis ablation:全局 memory 比单条轨迹上下文更有效

任务合成消融固定 1.5K trajectories 预算,比较 OS-Genesis、coupled pipeline 与 OpenMobile。human evaluation 对 50 个 pairwise comparisons 打分:OpenMobile 相对 OS-Genesis 在 complexity 上 win/tie/loss 为 0.68 / 0.22 / 0.10,soundness 为 0.44 / 0.48 / 0.08;相对 coupled pipeline 在 complexity 上为 0.26 / 0.62 / 0.12,soundness 为 0.06 / 0.90 / 0.04。这说明 OpenMobile 任务更复杂,但没有明显牺牲可执行性。

对应 AndroidWorld Pass@1:OS-Genesis 34.1 ± 1.7,Coupled Pipeline 45.3 ± 2.2,OpenMobile 48.3 ± 1.3。Coupled baseline 使用相同 generation prompt,但上下文只来自单条 exploration trajectory;OpenMobile 的提升说明全局 memory + long-term retrieval 的确让 instruction 覆盖更广。

5.3 Rollout strategy ablation:error-intervention 提供最多错误恢复信号

Rollout StrategyAvg. ERAndroidWorld Pass@1
Expert Distillation0.4244.8 ± 1.7
Self-Evolution0.1033.8 ± 0.9
Random Switch0.6445.1 ± 0.9
Error-Intervention Switch1.5648.3 ± 1.3

Avg. ER 是对每种策略随机抽 50 条 trajectory,人工统计每条轨迹平均包含多少 error-recovery instances。Error-intervention switch 的 Avg. ER 达到 1.56,明显高于 expert distillation 的 0.42 和 random switch 的 0.64,同时 Pass@1 最高。Self-evolution 只有 0.10 Avg. ER 且 Pass@1 33.8 ± 0.9,说明 learner 只靠自身成功轨迹迭代会受到当前能力上限限制。

5.4 Overlap and functionality coverage:收益不是 benchmark overfitting

Figure 4 解读:左图比较 synthetic instructions 与 AndroidWorld test instructions 的 semantic similarity;OpenMobile 因为共享 app/environment,相关性高于 AndroidControl / AMEX 是预期现象,但只有 3.5% 的合成 instruction similarity 超过 0.7。右图展示删除最相似样本后的性能变化:删除少量高相似样本只带来边际下降,说明模型不是依赖少数 test-like instruction;删除比例到 40% 后下降明显,是因为核心 app functionalities 也被移除了。

Figure 5 解读:左图显示随着 synthesized instruction 数量增加,OpenMobile 的 AndroidWorld functionality coverage 始终高于 coupled baseline;右图把 task complexity、coverage 和 success rate 联系起来:需要功能越多的任务越难,但在相同复杂度下,训练数据覆盖到更多所需 atomic functionalities 时成功率更高。这支持论文的主张:性能提升主要来自 broad functionality coverage,而不是简单 instruction overlap。

5.5 RL and additional results:SFT 已很强,RL 没稳定超过 SFT

论文还探索了 RL。Step-level GRPO 初期有收益,但很快饱和,最终没有超过 SFT baseline;作者认为原因是 step-level objective 与动态环境中的 long-horizon execution 不匹配,容易过拟合单步输出。Trajectory-level agentic RL 使用 OS-Themis 和 244 条“checkpoint 失败但 expert 成功”的 instructions,结果如下:

MethodAndroidWorld Pass@1 / Pass@3AndroidLab Pass@1 / Pass@3MobileWorld Pass@1 / Pass@3
Qwen3-VL-8B47.6 ± 2.2 / 62.143.5 / —9.4 / —
Ours-8B64.7 ± 3.2 / 78.051.5 ± 0.7 / 62.317.7 ± 2.2 / 24.8
Ours-8B-RL64.1 ± 0.5 / 77.653.9 ± 1.5 / 63.016.8 ± 0.9 / 20.5

RL 在 AndroidLab 上略高于 SFT,但 AndroidWorld 和 MobileWorld 没有超过 SFT;作者将其归因于当前环境设置多样性有限,以及 RL framework 稳定性仍需改进。

附录还给出 model scaling 和 data synthesis method 对比:Qwen2.5-VL-72B baseline 为 27.6,UI-Venus-72B 为 65.9,Ours-72B 为 59.3 ± 0.9 / 72.8;data synthesis 对比中,OS-Genesis 1.5K trajectories 得 17.4,HATS 1K 得 24.4,AutoPlay 20K 得 40.1,MobileGen 0.5K 得 45.7,OpenMobile 2.8K 得 64.7。论文提醒这些方法 base model 和实验设置不同,不能完全等价比较,但 OpenMobile 在 moderate data scale 下表现很强。

5.6 Limitations and takeaways

论文没有把 limitations 单独列成一节,但从实验和附录可以读出三个边界:第一,OpenMobile 当前主要在 AndroidWorld emulator infrastructure 上构建,尽管在 AndroidLab / MobileWorld 有泛化,环境多样性仍可能限制 RL 继续提升;第二,trajectory-level RL 依赖 OS-Themis 这类多 emulator rollout 与 critic infrastructure,稳定性和成本仍是未来方向;第三,released pipeline 中部分默认参数(例如 embedding model)与论文设定不完全一致,复现实验时需要显式对齐。

整体结论是:OpenMobile 证明了 open task-and-trajectory synthesis recipe 可以显著缩小开放 mobile agent 与闭源/闭数据系统之间的差距。它最有价值的不是某个单独 prompt,而是把 global functionality memory、quality-controlled instruction synthesis、error-intervention rollout 和 strong-step SFT 串成了可检查的开放数据生产线。