極簡(jiǎn)原型)
最近兩個(gè)星期我朋友圈和幾個(gè)技術(shù)社群里全是CUA這三個(gè)字母。有人說是AI要取代程序員了有人說這不就是老掉牙的RPA套了層大模型皮嗎還有人把Computer Use Agent念成“cua”說這玩意兒操作電腦跟嘴里喊一聲“嗖”一樣快。吵歸吵我實(shí)際把好幾款支持屏幕操作和桌面自動(dòng)化的智能體方案跑了一遍也自己寫了一個(gè)最小可用的Agent原型。這篇把CUA到底是什么、它能干什么、不能干什么、以及你自己怎么從零搭一個(gè)全部攤開講清楚。想搞AI Agent落地的人、做自動(dòng)化流程設(shè)計(jì)的朋友這篇應(yīng)該能幫你少走不少彎路。1. CUA不是新概念但偏偏在2025年火了1.1 從“AI只能出嘴”到“AI可以出手”先回憶一個(gè)場(chǎng)景過去我們用ChatGPT或者各類模型助手最多是讓它寫一段代碼、給一個(gè)方案然后我們自己復(fù)制粘貼到電腦里去執(zhí)行。這個(gè)鏈路的瓶頸不在模型而在“最后一公里”。模型知道應(yīng)該點(diǎn)哪個(gè)按鈕、輸入什么內(nèi)容但它沒有眼睛和手。CUA要補(bǔ)的正是這一段。我自己的體感是CUA這個(gè)詞從2024年下半年開始密集出現(xiàn)在技術(shù)社區(qū)的分享里到2025年幾乎成了AI Agent賽道的標(biāo)配話題。核心原因是模型能力終于跨過了一個(gè)閾值它不僅能看懂自然語言還能把一張電腦截圖里的按鈕、輸入框、菜單欄當(dāng)成“視覺輸入”來處理并且給出“該點(diǎn)哪里”的精確坐標(biāo)。這個(gè)能力往前推三五年基本是做不到的。1.2 CUA到底是什么Computer Use Agent直譯就是“計(jì)算機(jī)使用智能體”英文里也有Computer Using Agent的寫法。它指的不是某個(gè)單一模型而是一套能觀察圖形界面、推理操作步驟、通過鼠標(biāo)鍵盤輸入與系統(tǒng)交互的智能體系統(tǒng)。它在技術(shù)上的核心組件有三個(gè)感知模塊負(fù)責(zé)獲取屏幕畫面、窗口結(jié)構(gòu)、UI元素信息決策模塊通常由一個(gè)多模態(tài)大模型承擔(dān)根據(jù)當(dāng)前屏幕狀態(tài)決定下一步做什么執(zhí)行模塊把決策轉(zhuǎn)換成真實(shí)的鼠標(biāo)移動(dòng)、點(diǎn)擊、鍵盤輸入、滾動(dòng)等系統(tǒng)事件這三個(gè)模塊串起來就形成了一條“觀察-思考-行動(dòng)-再觀察”的循環(huán)。你可以把它理解成給大模型裝了一雙眼睛和一雙手讓它能像人一樣坐在電腦前干活。1.3 為什么偏偏是這兩年爆發(fā)很多年前RPA機(jī)器人流程自動(dòng)化就已經(jīng)能做類似的事情但CUA的爆發(fā)有幾個(gè)客觀條件多模態(tài)模型成熟了。早期CV模型只能做物體檢測(cè)、OCR識(shí)別出“這里有一個(gè)按鈕”但理解不了“這是一個(gè)保存按鈕點(diǎn)擊后應(yīng)該出現(xiàn)保存成功的提示”?,F(xiàn)在的多模態(tài)大模型把視覺和語義理解揉在一起看到一個(gè)復(fù)雜界面能像人一樣理解整體布局和交互關(guān)系。指令遵循和規(guī)劃能力到了可用級(jí)別。一個(gè)CUA任務(wù)往往需要連續(xù)操作十幾步甚至幾十步模型必須記住目標(biāo)是什么、當(dāng)前做到哪一步、出錯(cuò)之后怎么回退。Instruction Following能力不夠強(qiáng)的模型跑三步就忘了最終任務(wù)。各家廠商把基礎(chǔ)能力開放出來了。底層模型、屏幕理解API、Agent框架陸續(xù)開放開發(fā)者不需要自己從零訓(xùn)練一個(gè)“會(huì)點(diǎn)鼠標(biāo)”的模型直接調(diào)接口就能搭出一套可用的方案。開源生態(tài)也跟上了本地模型配合UI解析工具也能實(shí)現(xiàn)一個(gè)小規(guī)模CUA。成本曲線在往下走。視頻視覺模型的單次調(diào)用價(jià)格比兩年前低了一個(gè)數(shù)量級(jí)截圖理解這種任務(wù)不再是大廠專屬。再加上“cua”這個(gè)口語化的簡(jiǎn)稱在網(wǎng)上越傳越廣術(shù)語本身也出圈了。2. CUA、RPA、瀏覽器自動(dòng)化看著像其實(shí)不是一回事2.1 RPA的問題在于“菜單記憶”很多朋友一聽到CUA就想到RPA這很自然。但這兩者底層邏輯完全不同。傳統(tǒng)RPA本質(zhì)上是一個(gè)放映機(jī)你錄一遍流程它以后按同樣的軌跡播放。它靠的是固定坐標(biāo)、控件選擇器、窗口句柄這些“硬鉤子”。問題就在于桌面軟件改個(gè)版式彈窗位置變一下頁面加了一個(gè)新的bannerRPA的流程就斷了。我拿一個(gè)生活化的例子來講RPA就像你每天去同一家餐廳照著上次點(diǎn)的菜單原封不動(dòng)再點(diǎn)一遍。只要餐廳換個(gè)菜單版式、菜名改個(gè)字你就懵了CUA不一樣它像是一個(gè)坐在餐桌前的人先看一眼當(dāng)前菜單判斷“我要的紅燒肉這道菜在不在在哪里”然后才動(dòng)筷子。這個(gè)差異決定了RPA適合極穩(wěn)定的高頻流程CUA適合有一定變化但目標(biāo)清晰的長(zhǎng)尾任務(wù)。2.2 瀏覽器自動(dòng)化被限制在“瀏覽器容器”里再說瀏覽器自動(dòng)化典型工具有Playwright、Selenium、Puppeteer。它們確實(shí)能做復(fù)雜的網(wǎng)頁操作但工作范圍被嚴(yán)格限制在瀏覽器內(nèi)部通過DOM選擇器找到元素再模擬點(diǎn)擊、輸入。一旦目標(biāo)跳出瀏覽器范圍比如需要從網(wǎng)頁復(fù)制數(shù)據(jù)再填進(jìn)一個(gè)桌面Excel表格或者網(wǎng)頁彈出了操作系統(tǒng)級(jí)別的文件選擇框?yàn)g覽器自動(dòng)化就無能為力了。而CUA工作在操作系統(tǒng)層面它像一個(gè)真實(shí)用戶一樣操作整個(gè)桌面環(huán)境。瀏覽器只是它要操作的對(duì)象之一文件管理器、辦公軟件、內(nèi)部系統(tǒng)客戶端只要屏幕上能顯示、能用鼠標(biāo)鍵盤交互的東西理論上它都能操作。這個(gè)范圍上的差異是本質(zhì)性的。2.3 用一張表看清三者差異維度傳統(tǒng)RPA瀏覽器自動(dòng)化CUA驅(qū)動(dòng)方式錄制腳本固定選擇器DOM元素選擇器多模態(tài)模型語義理解工作范圍桌面/指定軟件瀏覽器內(nèi)網(wǎng)頁整個(gè)操作系統(tǒng)界面抗界面變化能力差改版即失效中依賴選擇器更新較強(qiáng)靠語義識(shí)別長(zhǎng)尾任務(wù)處理差流程外情況無法處理差好可實(shí)時(shí)推理單次運(yùn)行成本低低較高模型推理產(chǎn)生費(fèi)用部署門檻中低中高需要模型API或本地算力2.4 我的判斷不是替代是互補(bǔ)現(xiàn)在很多人討論“CUA會(huì)不會(huì)干掉RPA”我的看法是短期內(nèi)不會(huì)而且兩者很可能長(zhǎng)期共存。RPA在強(qiáng)規(guī)則、強(qiáng)審計(jì)、高穩(wěn)定性的場(chǎng)景里依然有優(yōu)勢(shì)比如財(cái)務(wù)對(duì)賬、批量報(bào)表這些流程不允許模型“臨場(chǎng)發(fā)揮”。CUA更適合的是那些RPA寫起來極其痛苦、規(guī)則極難窮舉的場(chǎng)景比如不同界面的填表、數(shù)據(jù)搬運(yùn)、界面巡檢。更聰明的做法是把兩者混編CUA負(fù)責(zé)判斷和導(dǎo)航RPA負(fù)責(zé)執(zhí)行已經(jīng)被驗(yàn)證過的高頻動(dòng)作。這樣既省了模型調(diào)用費(fèi)用又提升了整體穩(wěn)定性。3. 拆開一個(gè)CUA感知、規(guī)劃、執(zhí)行、驗(yàn)證四段閉環(huán)3.1 感知層截圖只是最底層的方案CUA的感知層有兩條技術(shù)路線實(shí)際項(xiàng)目里最好兩條都上。第一條是純屏幕截圖。把當(dāng)前屏幕或者指定窗口截下來交給多模態(tài)模型去理解。這條路最通用什么軟件都適用因?yàn)槿祟惸芸吹乃湍芸础H秉c(diǎn)是截圖分辨率高的時(shí)候token消耗大而且模型只能“看”到像素拿不到元素背后的屬性信息比如一個(gè)按鈕的控件ID、一個(gè)輸入框的變量名。第二條是讀取系統(tǒng)可訪問性樹Accessibility Tree。操作系統(tǒng)為了讓輔助功能工具能讀屏?xí)┞犊丶湫畔⒚總€(gè)按鈕、文本、輸入框叫什么、在什么坐標(biāo)、當(dāng)前是什么狀態(tài)。訪問可訪問性樹就像拿到一份帶標(biāo)注的地圖比純截圖精確得多。我在自己的原型里采用的做法是優(yōu)先讀可訪問性樹拿到界面元素和坐標(biāo)只有樹拿不到關(guān)鍵信息時(shí)才補(bǔ)一張截圖讓模型判斷語義。比如一個(gè)空白畫布上沒有可識(shí)別的按鈕但模型通過截圖能看出這是畫布區(qū)域這時(shí)截圖就很有用。純截圖相當(dāng)于人瞇著眼找按鈕可訪問性樹相當(dāng)于直接給按鈕貼了坐標(biāo)標(biāo)簽兩者結(jié)合最穩(wěn)。3.2 規(guī)劃層模型怎么決定“接下來點(diǎn)哪兒”規(guī)劃層是CUA的大腦通常由一個(gè)指令遵循能力強(qiáng)的大模型承擔(dān)。它的輸入是當(dāng)前屏幕狀態(tài)和用戶目標(biāo)輸出是下一個(gè)動(dòng)作。這里有一個(gè)關(guān)鍵設(shè)計(jì)不要讓模型輸出自然語言“你應(yīng)該點(diǎn)擊文件菜單”而是強(qiáng)制它輸出結(jié)構(gòu)化JSON。我在項(xiàng)目里給模型固定的輸出格式{ thought: 當(dāng)前頁面有用戶登錄框需要先點(diǎn)擊用戶名輸入框, action: { type: click, x: 320, y: 180 } }保留thought字段有一個(gè)額外價(jià)值審計(jì)。當(dāng)Agent做錯(cuò)時(shí)你可以回看它當(dāng)時(shí)的“思考過程”定位是哪一步理解出錯(cuò)了。這在調(diào)試多步任務(wù)時(shí)幾乎是救命的功能。3.3 執(zhí)行層把意圖變成鼠標(biāo)鍵盤事件執(zhí)行層相對(duì)簡(jiǎn)單但坑不少。我最早用pyautogui做鼠標(biāo)鍵盤模擬因?yàn)樗缙脚_(tái)、API簡(jiǎn)單。在Windows上直接能用在macOS上需要給終端開啟輔助功能權(quán)限系統(tǒng)設(shè)置-隱私與安全性-輔助功能否則鼠標(biāo)事件會(huì)被系統(tǒng)攔截。執(zhí)行時(shí)有三個(gè)實(shí)操細(xì)節(jié)值得注意鼠標(biāo)移動(dòng)到目標(biāo)坐標(biāo)后不要立刻點(diǎn)擊最好等0.2到0.5秒讓系統(tǒng)完成界面渲染點(diǎn)擊后不要馬上進(jìn)入下一步留出界面響應(yīng)時(shí)間具體時(shí)長(zhǎng)要看目標(biāo)軟件的反應(yīng)速度輸入中文文本時(shí)不要用keyboard.type逐字模擬中文輸入法會(huì)搗亂正確做法是先把文本寫入剪貼板再模擬CtrlV粘貼3.4 驗(yàn)證層動(dòng)作做完必須確認(rèn)“有沒有生效”很多初版CUA原型最缺的就是驗(yàn)證層。模型說“點(diǎn)擊下一步”系統(tǒng)也確實(shí)點(diǎn)擊了但界面上彈了一個(gè)對(duì)話框擋住了下一步按鈕此時(shí)Agent如果繼續(xù)按照原計(jì)劃操作就會(huì)一路點(diǎn)錯(cuò)。驗(yàn)證層的做法是每次執(zhí)行完動(dòng)作后截一張新圖讓模型判斷界面是否發(fā)生了預(yù)期變化。比如“點(diǎn)擊保存后是否出現(xiàn)了‘保存成功’的提示”。如果沒出現(xiàn)就要走異常處理分支重試、截圖分析原因、或者停下來請(qǐng)求人類幫助。在真實(shí)桌面環(huán)境里驗(yàn)證層比規(guī)劃層更重要。因?yàn)殄e(cuò)誤總是發(fā)生在“你以為成功執(zhí)行了”的時(shí)候。3.5 人的位置確認(rèn)模式必須要做現(xiàn)階段我不建議任何CUA系統(tǒng)全程完全無人監(jiān)督。至少保留一個(gè)可配置的“確認(rèn)模式”每執(zhí)行一個(gè)關(guān)鍵動(dòng)作之前先把動(dòng)作展示給用戶用戶確認(rèn)后才執(zhí)行。比如Agent要點(diǎn)擊“刪除”按鈕、要發(fā)送一封郵件、要提交一個(gè)表單這些都屬于高風(fēng)險(xiǎn)動(dòng)作必須經(jīng)過確認(rèn)。這不是保守而是CUA落地的底線。用戶信任是在一次次“沒有搞砸”中積累的一次亂點(diǎn)造成的損失可能讓整條產(chǎn)品線被拉黑。4. 用Python手搓一個(gè)極簡(jiǎn)CUA原型讓AI替你打開計(jì)算器算個(gè)加法4.1 環(huán)境準(zhǔn)備既然要自己動(dòng)手就上最簡(jiǎn)單的技術(shù)棧。我的原型依賴三個(gè)東西Python 3.10pyautogui截圖和鼠標(biāo)鍵盤模擬pillow圖像處理一個(gè)可調(diào)用的視覺語言模型服務(wù)云端API或本地模型都可以以下代碼以O(shè)penAI風(fēng)格的客戶端示例安裝命令pip install pyautogui pillow openai注意macOS用戶需要先給終端/IDE開啟輔助功能權(quán)限Windows用戶一般直接就能跑。多顯示器環(huán)境下建議先把分辨率固定下來或者在代碼里指定操作主屏幕。4.2 核心代碼截圖、決策、執(zhí)行下面是一段能跑的最小實(shí)現(xiàn)核心邏輯就是“截圖-讓模型決定動(dòng)作-執(zhí)行-循環(huán)”。你可以直接復(fù)制下來改成自己的任務(wù)。import json import time import io import base64 import pyautogui from PIL import Image from openai import OpenAI client OpenAI() # 需要提前配置好你的模型服務(wù)端點(diǎn)和密鑰 # 截圖并壓縮降低token消耗 def capture_screen(max_size(1280, 720)): img pyautogui.screenshot() img img.resize(max_size) img img.convert(RGB) buffer io.BytesIO() img.save(buffer, formatJPEG, quality70) return base64.b64encode(buffer.getvalue()).decode() # 讓模型基于當(dāng)前屏幕輸出一個(gè)動(dòng)作 def ask_for_action(screen_b64, instruction, system_prompt): response client.chat.completions.create( modelgpt-4o, messages[ {role: system, content: system_prompt}, {role: user, content: [ {type: text, text: instruction}, {type: image_url, image_url: { url: fdata:image/jpeg;base64,{screen_b64} }} ]} ], temperature0, ) return response.choices[0].message.content # 執(zhí)行模型返回的結(jié)構(gòu)化動(dòng)作 def execute_action(raw): action json.loads(raw) print(思考過程, action.get(thought, )) act action[action] if act[type] click: pyautogui.click(act[x], act[y]) elif act[type] type: pyautogui.write(act[text]) elif act[type] scroll: pyautogui.scroll(act[clicks]) elif act[type] wait: time.sleep(act[seconds]) elif act[type] finish: print(任務(wù)完成) return False return True # 系統(tǒng)提示詞約束模型只能輸出結(jié)構(gòu)化動(dòng)作 SYSTEM_PROMPT 你是一個(gè)計(jì)算機(jī)操作智能體。你會(huì)收到一張當(dāng)前屏幕截圖。 你的目標(biāo)是根據(jù)用戶指令完成操作。 只能輸出一個(gè)JSON對(duì)象格式如下 {thought: 你對(duì)當(dāng)前界面的判斷, action: {type: click, x: 0, y: 0}} action.type 可選值 - click: 必須提供x, y坐標(biāo) - type: 必須提供text內(nèi)容 - scroll: 必須提供clicks數(shù)正數(shù)向上滾動(dòng) - wait: 必須提供seconds秒數(shù) - finish: 表示你認(rèn)為任務(wù)已完成 def run_task(task_description, max_steps15): instruction task_description for step in range(max_steps): screen capture_screen() raw ask_for_action(screen, instruction, SYSTEM_PROMPT) print(f第{step 1}步, raw) should_continue execute_action(raw) if not should_continue: break time.sleep(0.8) # 等待界面響應(yīng) else: print(達(dá)到最大步數(shù)限制停止。) if __name__ __main__: run_task(打開電腦上的計(jì)算器計(jì)算 7 5顯示結(jié)果。)4.3 跑起來會(huì)發(fā)生什么第一次跑這個(gè)任務(wù)時(shí)你會(huì)看到Agent的行為不太像程序更像一個(gè)“人”第一次截圖是完整桌面模型判斷“需要先打開計(jì)算器”返回一個(gè)點(diǎn)擊任務(wù)欄圖標(biāo)的坐標(biāo)。執(zhí)行后第二次截圖顯示計(jì)算器已經(jīng)打開模型判斷“現(xiàn)在需要依次點(diǎn)擊7、、5、”于是連續(xù)返回幾次點(diǎn)擊動(dòng)作。最后它看到結(jié)果“12”顯示在屏幕上返回finish動(dòng)作循環(huán)結(jié)束。這個(gè)流程里模型并沒有任何“預(yù)先錄制”的坐標(biāo)它完全是依靠每次截圖里的視覺信息現(xiàn)場(chǎng)推理。這就是CUA和傳統(tǒng)RPA最不一樣的地方——換一臺(tái)電腦、換一個(gè)分辨率它依然能找到計(jì)算器的位置而RPA錄好的坐標(biāo)直接就廢了。4.4 為什么必須用結(jié)構(gòu)化JSON輸出有人可能會(huì)想為什么不直接讓模型用自然語言說“點(diǎn)擊x坐標(biāo)y坐標(biāo)”非要套一個(gè)JSON原因有三個(gè)第一解析穩(wěn)定。自然語言有無數(shù)種表達(dá)方式“點(diǎn)這里”“鼠標(biāo)左鍵按在某個(gè)位置”“點(diǎn)一下那個(gè)按鈕”每一樣都要寫正則去匹配遲早崩潰。JSON天然結(jié)構(gòu)化json.loads一次解析字段缺失一眼就能發(fā)現(xiàn)。第二執(zhí)行層可替換。模型層只產(chǎn)JSON執(zhí)行層只消費(fèi)JSON兩個(gè)模塊解耦。今天用pyautogui模擬鼠標(biāo)明天換成系統(tǒng)級(jí)的UI Automation框架甚至換成網(wǎng)頁自動(dòng)化工具執(zhí)行層改動(dòng)很小模型層完全不用動(dòng)。第三便于擴(kuò)展。后面想增加雙擊、拖拽、右鍵菜單、復(fù)制粘貼等能力只需要在JSON的action.type里加枚舉值然后在執(zhí)行層加對(duì)應(yīng)的分支函數(shù)模型會(huì)通過系統(tǒng)提示詞學(xué)會(huì)新動(dòng)作。4.5 離產(chǎn)品級(jí)還差多少上面這段代碼只是一個(gè)“視覺-動(dòng)作循環(huán)”的雛形距離真正能穩(wěn)定跑業(yè)務(wù)還差很多東西長(zhǎng)會(huì)話記憶任務(wù)一長(zhǎng)多輪截圖和動(dòng)作結(jié)果會(huì)超出模型上下文窗口需要做歷史信息壓縮和摘要循環(huán)和退避同一個(gè)動(dòng)作連續(xù)失敗幾次之后要繼續(xù)嘗試還是換一種方案需要一個(gè)決策機(jī)制局部截圖不需要每次都截全屏往往只裁剪變化區(qū)域就能決策成本和延遲都會(huì)大幅下降異?;謴?fù)某一步出錯(cuò)后能否回退到上一個(gè)穩(wěn)定狀態(tài)而不是越走越偏沙箱隔離在不可控系統(tǒng)環(huán)境里跑操作最好指定一個(gè)虛擬桌面或者容器來兜底我在實(shí)際項(xiàng)目里是先跑通最小原型再逐步把這些工程問題加進(jìn)去的。最忌諱一開始就把系統(tǒng)設(shè)計(jì)得像一個(gè)大而全的平臺(tái)結(jié)果連一個(gè)最簡(jiǎn)單的任務(wù)都跑不穩(wěn)。5. 什么場(chǎng)景值得交給CUA什么場(chǎng)景現(xiàn)階段別碰5.1 真正值得做的三類場(chǎng)景根據(jù)我的實(shí)測(cè)下面三類場(chǎng)景CUA的效果最明顯ROI也最高。第一類是跨系統(tǒng)數(shù)據(jù)搬運(yùn)。典型場(chǎng)景是從網(wǎng)頁后臺(tái)導(dǎo)出數(shù)據(jù)填到本地Excel或者另一套業(yè)務(wù)系統(tǒng)里。這個(gè)過程往往涉及到字段對(duì)齊、格式轉(zhuǎn)換、去重判斷用RPA寫規(guī)則極度痛苦用CUA反而簡(jiǎn)單——把數(shù)據(jù)源界面和目標(biāo)界面截圖給模型告訴它“把A系統(tǒng)這一行的名稱、金額、日期填到B系統(tǒng)對(duì)應(yīng)字段里”它能邊看邊搬。第二類是重復(fù)且需要判斷的表單填報(bào)。比如每天根據(jù)一組郵件內(nèi)容在不同的選項(xiàng)里勾選對(duì)應(yīng)項(xiàng)并提交。判斷條件一變RPA腳本就要改CUA靠語義理解描述變了也能處理。第三類是界面上巡檢和數(shù)據(jù)看板摘要。每天早上打開幾個(gè)軟件截圖讓模型生成一份前一天的運(yùn)營(yíng)摘要。這種任務(wù)不要求極快的速度也不需要100%的確定性很適合Agent試水。5.2 現(xiàn)階段別指望這些場(chǎng)景有一些場(chǎng)景現(xiàn)階段把CUA硬塞進(jìn)去會(huì)非常痛苦毫秒級(jí)交互操作。股票交易、競(jìng)技游戲、實(shí)時(shí)音視頻控制這些對(duì)延遲極其敏感截圖-推理-執(zhí)行這個(gè)循環(huán)本身就跑不起來需要物理外設(shè)配合的場(chǎng)景。比如U盤插拔、掃碼槍掃描、打印紙張分類CUA只能操作虛擬界面摸不到物理世界高風(fēng)險(xiǎn)系統(tǒng)管理操作。比如刪庫、批量改權(quán)限、生產(chǎn)環(huán)境配置變更這些應(yīng)該走API加審批流而不是讓Agent看著屏幕點(diǎn)鼠標(biāo)涉及大量敏感數(shù)據(jù)的自動(dòng)化。如果把客戶個(gè)人信息、財(cái)務(wù)數(shù)據(jù)直接截圖喂給外部模型API合規(guī)上會(huì)有很大問題需要先想清楚方案5.3 成本和安全用錢和隱私換效率要有邊界CUA每一步操作都要帶一張截圖給模型一個(gè)30步的任務(wù)最壞情況下會(huì)產(chǎn)生30次視覺模型調(diào)用。我算過一筆賬如果每步都用旗艦視覺模型的API一個(gè)復(fù)雜任務(wù)的成本可能在幾元到幾十元不等具體看截圖大小和模型定價(jià)。批量跑還好一旦變成高頻生產(chǎn)任務(wù)成本壓力會(huì)很大。幾個(gè)降本優(yōu)化手段我實(shí)測(cè)有效優(yōu)化方式效果截圖壓縮到1280x720以內(nèi)轉(zhuǎn)JPEG質(zhì)量70token費(fèi)用大約能降到原來的50%以內(nèi)優(yōu)先讀可訪問性樹減少不必要的截圖請(qǐng)求次數(shù)和整體延遲大幅下降簡(jiǎn)單界面用便宜小模型困難步驟才調(diào)旗艦?zāi)P涂偝杀窘狄话胄Ч幻黠@打折安全層面上最重要的是敏感數(shù)據(jù)的流向必須提前設(shè)計(jì)。如果業(yè)務(wù)文件包含客戶信息、薪資、內(nèi)部經(jīng)營(yíng)數(shù)據(jù)建議使用本地部署模型或者在私有網(wǎng)絡(luò)環(huán)境內(nèi)運(yùn)行別想都不想就直接調(diào)外部API。這條路一旦走錯(cuò)后面補(bǔ)合規(guī)成本會(huì)非常昂貴。6. 實(shí)踐中踩過的坑五條值得寫進(jìn)文檔的教訓(xùn)6.1 分辨率一變坐標(biāo)全是錯(cuò)的我在第二版原型里遇到了一個(gè)非常低級(jí)的錯(cuò)誤開發(fā)機(jī)上跑得好好的Agent換到一臺(tái)高分屏筆記本上就到處亂點(diǎn)點(diǎn)擊位置明顯偏了。原因是截圖做了縮放處理而點(diǎn)擊事件用的是截圖縮放后的坐標(biāo)沒有做映射換算另外系統(tǒng)DPI縮放比例不同同樣一個(gè)按鈕在不同電腦上的屏幕坐標(biāo)也不一樣。現(xiàn)在的經(jīng)驗(yàn)是要么在代碼里把截圖分辨率固定下來并讓執(zhí)行層基于同一坐標(biāo)系計(jì)算要么直接用pyautogui提供的size()換算實(shí)際屏幕尺寸。如果是在虛擬機(jī)里跑直接把分辨率鎖死能省掉一堆兼容麻煩。6.2 彈窗是所有Agent的殺手桌面軟件比起網(wǎng)頁更容易彈窗證書更新提示、廣告彈窗、未保存修改提醒、Windows Defender提示任何一個(gè)彈出來都會(huì)擋住原本要點(diǎn)擊的區(qū)域。更麻煩的是彈窗出現(xiàn)的位置和內(nèi)容都具有隨機(jī)性你沒法提前預(yù)知。我的解法是在系統(tǒng)提示詞里加一條硬規(guī)則“如果檢測(cè)到未預(yù)期的彈窗先處理彈窗再繼續(xù)原任務(wù)。”同時(shí)在驗(yàn)證層專門寫了一個(gè)分支對(duì)比上一步截圖和當(dāng)前截圖如果出現(xiàn)了新的大面積視覺變化且模型認(rèn)為當(dāng)前不是預(yù)期界面就先調(diào)用“關(guān)閉彈窗”動(dòng)作。實(shí)測(cè)下來加上這條規(guī)則后連續(xù)任務(wù)的成功率能提升兩成以上。6.3 Agent會(huì)陷入死循環(huán)有一次我測(cè)試一個(gè)數(shù)據(jù)錄入任務(wù)Agent因?yàn)檎也坏揭粋€(gè)隱藏菜單連續(xù)七次執(zhí)行同一個(gè)點(diǎn)擊動(dòng)作每次的thought都是“點(diǎn)擊菜單展開按鈕”但菜單根本沒彈出來。如果不加限制它能對(duì)著同一個(gè)坐標(biāo)點(diǎn)到天荒地老。后來我在所有循環(huán)外面加了一個(gè)計(jì)數(shù)器超過15步就停下來把當(dāng)前狀態(tài)發(fā)給用戶請(qǐng)求指導(dǎo)。這一步是保障系統(tǒng)可靠性的底線寧可停下來讓人類接管也不能讓錯(cuò)誤動(dòng)作無限重復(fù)。6.4 token消耗比想象中更快我第一次跑通完整流程后看API賬單嚇了一跳一個(gè)不到三十步的任務(wù)光截圖理解就消耗了驚人的token。問題就出在全尺寸PNG截圖一張圖幾MBbase64編碼之后完全失控。后來做了三個(gè)改動(dòng)截圖前用Pillow把分辨率壓縮到1280x720全部轉(zhuǎn)JPEG格式quality設(shè)為70部分簡(jiǎn)單操作不再傳截圖直接根據(jù)可訪問性樹的坐標(biāo)執(zhí)行同樣的任務(wù)成本直接降到原來的三分之一不到。6.5 敏感數(shù)據(jù)和外部模型之間要有一道墻這是我在項(xiàng)目上線前才發(fā)現(xiàn)的問題一個(gè)內(nèi)部系統(tǒng)的數(shù)據(jù)搬運(yùn)任務(wù)每天經(jīng)過Agent處理的文件里包含客戶合同信息而我的原型默認(rèn)把全屏截圖發(fā)給了外部API。這意味著合同里的金額、客戶名、聯(lián)系方式都可能被發(fā)送到第三方服務(wù)。發(fā)現(xiàn)問題后我們臨時(shí)把方案改成了兩步走先用本地小模型做敏感信息檢測(cè)截圖里如果出現(xiàn)疑似身份證號(hào)、手機(jī)號(hào)、金額等字段就裁剪掉對(duì)應(yīng)區(qū)域或者打上馬賽克再傳給外部大模型。這當(dāng)然增加了工程復(fù)雜度但這是必要成本。在合規(guī)這件事上越早考慮后面越省心。我實(shí)際用這套原型跑了兩個(gè)多月的報(bào)表整理和界面巡檢最大的感受是CUA并不是讓人變懶而是把人和軟件之間的“翻譯成本”降下來了。以前我寫一個(gè)RPA腳本要反復(fù)調(diào)試選擇器現(xiàn)在只需要對(duì)著屏幕說清楚目標(biāo)Agent自己理解界面、完成操作遇到不懂的還能停下來問我。最后分享一個(gè)小技巧每一輪把上一步操作后的截圖和一句簡(jiǎn)短的環(huán)境描述一起傳給模型比如“當(dāng)前在計(jì)算器界面右上角有關(guān)閉按鈕”成功率會(huì)比只丟一張裸截圖高不少因?yàn)槟P偷淖⒁饬?huì)被引導(dǎo)到關(guān)鍵區(qū)域。CUA現(xiàn)在還遠(yuǎn)不完美但方向已經(jīng)明明白白AI不光會(huì)說話開始會(huì)“干活”了。