让 AI 智能体
读得懂桌面应用
agent-desktop 读取操作系统的可访问性树,把它变成带 ref 的 JSON。 智能体对一个 ref 执行动作,再快照一次来核对——全程不做像素匹配, 控制循环始终留在你自己的智能体里。
$ agent-desktop snapshot --app Finder -i
{
"version": "2.6",
"ok": true,
"command": "snapshot",
"data": {
"app": "Finder",
"snapshot_id": "s8f3k2p9",
"ref_count": 59,
"complete": true,
"tree": {
"role": "treeitem",
"name": "Documents",
"ref_id": "@s8f3k2p9:e8",
"available_actions": ["Click"]
}
}
}
$ agent-desktop click @s8f3k2p9:e8
$ agent-desktop snapshot --app Finder -i # 再读一次核对边界
它是什么,不是什么
这四条决定了它适合放在系统的哪一层,也决定了它做不到什么。
智能体调用的工具
不是智能体。观察—操作—验证的循环由调用方持有,它只把界面变成可寻址的数据,再把一次动作落下去。
内部没有模型
不内嵌 LLM,没有图形界面,也没有交互式提示。每条命令打印一个 JSON 信封然后退出。
只管桌面应用
网页自动化请用 agent-browser。自己启动的 Chromium / Electron 应用里的网页内容,它会开一个 DevTools 端口让 agent-browser 连上去。
只读应用暴露的
它读可访问性树,不做像素匹配,所以一个不发布可访问性树的界面,它同样读不到。
控制循环
四步一轮:摸清、钻进、动作、核对
挑一步看它对应的命令和读数。一次成功的动作并不证明界面变了,所以每一轮都以一次读取结束。
agent-desktop snapshot --app Finder --skeleton -i --compact{ "role": "window", "name": "Downloads",
children: [
{ "role": "outline", "ref_id": "@s8f3k2p9:e1" },
{ "role": "list", "ref_id": "@s8f3k2p9:e3" },
{ "role": "toolbar", "ref_id": "@s8f3k2p9:e7" }
] }一次全量快照在密集应用里能产出上千个节点,骨架只给你几十行。
agent-desktop snapshot --root @s8f3k2p9:e3 -i --compact{ "role": "list", "ref_id": "@s8f3k2p9:e3",
children: [
{ "role": "treeitem", "name": "Documents",
"ref_id": "@s8f3k2p9:e8", "available_actions": ["Click"] },
{ "role": "treeitem", "name": "Downloads",
"ref_id": "@s8f3k2p9:e9", "available_actions": ["Click"] }
] }这一层才足够细,可以拿来动作。
agent-desktop click @s8f3k2p9:e8{ "version": "2.6", "ok": true, "command": "click" }ok 只说明请求被接受,不说明界面按你的预期变了。
agent-desktop wait --element @s8f3k2p9:e9 --predicate value --value Downloads{ "version": "2.6", "ok": true,
"command": "wait",
"data": { "matched": true, "elapsed_ms": 142 } }界面变了就用新快照里的 ref;旧 ref 会返回 STALE_REF。
实现
从调用方到应用,只有这一条链
core 永远不 import 任何平台 crate,平台 crate 之间也互不 import。只有 CLI 和 C 库把一个平台 crate 接到 core 上,并且在编译期就选定。
调用方
你的代码或 LLM 循环。运行一条命令,读它打印的 JSON 信封。
agent-desktop CLI / libagent_desktop_ffi
CLI 每次调用起一个独立进程;C 库在进程内直接调用同一套工具。
agent-desktop-core
命令、RefStore、快照构建。定义 PlatformAdapter trait 和所有共享类型。
PlatformAdapter
core 触达操作系统的唯一途径。
agent-desktop-macos
AX API
agent-desktop-windows
UI Automation
agent-desktop-linux
AT-SPI
操作系统的可访问性 API
macOS 的 AX API、Windows 的 UI Automation、Linux 的 AT-SPI。平台 crate 只通过它说话。
应用
通过上面那个 API 暴露它的界面。没暴露的,读不到。
一个二进制只驱动一个操作系统
平台在编译期选定,所以不存在运行时的跨平台分派,也不存在「在 Linux 上驱动 Windows 应用」这种路径。 每个平台的适配器只能在它自己的操作系统上构建。
平台
同一套命令,三种底层
命令名在三个平台完全一致,能力边界不同。最准确的对照表来自你脚下这台机器: agent-desktop skills get platform。
| 能力 | macOS | Windows | Linux |
|---|---|---|---|
| 可访问性树 | 支持 | 支持 | 支持(AT-SPI) |
| 点击 / 输入 / 键盘 | 支持 | 支持 | AT-SPI;X11 / GNOME 按键 |
| 鼠标输入 | 支持 | 支持 | X11,--headed |
| 截图 | 支持,需要「屏幕录制」 | 支持 | X11 窗口;Wayland 门户 |
| 剪贴板 | 支持 | 支持 | 支持;Wayland 需要 wl-clipboard |
| 应用与窗口管理 | 支持 | 支持 | 启动/列出;X11 窗口控制 |
| 通知 | 支持;通知中心需要 System Events 的自动化权限 | 支持 | GNOME Shell |
| 外壳界面 | Dock、菜单栏附加项 | 任务栏、系统托盘、开始菜单、操作中心 | 仅 system-tray 与 action-center 可用 |
| 前置条件 | 系统 | 架构 | 授权 |
|---|---|---|---|
| macOS | 13 或更高 | Intel / Apple Silicon | 辅助功能权限 |
| Windows | 10 1809 / Server 2019 起 | x64 / ARM64 | 终端同级完整性免授权 |
| Linux | Ubuntu 24.04(glibc 2.35+) | x86_64 / aarch64 | 图形会话 + AT-SPI 总线 |
命令
60 个命令名,56 个可执行
虚线划掉的那四个——key-down / key-up / mouse-down / mouse-up—— 已经发布,但在有守护进程能可靠释放被按住的按键或鼠标键之前会拒绝运行。这是设计上的失败关闭。
snapshotfindgetisscreenshotlist-surfacesclickdouble-clicktriple-clickright-clicktypeset-valueclearfocusselecttogglecheckuncheckexpandcollapsescrollscroll-topresshoverdragmouse-movemouse-clickmouse-wheelkey-downkey-upmouse-downmouse-uplaunchclose-applist-appslist-windowslist-displaysfocus-windowresize-windowmove-windowminimizemaximizerestoreopen-system-surfacelist-notificationsdismiss-notificationdismiss-all-notificationsnotification-actionclipboard-getclipboard-setclipboard-clearwaitsessiontracecursor-overlaystatuspermissionsversionbatchskills智能体接入
文档随二进制一起发布
智能体在动手之前先读它自己那个版本的规则,这样依据永远和正在调用的二进制对齐,而不是和某份会过期的网页文档对齐。
让智能体自己取规则
两条命令,一条讲跨平台的循环规则,一条讲你脚下这个平台的能力边界。只读一条,智能体会按另一个平台的假设行事。
agent-desktop skills get desktop # 循环、ref、验证与重试规则
agent-desktop skills get platform # 你这个平台上的能力边界
agent-desktop <command> --help # 单条命令的参数或者写进 AGENTS.md
不想装技能,就把这段直接放进仓库的 AGENTS.md。
使用 `agent-desktop` 来查看并操作桌面应用。首次使用前先运行
`agent-desktop skills get desktop` 和 `agent-desktop skills get platform`,
并按其中的说明执行。契约只有一个信封
每条命令打印一个 JSON 信封,包含 ok 以及data 或 error。 只有当 error.disposition.retry 为safe 时才重试。
{
"version": "2.6",
"ok": false,
"command": "click",
"error": {
"code": "STALE_REF",
"disposition": { "retry": "unsafe" },
"suggestion": "重新运行 snapshot,并使用新快照里的 ref"
}
}不想走 CLI,就在进程内调用
每个版本同时发布三个平台的 libagent_desktop_ffi,同一套 core、同一个适配器、同一份信封语义。
import ctypes
lib = ctypes.CDLL("./lib/libagent_desktop_ffi.dylib")
lib.ad_adapter_create.restype = ctypes.c_void_p
assert lib.ad_init(7) == 0 # ABI 主版本匹配才返回 AD_RESULT_OK
adapter = lib.ad_adapter_create()
lib.ad_adapter_destroy(adapter)快照、剪贴板、截图和调试产物都可能含私密内容
不要把它们放进公开日志或上传。可选的 JEV 助手会把屏幕描述发送给你配置的模型服务商, 它与原生 CLI 彼此独立。 隐私与数据处理 →