跳到主要内容

OpenAdapt — 架构与原理

30 秒导读: OpenAdapt 让你演示一遍在电脑上怎么点、怎么打字(录屏 + 记录鼠标键盘),然后它用大模型把这段示范改写并重放到新的场景——哪怕界面挪了位置、按钮换了地方,也能靠「这个元素长什么样/叫什么」而不是「点第 (x, y) 像素」把动作落回去。一句话:给机器看你怎么做,而不是写脚本告诉它坐标。

1. 这是什么(零基础也能懂)

  • 一句话定义: OpenAdapt 是大模型和桌面/网页 GUI 之间的适配器——把「人的示范」翻译成「模型能理解、能改写、能重放的动作」。项目名就是 Open(开源) + adapt(适配器)。

  • 解决什么问题 / 给谁用: 传统 RPA(机器人流程自动化)脚本写死了坐标和控件路径,界面一改就全崩。OpenAdapt 想让不会编程的人也能自动化:你手动做一遍任务,它录下来;之后你用一句自然语言(「把收件人换成 Bob」)让它改着重放。给做重复桌面工作的人、做 computer-use agent 研究的人用。

  • 它能做什么(功能):

    • 录制一段 GUI 示范:截图 + 鼠标 + 键盘 + 窗口信息 + 浏览器 DOM(可选)。
    • 把原始输入清洗成干净的动作序列(合并连续移动、去掉冗余、把逐字符按键合成文本)。
    • 用自然语言改写这段示范(改文本、改目标元素)。
    • 重放:对当前屏幕重新做视觉定位,把动作落到正确的 UI 元素上。
    • 训练/评测 VLM(视觉语言模型)agent(在 v1.0+ 的子包里)。
  • 用起来什么样: 命令行录一段、再重放:

    # 录一段示范(v1.0+ 统一 CLI)
    openadapt capture start --name login-flow
    # ……你手动操作 GUI,然后 Ctrl+C 停止

    # 老版(v0.46.0 单体)里用重放策略 + 自然语言指令改写重放
    python -m openadapt.replay VisualReplayStrategy --instructions "用 Bob 代替 Alice"
  • 一句话直觉/类比: 把它想成**「给电脑录制的宏,但宏认得屏幕」。普通宏记的是「点 (840, 210)」,界面一动就废;OpenAdapt 记的是「点那个写着『发送』的蓝按钮」,重放时再去当前屏幕上找**那个按钮。

本节不出现底层代码;记住一句:录示范 → 清洗 → 按描述重定位 → 重放。

2. 顶层全景(它大概怎么转)

2.1 两个时代,一个仓库

这个仓库里其实住着两套代码,理解它必须先分清:

位置是什么本文档重点
v1.0+ 元包openadapt/(仓库根的包)一个很薄的统一 CLI,把功能拆成一堆 openadapt-* PyPI 子包,按需懒加载第 5 章
v0.46.0 单体legacy/openadapt/真正的引擎:录制、事件处理、重放策略、视觉定位全在这第 1-4 章

怎么读这张关系: 新版把老版拆散成微服务式的子包发到 PyPI;老版仍是读懂核心原理最完整的一份源码,所以下面的原理讲解主要挖 legacy/

2.2 核心主线(Demonstrate → Learn → Execute)

README 把流程概括为演示 → 学习 → 执行三段。落到 legacy 源码,一条端到端主线是这样流动的:

[人操作 GUI]
│ 鼠标/键盘/截图/窗口

① 录制引擎 record.py ──► 多个读线程 ──► event_q ──► 处理线程 ──► 分类写队列 ──► SQLite
│ (键盘/鼠标/屏幕/窗口/浏览器各一个线程)

② 事件后处理 events.py ── merge/discard ──► recording.processed_action_events(干净动作序列)


③ 重放策略 strategies/ ── 按描述给每个鼠标动作打上「active_segment_description」
│ 再用自然语言 instructions 改写整段动作

④ 视觉重定位 visual.py ── 对当前屏幕:分割 → 描述每块 → 按描述找回坐标


⑤ playback.play_action_event ── 用 pynput 真的去点/打字

2.3 部件一句话职责

部件干什么在哪个文件(legacy)
录制引擎多线程采集鼠标/键盘/截图/窗口/浏览器事件,落 SQLiteopenadapt/record.py
数据模型Recording / ActionEvent / Screenshot / WindowEvent 等 ORMopenadapt/models.py
事件处理把海量原始事件 merge/discard 成干净序列openadapt/events.py
重放基类定义「拿到截图 → 产出下一个动作 → 重放」的循环openadapt/strategies/base.py
视觉策略分割 + 描述 + 按描述重定位(核心创新)openadapt/strategies/visual.py
视觉工具从分割图抽 mask、算包围盒/质心、SSIM 相似度openadapt/vision.py
分割适配器调 Set-of-Mark / FastSAM 把窗口切成区域openadapt/adapters/som.pyultralytics.py
模型适配器统一 OpenAI/Anthropic/Google 的多模态提示接口openadapt/adapters/prompt.py
v1.0+ CLI统一命令入口,懒加载子包openadapt/cli.py(仓库根)

2.4 一句话把主线走一遍

输入是你的一次示范;录制引擎把它拆成上千条原始事件落库;事件处理把它压成几十条干净动作;重放策略给每个点击标注「你点的是哪个元素(用一句描述)」,并按你的自然语言指令改写;重放时对当前屏幕重新分割、重新描述,用描述找回那个元素现在在哪,最后真的去点。输出是在新场景上完成同一个任务

3. 往下读哪一章

  • 想搞懂「录一段示范到底记了什么、怎么记」 → 读 01-record-pipeline.md
  • 想搞懂「为什么原始事件要清洗、怎么清洗」 → 读 02-event-processing.md
  • 想搞懂「有哪些重放策略、各自取舍」 → 读 03-replay-strategies.md
  • 想搞懂本项目最核心的巧思「按描述重定位」 → 直接读 04-visual-grounding.md(精华在此)。
  • 想搞懂新版 v1.0+ 的元包/CLI 架构 → 读 05-meta-package-cli.md

建议顺序:1 → 2 → 3 → 4 → 5。赶时间只读 4(视觉重定位是 OpenAdapt 区别于普通宏录制的地方)。

4. 代码地图(导航索引)

主题文件路径(相对克隆根)关键符号
v1.0+ CLI 入口openadapt/cli.pymaincapture_starttrain_starteval_run
v1.0+ 懒加载openadapt/__init__.py__getattr__
v1.0+ 统一配置openadapt/config.pyOpenAdaptSettingssettings
录制主流程legacy/openadapt/record.pyrecordprocess_eventsread_mouse_events
数据模型legacy/openadapt/models.pyRecordingActionEventScreenshotWindowEvent
事件处理legacy/openadapt/events.pyget_eventsmerge_eventsremove_redundant_mouse_move_events
重放基类legacy/openadapt/strategies/base.pyBaseReplayStrategyrun
视觉重定位legacy/openadapt/strategies/visual.pyVisualReplayStrategyget_window_segmentationget_active_segment
视觉工具legacy/openadapt/vision.pyget_masks_from_segmented_imagecalculate_bounding_boxesget_image_similarity
分割适配器legacy/openadapt/adapters/som.pypredict

5. 横向对比(computer-use 货架)

OpenAdapt 在 computer-use 这一支里的独特取舍:不追求「零样本让模型自己看屏幕操作」,而是「用人类示范轨迹去消除 UI 歧义」(README 称之为 Trajectory-Conditioned Disambiguation,轨迹条件化消歧)。

  • 与「纯 VLM 直接看屏幕点坐标」的 agent 相比:OpenAdapt 多了一层录制 + 按描述重定位,把「点哪」从「模型凭空猜坐标」变成「在录制时标注的元素描述,重放时重新找回」。
  • 与传统 RPA(记死坐标/控件路径)相比:OpenAdapt 用分割 + 语言描述做定位锚点,对界面漂移更鲁棒。

各机制的具体实现见分章;这是货架级视角,细节下钻到 04-visual-grounding.md