数据截至 (上游 commit 96983c73ed09)
UFO — 架构与原理
30 秒导读: UFO 是微软开源的 Windows 桌面 agent。你用中文/英文说一句「把这份 Word 里的表格截图发到邮件里」,它自己截屏、认出屏幕上有哪些按钮、决定点哪个、真的去点。第三代(UFO³ Galaxy)在此之上加了一层:把一句话拆成跨多台设备的任务 DAG,并行调度、边跑边改图。
1. 这是什么(零基础也能懂)
一句话定义
UFO 是一个把自然语言变成真实鼠标键盘操作的 Windows agent 框架。
解决什么问题
假设你要做一件跨好几个应用的琐事:打开 Excel 找到某列数字 → 算个总和 → 打开 Outlook 写封邮件把结果发出去。
这件事对人来说不难,只是烦。对 LLM 来说难在两处:
- 它看不见你的屏幕。 模型只会读文本,不知道「保存」按钮在哪。
- 它伸不出手。 就算它想清楚了要点哪里,也没有鼠标。
UFO 补的就是这两样:一只眼睛(截屏 + 枚举 Windows 控件),一双手(pywinauto 点击 / Office COM 调用)。
给谁用
| 用户 | 拿它干什么 |
|---|---|
| 想自动化 Windows 日常操作的工程师 | 直接命令行跑,让它替你点 Office、资源管理器、浏览器 |
| 研究 GUI agent 的人 | 一套完整的「感知 + 决策 + 执行 + 记忆 + 评测」参考实现 |
| 做跨设备编排的人 | Galaxy 层:把 Windows / Linux / Android 当成算力节点排 DAG |
它能做什么
- 枚举桌面上所有窗口,自己挑一个打开、切换。
- 在选中的应用里枚举可交互 控件,点击、输入、拖拽、滚轮、快捷键。
- 对 Office 三件套走 COM API 而不是点鼠标(更快更稳)。
- 敏感动作(发送、删除、关窗)先停下来问人。
- 把每一步的截图、思考、动作、结果写成结构化日志,还能自我评测。
- Galaxy:把请求拆成任务 DAG,分配到多台设备并行跑,并根据中间结果改图。
用起来什么样
最小用法就是一条命令(依据:ufo/ufo.py:51-74 的 main,以及 ufo/__main__.py):
# 单机模式:UFO² 直接接管这台 Windows
python -m ufo -t my_task
# 请求也可以直接写在命令行上,省掉交互式提问
python -m ufo -t my_task -r "打开记事本,写一句 hello 并保存到桌面"
# 跨设备模式:UFO³ Galaxy
python -m galaxy "从两台 Linux 服务器收集错误日志,汇总成 Excel 发邮件"
不带 -r 时,它会打印一个欢迎面板再问你要做什么(ufo/module/interactor.py:26 first_request)。
一句话直觉
把屏幕当成一张贴满了编号便利贴的图。
UFO 每一步都干同一件事:截图 → 把每个可点的控件框起来编上号(1、2、3…)→ 把「这张编号图 + 控件清单」丢给模型 → 模型回一句「点 7 号」→ 程序把 7 号翻译回真实控 件,点下去。
模型永远只报编号,从不报坐标。编号这层间接寻址,是整个框架最核心的一招。
本节到此为止不涉及任何代码细节。下面开始讲它内部怎么转。
2. 顶层全景(它大概怎么转)
2.1 先分清两层产品
仓库里其实住着两个东西,共用一套底层设施:
UFO²(目录 ufo/) | UFO³ Galaxy(目录 galaxy/) | |
|---|---|---|
| 管什么 | 一台 Windows 机器 | 多台异构设备 |
| 任务模型 | 顺序循环:一步一动作 | DAG:任务节点 + 依赖边 |
| 主要 agent | HostAgent + AppAgent | ConstellationAgent |
| 并发 | 无(单线主线) | 有(asyncio 并行跑就绪节点) |
| 入口 | python -m ufo | python -m galaxy |
Galaxy 不是替代品,它把一台跑着 UFO² 的 Windows 机器当作 DAG 里的一个执行设备。