Skip to content
AI Ferryman Alex
Go back

Vercel 的 agent-desktop,讓 agent 像讀屏軟件一樣讀你的電腦

靠截圖開電腦的 agent 是在猜。它先給你屏幕拍張照,再把照片發給一個視覺模型,讓模型從像素裏猜按鈕在哪。你上一次看它把按鈕點錯,是什麼時候?

Vercel 的 agent-desktop 給 agent 換了一條路,因爲它讀的是操作系統本來就記着的那份控件清單。這條路這幾天很受關注。它 11 月 5 號那天單日就漲了大約 2,100 星,我第二天去查的時候,已經漲到 17,978 星,快 18,000 了。

這個工具是一個 Rust 寫的命令行程序,外加一個 C 語言庫。它按 Apache-2.0 協議開源,能跑在 macOS、Windows 和 Linux 上。

1.0.0 版是 10 月 28 號出的,之後版本一直在動,11 月 3 號出了 1.1.0,11 月 5 號又出了 1.2.0。它裏面沒有模型。決定下一步幹什麼的那個循環在你自己的 agent 那邊,因爲 agent-desktop 只是那雙手,它只負責看屏幕和點擊。

它看屏幕靠的是無障礙樹。無障礙樹就是操作系統給每個應用記的一份結構化清單。每一個按鈕、輸入框、菜單和複選框都在上面。每個元素叫什麼名字、是個什麼角色,也全寫得清清楚楚。

這份清單在 macOS 上來自 AX 接口,在 Windows 上來自 UI Automation,在 Linux 上來自 AT-SPI。它本來是給讀屏軟件用的,是爲了讓看不見的人也能用電腦纔有的。

agent 要一份快照,agent-desktop 就給它一段 JSON,裏面每一個能操作的元素都有一個編號,像 @s8f3k2p9:e8 這樣。agent 按這個編號點一下,然後再拍一份快照,看看剛纔那一下到底起了什麼變化。要是中間屏幕變了,那麼這次操作就會報一個 STALE_REF,意思是那個編號已經過期了。agent 得重新拍一份快照,而不是對着舊編號瞎點。

agent 是怎麼認識桌面的:對話框的按鈕以文字清單回來,每個都帶着編號,@e1 button "Stop"、@e2 button "Continue",agent 按編號點 @e1,程序用退出碼 1 確認按中的是 Stop 那一側

這跟截圖是兩種不一樣的看見。截圖是一張照片,agent 得從像素裏推算按鈕在哪。快照是文字,按鈕的名字就寫在裏面,所以 agent 不用猜座標,也不用每走一步都把一張照片發給視覺模型去看。

它默認是無頭模式,意思就是它直接跟無障礙接口說話,不用動你的鼠標,也不搶你正在用的窗口的焦點。從 1.2.0 開始,它還能把命令當成 MCP 工具提供出去,所以 agent 的宿主程序可以直接像調用其他工具一樣調用它。

我把 1.2.0 的 Linux 版下載下來,放到我這臺沒有桌面環境的服務器上跑了一下。我想看看,在沒東西可讀的地方,它到底會怎麼反應。

它的狀態命令回答得很直白:無障礙權限是被拒絕的狀態,能支持的界面一個都沒有,給出的理由是連不上 D-Bus 會話總線。我給它開了一個新的 D-Bus 會話再跑,它還是拒絕,這次的理由是這臺機器上沒有裝 AT-SPI,也就是 Linux 的那層無障礙接口。

我讓它列出機器上的應用,它直接報錯,說這個會話裏沒有可用的 AT-SPI 無障礙總線。所以在沒有無障礙層的地方,這個工具什麼都看不見,而且它會把缺的是哪一層說清楚。

所以我在這臺服務器上把缺的層一層一層補了上去。先裝上 AT-SPI,再配好會話總線和一塊虛擬屏幕,它這次能看見應用了,但是認不出窗口,因爲還差一個窗口管理器。把窗口管理器補上之後,它才真正能用。它預設的工作環境就是一臺平時在用的桌面電腦,工具自帶的說明裏也寫了,它是在 GNOME 桌面上測的。

補齊之後,我拿一個小對話框程序(zenity)當靶子。它彈出來的是一個問題對話框,上面兩個按鈕,一個寫着繼續,一個寫着停止。快照回來的是一段 1,149 字節的 JSON,一共 16 個節點。能點的兩個按鈕各自有一個編號,停止那個是 e1,繼續那個是 e2。

我讓 agent-desktop 按編號點了停止那一下,它返回說動作已經送達。然後我去看那個對話框程序的退出碼,是 1,正是按了停止那一側的結果。這一下點沒點中,不用看截圖猜,程序自己的反應就說明了。

但是省多少這件事,還是沒有可比的數字。市面上沒有公開發表過的對比數字,因爲沒有人把它跟截圖那條路放在同樣的任務上比過。所以 token 能省多少、速度能快多少,我這裏不會給你報一個對比數字。

省是省在結構上。進來的是文字而不是照片,出去的是準確的編號而不是猜出來的座標,所以中間不用過視覺模型。但是這個結構自己也要消耗 token,因爲快照本身就是一段要發給模型讀的文字。我實測的兩個對話框還都很小,一個 1,149 字節,另一個是帶 40 行數據的列表,3,079 字節。界面上的控件越多、嵌套越深,這段文字就越長。

工具自己對這件事的解法是骨架快照:agent 先拿一份裁剪過的樹把應用看個大概,然後再一個區域一個區域地往裏鑽,而不是一口把整棵樹吞下去。我拿那個 40 行的列表試了一下,骨架快照是 1,630 字節,比完整的少了差不多一半。

順帶還發現一件事:那個列表有 40 行數據,快照裏卻只有 45 個節點,因爲 GTK 的列表只把畫出來的行放進樹裏,所以樹的大小是跟着界面長什麼樣走的,不跟數據有多少行走。還有一種界面是這個工具看不見的:一個應用要是不提供無障礙樹,那麼它在這個工具眼裏就是不存在的,工具自己也這麼說了。

快照裏可能裝着你桌面上的隱私內容,剪貼板和截圖也一樣,README 裏把這句話寫得很明白:別把這些東西放進公開的日誌和上傳裏。所以我會只把它交給自己信得過的 agent,快照不寫進日誌,而且先在一個不打緊的應用上試試,等摸熟了再讓它去碰那個開着郵件和銀行頁面的應用。

我的看法是,電腦操作就是往這個方向走的,因爲讀清單總比猜像素靠譜,最後贏下來的工具會是那個讀清單的,而不是那個給屏幕拍照的。但是裝它之前,先想想它要的那份權限,因爲拿着這份權限的 agent,你看到什麼它就看到什麼。

要是這篇讓你去查了下自己的無障礙權限,歡迎訂閱這個博客,或者先收藏起來。我會接着寫 AI、安全和開源這幾塊的實事,下一篇我接着拆一個同類的工具。

來源:倉庫 https://github.com/vercel-labs/agent-desktop ;發佈帖 https://x.com/0xSpeter/status/2118512982657556508


在 X 上討論→

評論都在 X 上——回覆、引用和討論都在那邊進行。