Article

agent-desktop 深度解析:不截图,也能让 Agent 操控桌面

· 10 min read · Written in Chinese

GitHub 上今天(2026-11-04)能查到的 vercel-labs/agent-desktop 大约 13,135 星,语言是 Rust,许可证 Apache-2.0。最新发版是 v1.1.0(2026-11-03),npm 上同名包也是 1.1.0。

它让 Agent 看见并操作桌面应用,但不靠截图,也不做像素匹配。它读操作系统暴露的无障碍树,吐出 JSON;每个能动手的元素带一个 ref。Agent 对着 ref 点或输入,再读一遍界面确认结果。循环写在你的 Agent 里,agent-desktop 本身不内嵌模型。

官网文档写得很直白:它是工具,不是 Agent;桌面应用才是它的范围,网页请用同系列的 agent-browser。

观察、定位、行动、验证的四步循环:snapshot 读树,元素带 ref,对 ref 操作,再 snapshot 确认

一次最小循环长什么样

官方 quick start 用 Finder 举例。命令大致是:

agent-desktop snapshot --app Finder -i
agent-desktop click @s8f3k2p9:e8
agent-desktop snapshot --app Finder -i

每条命令吐一个 JSON 信封。快照里有 snapshot_id、ref_count、以及一棵带 role、name、ref_id、available_actions 的树。ref 必须写成 @快照id:元素id 这种限定形式;裸的 @e8 会直接报 INVALID_ARGS。

文档里还有四步演示:先 skeleton 扫一眼,再 --root 钻进某个区域,再 click,再用 wait --predicate 核对显示值。成功点一下,并不等于界面已经变成你想要的样子,所以循环要以一次读取收尾。

装法也很短:npm i -g agent-desktop,或者 macOS/Linux 上 brew install agent-desktop。跑起来先 agent-desktop status,macOS 还要按 permissions --guide 把辅助功能权限授给调用它的那个进程。

分层:从你的 Agent 到系统 API

文档站把调用链写成七层。我画成更常见的分层条带,方便对照仓库里的 Cargo workspace:

分层:调用方 Agent/MCP → CLI/FFI → core 与 PlatformAdapter → macos/windows/linux → 桌面应用

要点有几条,都来自官方介绍和仓库结构:

  1. 调用方是你的代码或 LLM 循环。它负责观察、行动、验证。
  2. 入口是 CLI,或者进程内的 C 库 libagent_desktop_ffi。两边跑同一套 core。
  3. agent-desktop-core 管命令、RefStore、快照拼装,并定义 PlatformAdapter trait。
  4. core 只通过 PlatformAdapter 碰操作系统。平台 crate 之间互不引用。
  5. 真正连 OS 的是 agent-desktop-macos(AX API)、agent-desktop-windows(UI Automation)、agent-desktop-linux(AT-SPI)。每个二进制只编自己那一平台。
  6. 应用必须把自己的界面通过无障碍 API 暴露出来。树里没有的东西,它就看不见。

workspace 成员是 crates/core、macos、windows、linux、ffi,外加 src(CLI)。Cargo.toml 里写的 workspace 版本是 1.1.0,edition 2024,rust-version = "1.89"。

对 Agent 还很实用的是:二进制自带版本对齐的技能指南。agent-desktop skills get desktop 讲循环、ref、校验和重试规则;skills get platform 讲当前 OS 的差异。也可以 npx skills add https://github.com/vercel-labs/agent-desktop --skill agent-desktop。MCP 入口是 agent-desktop mcp,把各条命令挂成 stdio 工具,名字类似 desktop_snapshot、desktop_click。

命令名一共 60 个,其中 56 个可直接跑;key-down / key-up / mouse-down / mouse-up 四处按住类动作会拒绝,直到有守护进程能负责松开。默认动作是无头的:不挪指针、不抢焦点。需要物理输入时再加全局 --headed。

ref 为什么会过期

ref 是某次快照里,给可操作或可下钻节点分配的短标识。同一快照内它是确定的,但跨界面变化并不稳定。行动前会走严格重识别:用存下来的身份证据,在活树上找匹配。找不到就 STALE_REF,找到多个就 AMBIGUOUS_TARGET,它不猜。

ref 生命周期:snapshot 分配限定 ref,行动前严格重识别,匹配则执行,否则 STALE_REF 或 AMBIGUOUS_TARGET,再重新 snapshot

CONCEPTS.md 把这件事写得很细。身份证据包括角色、native id、稳定名称和描述;可变的输入框内容不当作身份。macOS 上若拿得到元素自己的 accessibility 地址,可以直接回指;其它情况靠“完整窗口观察 + 谓词唯一匹配”。窗口句柄还会被 OS 回收,所以身份会再叠一层进程世代校验,避免点到后来占用同一句柄的新窗口。

对写 Agent 的人,实用规则只有三条:

  • 永远用带快照 id 的限定 ref。
  • 界面一变就重新 snapshot,别死磕旧 ref。
  • 看错误信封里的 error.disposition.retry:标成 safe 才重试。

默认还有自动等待:对 ref 的动作会在有限预算内轮询到可操作(文档写默认 5000ms,type 再按字符加一点)。--timeout-ms 0 可以关掉,改成立刻试一次。

走无障碍树,跟截图派差在哪

“Computer Use” 这个词现在常被截图派占着:模型看屏幕图,估坐标,再合成鼠标键盘。agent-desktop 走另一条路。两边都能让 Agent 碰桌面,取证方式和失败模式差很多。

对比表:看见什么、怎么点、模型角色、边界、适合场景

我更在意这几条差异:

  • 输出是结构化树。按钮叫什么、能不能点,写在字段里,少一轮“从图里猜”。
  • 默认无头。语义路径走得通时,不必把鼠标晃来晃去,也少干扰你正在用的会话。
  • 工具不含模型。你可以把 snapshot 结果喂给任意模型,也可以写成确定性脚本,完全不经过 LLM。
  • 边界也很清楚:应用没暴露无障碍树,它就瞎了;纯图画、自定义绘制控件,往往不如截图派。Chromium / Electron 里的网页内容,文档建议另开 DevTools 端口交给 agent-browser。

平台门槛写在 README 和文档站:macOS 13+(Intel / Apple Silicon),Windows 10 1809+ 或 Server 2019+(x64 / ARM64,且在登录用户的交互桌面里),Linux 以 Ubuntu 24.04+ 为参考(glibc 2.35 底线,需要图形会话和 AT-SPI 总线)。三端命令名一致,但哪些能无头、哪些必须 --headed、哪些直接拒绝,要看各平台页。

动手时我会怎么接

如果要把桌面能力接进现有 Agent,我大概会按这个顺序:

  1. 本机装好,跑通 status 和 permissions。
  2. 让 Agent 先读 skills get desktop 和 skills get platform,再开始点。
  3. 会话用 session start,需要回放再开 trace / 截图工件;注意工件可能带桌面隐私内容。
  4. 能语义走通就别开 --headed。Windows 上 type 没有无头语义路径,文档明确说无头文本写入走 set-value。
  5. 失败只看结构化错误和 disposition,别靠自然语言猜能不能重试。

对做桌面小应用的人,还有一个很实在的副作用:无障碍标签写清楚,Agent(以及屏幕阅读器)都更好用。name、角色、AutomationId / AXIdentifier 这些字段,会直接进 snapshot。标签稀碎的界面,树读出来也稀碎。

如果你在做类似 orca-agent 这种自己控循环的 Agent,agent-desktop 适合当“桌面眼睛和手”:CLI 或 FFI 调用,JSON 进你的状态机,模型只负责决策。网页自动化继续留给浏览器工具。

材料与时效

本文数字与接口说明来自 2026-11-04 当天可读的公开材料:

  • 仓库 README、CONCEPTS.md、Cargo workspace
  • 文档站 agent-browser.dev/desktop 及其 Snapshots and refs、平台页
  • GitHub API 的 star / license / 最新 Release,以及 npm agent-desktop@1.1.0

我没有在本机实际驱动三端无障碍栈做端到端实测;文中的行为描述以官方文档和概念词汇表为准。版本继续迭代时,以仓库和文档站为准。

Keep Reading

Related articles

Discussion

Published after moderation · Markdown supported

Discussion loads when you reach this section.