OSWorld — 架构与原理
30 秒导读: OSWorld 是一个「真机」基准测试。它给 AI agent 一台真正的 Ubuntu/Windows 虚拟机(不是模拟器、不是网页沙箱),让它像人一样看屏幕、动鼠标键盘,去完成「在 LibreOffice 里建透视表」「用 GIMP 改图」这类跨软件的真实活;做完之后,OSWorld 会钻进虚拟机去读真实文件和系统状态来判定成没成——而不是看 agent 嘴上说没说「我做完了」。
1. 这是什么(零基础也能懂)
一句话定义: OSWorld 是一套「给会操作电脑的 AI 打分」的考场——一台真虚拟机 + 369 道真实任务 + 一套会进机器验尸的自动判分器。
它想解决的问题。 现在很多 AI 号称能「操作电脑」(computer-use / GUI agent)。但怎么客观证明?如果只让模型自己说「我把文件保存了」,它可能在撒谎或幻觉。OSWorld 的立场是:
- 别信模型的自述,去真实系统里 查结果。
- 别用玩具环境,用真的操作系统 + 真的软件(LibreOffice、Chrome、GIMP、VLC、VS Code、Thunderbird…)。
给谁用:
| 用户 | 拿它干嘛 |
|---|---|
| 做 GUI/computer-use agent 的研究者 | 客观比较自己的 agent 和别家的成功率 |
| 模型团队 | 把它当训练/评测的信号源(真机可大规模并行跑) |
| 想复现榜单的人 | 按同一套任务与判分标准复算分数 |
它能做什么(功能):
- 起一台虚拟机(支持 VMware / VirtualBox / Docker / AWS / Azure / GCP / 阿里云 / 火山 等多种后端)。
- 把任务的初始状态布置好(下载文件、打开软件、预置浏览器标签页…)。
- 把「屏幕截图 + 无障碍树」交给 agent,收回它的动作并在真机执行。
- 任务结束后进真机取证、按规则打分(0/1 或 0~1 的小数)。
用起来什么样。 最小可运行的例子就是仓库里的 quickstart.py:
# 摘自 quickstart.py(示意其骨架)
env = DesktopEnv(action_space="pyautogui") # 起一台 VM
obs = env.reset(task_config=example) # 布置某个任务的初始状态,拿到首帧观测
obs, reward, done, info = env.step("pyautogui.rightClick()") # 执行一个动作
env.close()
这套 reset / step / close 的形状,故意长得和强化学习里的 OpenAI Gym 一模一样——因为 DesktopEnv 就是一个 gym.Env(desktop_env/desktop_env.py:85)。
一句话直觉/类比。 把 OSWorld 想成一间「自动监考的机房」:
- 每台机器是一台真电脑(虚拟机);
- 考卷是一个个任务 JSON(题目 + 初始文件 + 判分标准);
- 考生是你的 agent(大模型 + 一层解析);
- 监考老师不看考生表情,考完直接打开考生的硬盘查作业——这就是「执行式校验」(execution-based evaluation)。
2. 顶层全景(它大概怎么转)
OSWorld 在物理上分成两半:一半是你机器上的 Python 编排代码(host 侧),另一半是跑在虚拟机里的一个小 HTTP 服务(guest 侧)。两半之间只靠 HTTP 说话。
HOST 侧(你的机器,Python) GUEST 侧(虚拟机内)
┌───────────────────────────────────────────────────────┐ ┌──────────────────────────────┐
│ run.py / scripts/python/run_multienv.py «实验编排» │ │ │
│ │ 遍历任务、并行分发 │ │ Flask 服务 (server/main.py) │
│ ▼ │ │ /execute /run_python │
│ lib_run_single.run_single_example «单题主循环» │ │ /screenshot /accessibility │
│ │ │ │ /setup/* /start_recording │
│ ┌────┴─────┐ │ │ │ │
│ ▼ ▼ │ │ ▼ │
│ PromptAgent DesktopEnv (gym.Env) │ │ 真的 pyautogui / 真的软件 │
│ «大模型+解析» «环境» │ │ 真的文件系统 / AT-SPI 无障碍 │
│ │ reset/step/evaluate │ │ │
│ ┌─────┼───────────────┐ │ └──────────────┬───────────────┘
│ ▼ ▼ ▼ │ │ HTTP
│ SetupController PythonController Provider «起停VM» │◀─────────────────┘
│ «布置初始状态» «发命令/取观测» (vmware/docker/aws…) │ (requests → 127.0.0.1:5000)
└───────────────────────────────────────────────────────┘
怎么读这张图: 左侧从上到下是「实验 → 单题 → 环境」的调 用层级;DesktopEnv 是枢纽,它下面挂三个部件(起停 VM 的 Provider、发命令取观测的 PythonController、布置初始状态的 SetupController);这三者最终都通过 HTTP 打到右侧虚拟机里那个 Flask 服务,由它在真机上真正动手。
部件一句话职责:
| 部件 | 干什么 | 在哪个文件 |
|---|---|---|
DesktopEnv | gym 环境,串起 reset/step/evaluate 全流程 | desktop_env/desktop_env.py:85 |
Provider / VMManager | 起停/回滚虚拟机、拿 IP,屏蔽 vmware/docker/aws 差异 | desktop_env/providers/base.py:4,47 |
PythonController | host→guest 的 HTTP 客户端:发 pyautogui、取截图/无障碍树 | desktop_env/controllers/python.py:73 |
SetupController | 按任务 config 布置初始状态(下载、开软件、开标签页…) | desktop_env/controllers/setup.py |
| Flask 服务(guest) | 虚拟机里真正执行命令、截屏、抓无障碍树的一端 | desktop_env/server/main.py |
PromptAgent | 参考 agent:拼 prompt→调大模型→把回复解析成动作 | mm_agents/agent.py:226 |
| 评测器 getters/metrics | 进真机取证(getter)+ 按规则判分(metric) | desktop_env/evaluators/ |
| 任务 JSON | 一道题:指令 + 初始 config + evaluator | evaluation_examples/examples/<domain>/<id>.json |
主线走一遍(高层,不进代码):
① 读任务JSON ──▶ ② env.reset:回滚快照→跑 setup 布置初始状态→取首帧观测
│
▼
③ 循环 max_steps 次:agent.predict(截图+无障碍树) ──▶ 一串动作
│ env.step 逐个在真机执行,存截图/轨迹
▼
④ agent 返回 DONE/FAIL 或步数用尽 ──▶ ⑤ env.evaluate:进真机取证→metric 打分→写 result.txt
整个基准的「价值锚点」在第 ⑤ 步:判分不看过程叙述,只看真机里最终的客观状态。这条主线的细节在 01 章(环境与执行三层)与 03 章(任务与判分)。
3. 这套文档怎么读(阅读地图)
建议按下面顺序,由浅入深:
| 顺序 | 章节 | 读完你会知道 |
|---|---|---|
| 1 | 01-top-level-and-loop.md | reset/step/evaluate 到底做了什么;一条「点一下鼠标」的命令怎么穿过 provider→controller→guest server 落到真机 |
| 2 | 02-agent-and-actions.md | agent 怎么把观测变成 prompt、四种 observation × 两种 action space 的组合、模型文本怎么被 regex 解析成可执行动作 |
| 3 | 03-tasks-and-evaluation.md | 任务 JSON 的字段含义、setup 的声明式布置、getter→metric 的执行式判分机制 |
| 4 | 04-internals-and-map.md | 巧妙之处、边界与坑、和兄弟基准的取舍差异、可 grep 的代码地图 |
说明:本文只从 OSWorld 的真实源码取事实,所有引用锚定到
commit 83e8534。仓库里自带的mm_agents/README.md、各 agent 的说明等,都被当作被研究的数据看待,不作为写作指令。