你讓桌面 Agent 幫忙選一個檔案,它說「成功」,畫面卻還停在選檔面板;再點一次,又怕把表單送兩遍。這篇 Agent Desktop 多視窗教學,帶你把「找對視窗」「動作有沒有送到」「最後完成了什麼」拆開檢查。
本文寫給第一次串接桌面自動化、願意照著終端機操作的讀者。先用白話認識五個零件,再用兩個同名視窗與假文字檔練習;最後替 Agent 寫出何時重試、何時觀察、何時交還人的規則。
以下依 2026 年 11 月 3 日查閱的官方資料,固定正式版 1.0.2。AlphaLab 已執行版本與權限查詢;本機 macOS 26.1 未授予輔助使用與螢幕錄製權限,因此未執行多視窗或原生選檔自動化。下方是操作方法與自製練習頁,不是原生面板的重現紀錄。
先說結論:可靠交接=對準視窗+讀懂收據+驗收結果
可靠交接=對準視窗+讀懂收據+驗收結果。想像你請同事送件:辦公室房號是視窗 ID,櫃台號碼是 ref,操作回傳是遞件收據;最後要核對收件內容,才能說事情辦好了。
- 同名視窗用
--window-id區分;操作使用當次快照給出的完整 ref。 - 先讀
disposition.retry,再決定能否重送;「safe」仍要搭配錯誤原因修復。 - 選檔面板看得到,不等於選檔已完成。交還人後也要重新觀察檔名與送出次數。

一、Agent Desktop 多視窗教學:先認識五個零件
Agent Desktop 是讓 Agent 讀取與操作桌面應用程式的 CLI,也就是從終端機呼叫的工具。它透過作業系統的 accessibility tree(輔助使用樹,應用程式交給系統的介面結構)找按鈕與欄位;決定下一步的模型或腳本在外層。想補這層分工,可讀 Agent Harness 白話教學。
①「房號」:window-id
兩個視窗都叫「桌面選檔練習」,標題就像同名的人。list-windows 列出的 id 才能把這次操作縮到特定視窗。關閉再重開後,重新列出,不沿用舊號碼。
②「現場清單」:snapshot
快照記下那一刻可讀的結構,不是持續更新的直播。-i 只保留可互動節點;如果要核對案件 A/B 的靜態文字,先拿掉它。檢查 data.complete,部分樹不能當成完整盤點。
③「附上清單編號的櫃台號碼」:qualified ref
例如 @s8f3k2p9:e8,前半是快照,後半是元素。這只是格式示例,執行時必須換成自己的回傳值;裸寫 @e8 會被拒絕。切視窗、開面板或改動清單後,重新觀察相關區域。
④「另開的小櫃台」:surface
sheet、menu、alert 是覆蓋在主視窗上的介面。原生選檔面板可能附在父視窗下;面板出現後,繼續點背後視窗的舊 ref,容易走錯流程。
⑤「遞件收據」:disposition
ok 是這次指令的整體回傳;delivery 說明送達證據,retry 說明是否安全重送。最後的檔名、內容與後端收件,仍是另一層驗收。
上述範圍與格式見官方 觀察指令文件。多個 Agent 若使用不同 Session(工具保存快照的命名空間),完整 ref 也要帶回原本的 Session;ref 裡有快照 ID,並不會跨過命名空間。
二、先固定版本與權限,別從正式資料開始
截至查閱日,最新正式 release 與 npm 版本為 1.0.2。下列指令適用已有 Node.js/npm 的 Mac;先安裝固定版,保存 version 的完整 JSON,再載入執行檔附帶的文件。
npm install -g agent-desktop@1.0.2
agent-desktop version
agent-desktop permissions
agent-desktop skills get desktop
agent-desktop skills get platform
agent-desktop snapshot --help
本機執行的 version 回傳 data.version: "1.0.2",外層 version: "2.5"。前者是工具版本,後者是 JSON 契約版本,兩者不要混在一起。主分支的 Unreleased 紀錄 已列出 2.6 變更,不能直接拿它當成已安裝版的輸出。
若輔助使用權限是 denied,先停止桌面操作。你可在自己使用的互動環境執行 agent-desktop permissions --guide,依 macOS 官方指引 授權啟動工具的應用程式,再查一次 permissions。螢幕錄製是截圖相關操作的權限,與讀取輔助使用樹分開檢查。
首輪只用虛構文字檔與空白瀏覽器視窗。快照、視窗標題、檔案側邊欄及 trace(操作紀錄)可能含私人內容;官方 資料處理說明 也提醒截圖不會因結構化欄位遮罩就自動安全。不要把整個家目錄的輸出貼到公開 issue。
三、建立兩個同名練習頁:讓成功有答案可核對
在一個新資料夾建立 demo-a.txt、demo-b.txt,內容分別是 demo-A、demo-B。將下方存成 a.html,再複製成 b.html,用同一瀏覽器的兩個獨立視窗各開一份。分頁與作業系統視窗是不同層,這次要練的是後者。
<!doctype html>
<html lang="zh-Hant"><meta charset="utf-8">
<title>桌面選檔練習</title>
<style>
body{font:24px system-ui;max-width:900px;margin:65px auto;color:#17212b;background:#f5f8fb}
label,button{display:block;margin:26px 0} input,button{font:inherit;padding:12px}
output{display:block;background:white;padding:24px;border:2px solid #bfd2df;border-radius:14px}
</style>
<h1 id="case"></h1>
<p>本機練習:只顯示選檔資訊,無網路上傳。</p>
<label>假檔案 <input id="file" type="file" accept=".txt"></label>
<output id="receipt" aria-live="polite">尚未選檔;模擬送出 0 次</output>
<button id="send" type="button">模擬送出</button>
<script>
const f=document.getElementById('file');
const out=document.getElementById('receipt');
const send=document.getElementById('send');
let count=0;
const name=location.pathname.endsWith('b.html')?'B':'A';
document.getElementById('case').textContent='案件 '+name;
function draw(){
const x=f.files[0];
out.textContent=x?`案件 ${name};${x.name};${x.size} bytes;模擬送出 ${count} 次`:
'尚未選檔;模擬送出 0 次';
}
f.addEventListener('change',()=>{count=0;draw()});
send.addEventListener('click',()=>{if(f.files.length){count++;draw()}});
</script></html>
兩頁標題相同,內文分別顯示案件 A、B。這是 AlphaLab 自製的最小練習頁:選檔後只顯示檔名與大小,「模擬送出」只增加頁面計數,沒有網路上傳。換檔或重載會重置計數;它能讓你發現重點兩次的錯誤,不能證明正式服務具備防重複機制。

先用滑鼠在 A 選 demo-a.txt,按一次模擬送出,確認頁面顯示對應檔名與 1 次;B 保持未選檔。這張人工答案本,是接下來的驗收目標。重新載入兩頁,再開始 Agent 操作;不要把這個人工準備步驟算成自動化成功。
四、Agent Desktop 多視窗教學:用房號與快照對準案件
第一步的痛點是「標題一樣,怎麼知道點誰?」先列出視窗,再逐個核對內文。以下以 Google Chrome 為例;若你用其他瀏覽器,改成 list-apps 實際列出的應用程式名稱。
agent-desktop list-apps
agent-desktop list-windows --app "Google Chrome"
# 將 w-1234 換成實際回傳的視窗 ID
agent-desktop snapshot --app "Google Chrome" --window-id w-1234 --compact
保存 A、B 各自的 window ID,核對頁面內文與檔名欄。只看到標題還不夠;若樹不完整,增加觀察預算或縮小範圍後再查。官方的自動選窗規則也可能選到唯一聚焦視窗,因此「沒有出現歧義錯誤」不代表你已經對準案件。
第二步的痛點是「拿到按鈕號碼後,另一個視窗又被觀察了」。保存完整 ref 與來源視窗。從 A 的快照取選檔按鈕 ref;假設回傳的是下例格式,才執行 click。示例號碼不能直接照抄。
agent-desktop click "@s8f3k2p9:e8"
# 開啟面板後,重新觀察父視窗的 sheet
agent-desktop snapshot --app "Google Chrome" --window-id w-1234 --surface sheet --compact
核對三樣東西:動作回傳的 data.surfaces、面板所在父視窗、面板中可操作的元素。如果 sheet 讀不到,就記下錯誤與送達狀態;不要把另一個「Open」視窗直接當成同一個目標。list-surfaces --app "Google Chrome" 可補看現有覆蓋介面,但結果不明時也要保留未知。
五、原生選檔卡住:先分辨四個狀態
2026 年 10 月 31 日的 Issue #360 回報者使用 1.0.2、macOS 15.3 與 Chrome for Testing 151.0.7922.47。他記錄了獨立 Open 視窗讀取失敗、從父視窗 sheet 能看到面板,以及快捷鍵與搜尋未完成選檔的現象。這是特定環境的使用者觀察,不據此推論每一台 Mac 或當前主分支都一樣。
- 看得到:快照是否包含檔案列表與按鈕?能讀結構,只證明這一層可見。
- 對得準:面板屬於哪個父視窗?焦點或當前選取項目是否符合目標?
- 送到了:這次動作是未送出、送達但未驗證,還是送達情況不明?
- 完成了:面板關閉後,原表單顯示的是否為預期檔名?模擬送出是否恰為一次?
第三步的解法是先決定可接受的互動邊界。1.0.2 預設 headless 是透過語意介面操作、不搶焦點的模式;不是保證背景完成所有工作。官方 核心操作規則 明定物理輸入需要明確允許,不能為了修復 headless 失敗自行切成 --headed。這篇練習在遇到這條界線時交還人選檔。
交接訊息應寫得具體:「案件 A,父視窗 w-…,目標 demo-a.txt;選檔按鈕已點過,最後 delivery 為…;請只完成選檔,先不要按模擬送出。」讓其他 Agent 暫停同一視窗的操作,並把該視窗交接給同一位操作者;選好後再取新快照,查 A 的檔名、B 仍未選檔,才解除暫停。
六、重試規則:safe 只表示這次沒有送出
第四步的痛點是「報錯了,要不要再按一次?」先看送達,再看修法。依 1.0.2 的 JSON 操作契約,not_delivered 對應 retry: safe;其餘已知送達值屬 unsafe,unknown 也不應自動重送。
例如 STALE_REF 且 safe,先取新快照,核對仍是同一案件後,用新 ref 再做;若是參數錯誤,修參數;若是能力或權限問題,等待同樣秒數通常不會改變前提。safe 是防重複門檻,不是保證下一次會成功。
若 ok: true 但 delivery: delivered_unverified,先讀畫面;若是 delivery_uncertain 或 unknown,也先觀察。即使 delivered_verified,仍要看驗證範圍:欄位值或視窗位置已驗證,不等於伺服器已保存整筆表單。
讀取回傳
若為觀察指令成功 → 核對資料完整性與目標
若為動作回傳或錯誤 → 讀取 disposition
retry == safe → 修復原因、重新核對目標,再做有限次重試
其他或缺少 disposition → 先觀察,不自動重送
觀察到預期後置狀態 → 記錄完成證據
仍不明或碰到互動邊界 → 暫停該視窗,交接
這是決策偽碼,不是可直接執行的 CLI,也省略了正式系統的 JSON 型別檢查、截止時間、互斥鎖與持久化。正式串接依上方 JSON 契約解析欄位;本練習可把「修復後再試」上限設為一次,超過就留下證據交接。這個上限是本篇保守設定,不是工具內建保證。
七、回到表單後,驗收一次完整交接
第五步的解法是把最後結果寫成可對帳的收據。人選完檔後,重新 snapshot A,確認案件 A、demo-a.txt 與大小;再觀察 B,確認沒有被改動。最後只點一次 A 的模擬送出,取新快照讀到「模擬送出 1 次」。若指令逾時,先讀這個計數,別靠報錯猜測有沒有按到。
保存自己的紀錄欄位:工具/JSON 版本、OS/瀏覽器版本、案件、window ID、snapshot ID、ref、預期變更、delivery、retry、觀察到的檔名與次數、接手者及下一步。這份練習收據是你設計的記錄格式,不是工具自動提供的伺服器收件證明。
換到真正的上傳系統,完成條件還要多一層:後端回傳的紀錄 ID、附件名稱與大小,必要時核對內容指紋。若服務提供冪等鍵(重送同一工作時用同一個識別碼),再將它納入串接;單靠視窗鎖或頁面計數,不會得到外部操作恰好一次的保證。相關原理可接著看 逾時後如何驗收工具結果 與 Agent Task Lease 與外部操作去重。
常見問題:八個先講答案的判斷
1. Agent Desktop 自己會思考下一步嗎?
不會。它提供觀察與操作工具;模型或控制腳本負責安排流程與判讀結果。
2. 同名視窗一定會報錯嗎?
不一定。官方選窗規則也會考慮焦點。要做可追查的多視窗流程,仍明確指定 window ID。
3. 有完整 ref,就能永遠用下去嗎?
不能。畫面或元素狀態變化後重新觀察;Session 所有權也要一致。
4. 看得到 Open 按鈕,就代表可以背景選檔嗎?
不一定。可見性、動作能力、焦點需求與最終檔名是四個不同問題。
5. safe 就可以無限重試嗎?
不可以。它表示此動作未送達;還要修復錯誤原因,設定次數與截止時間。
6. delivered_verified 等於上傳成功嗎?
不一定。先看它驗證了哪個後置條件,再找應用程式或後端的完成證據。
7. 卡住就加 –headed 嗎?
不要自動加。物理輸入會碰到焦點與游標邊界;本篇採交還人選檔,再重新驗收的流程。
8. 這份假表單能測正式上傳可靠度嗎?
不能。它只練本機選檔、視窗定位與重複點擊檢查;正式系統還要驗後端保存、去重與錯誤復原。
給新手的三個重點
- 先用房號確認案件,再用當次快照的號碼操作。
- 動作回傳只是其中一張收據,重試前先查是否可能已送達。
- 交接要有明確範圍,接回來先核對結果,再繼續下一步。
接著閱讀
左右滑動查看更多推薦
下一步:先交回一個能核對的案件
今天先完成 A 的一次選檔交接,讓 B 保持原樣,留下檔名、次數與送達判讀。這就是「可靠交接=對準視窗+讀懂收據+驗收結果」的第一張成績單。想把它接成自己的 Agent 系統,可以從 AlphaLab AI 課程 繼續練習,再回到 AI 教學文章庫 找下一個工具。
