標籤: 安全沙箱設計

  • 用 Gemini 3.5 控螢幕:Agent 實戰架構解析

    用 Gemini 3.5 控螢幕:Agent 實戰架構解析

    📌 本文重點

    • Gemini 3.5 直接「看螢幕 + 點 UI」,大幅簡化自動化 Agent
    • 用 DSL 約束操作與多輪回饋,提升穩定性與錯誤恢復能力
    • 安全邊界與權限治理是避免變成「超級巨鼠標」的關鍵

    Gemini 3.5 的 Computer Use 功能直接解決了一個老問題:過去我們寫辦公自動化或 E2E 測試 Agent,必須在「語言模型」和「操作工具」之間做大量 glue code(PlaywrightSelenium、各種 RPA SDK)。現在模型本身就能看螢幕 + 理解 UI + 產生操作事件,實作「會自己點 UI」的 Agent 架構可以大幅簡化,同時在 OSWorld 這類 benchmarks 上已經能接近人類級別的操作能力。

    💡 關鍵: Gemini 3.5 直接讀螢幕與 DOM,讓原本需要大量 glue code 的自動化流程被模型本身吸收,工程複雜度大幅下降。


    重點說明:Gemini 控螢幕的技術斷面

    1. 螢幕感知:Screenshot + DOM 雙通道

    Gemini 3.5 FlashComputer Use 能力裡,核心是讓模型同時看到:

    • 螢幕截圖:提供視覺語意,例如按鈕風格、顏色、位置、Tooltip 等。
    • DOM 或可操作節點樹:提供結構語意,如 aria-labelroleid、階層關係。

    實作上通常會有一個中介層:

    • 你的 Agent Runtime 負責抓取 當前視窗 screenshot、序列化 DOM / widget tree 成結構化 JSON
    • 透過 Gemini API 以多模態輸入丟給模型,模型回傳抽象操作意圖(例如「點選『匯出報表』按鈕」),再轉成具體事件(例如 click(x, y)click(selector))。

    這比傳統 RPA 的「座標點擊」穩健得多,因為模型能根據文字與結構定位元素,不再怕視窗尺寸微調就全掛。

    2. 操作語義到事件映射:從自然語言到 GUI 事件模型

    Gemini 本身不直接產生 OS-level 事件,而是給出操作語義,由你的 Agent 層做事件映射。典型設計是:

    • 模型輸出一組高階指令
    • click element: 「匯出報表」scroll until: 「三月」type in field: 「搜尋」 -> "季報"

    • Agent 將其轉換成具體事件:

    • 瀏覽器端:document.querySelector(...) + element.click()
    • 桌面端:座標點擊(OS API / robot library)

    建議在系統層設計一個 操作 DSL,例如:

    {
      "actions": [
        { "type": "click", "target": { "text": "匯出報表", "role": "button" } },
        { "type": "fill", "target": { "placeholder": "搜尋" }, "value": "季報" },
        { "type": "wait", "condition": { "text": "匯出完成" }, "timeoutMs": 10000 }
      ]
    }
    

    讓 Gemini 的輸出約束在這個 DSL 內,再由你寫 resolverDSL 轉成實際 API 呼叫,如 PlaywrightChromium DevTools 或自製桌面自動化套件。

    3. 權限與安全沙箱:避免做成「超級巨鼠標」

    能「看螢幕 + 點 UI」的 Agent,在安全上本質上是半個遠端操控工具。要避免直接變成超級巨鼠標,需要在設計時就加上:

    • Scope 限制:只允許控制特定應用(例如公司內部 CRM),而不是整個 OS
    • 權限分級:讀取螢幕 ≠ 可以操作所有按鈕,對「刪除」「匯出」「設定」類操作加上額外人為確認。
    • 審計與可回溯:所有操作都要有 log,包括模型輸入、輸出 DSL、最後映射的實際事件。

    Gemini 在雲端側有基本的安全保護,但真正壓力在你自家的 Agent Runtime。核心結論:螢幕控制能力是一把雙面刃,沒安全邊界就等同開放一個高權限自動點擊器。

    💡 關鍵: 把控制範圍鎖在特定應用與低權限環境,是避免「一個 Bug 變成全系統災難」的第一道防線。


    實作範例:會自己點 UI 的辦公自動化 / E2E Agent

    以下用 pseudo-code 示範一個基於 Gemini Computer Use 的 Agent 架構,對比你現在用 PlaywrightRPA 的做法。

    1. Agent 主循環:狀態管理與事件模型

    假設你有一個 Browser Automation Runtime,可以:

    • 抓取 screenshot
    • dump DOMJSON
    • 執行 DSL 動作

    初始化與一次任務呼叫

    # 假設有 gemini_client 已封裝好
    from agent_runtime import get_screenshot, get_dom_tree, execute_actions
    
    SYSTEM_PROMPT = """
    你是一個辦公自動化 Agent。你只能透過提供的 action DSL 操作螢幕。
    目標:根據使用者需求,在瀏覽器完成操作。
    請只輸出 JSON,不要輸出其他文字。
    """
    
    state = {
        "task": "下載最新的月報表並存到桌面",
        "history": []
    }
    
    def run_step(state):
        screenshot = get_screenshot()
        dom = get_dom_tree()  # 結構化 JSON
    
        prompt = {
            "system": SYSTEM_PROMPT,
            "user": {
                "task": state["task"],
                "history": state["history"],
                "screen": screenshot,   # 圖像
                "dom": dom              # 結構化文字
            }
        }
    
        # 透過 Gemini 3.5 Flash 多模態 API
        resp = gemini_client.generate(
            model="gemini-3.5-flash-computer-use",
            input=prompt,
            # 關鍵參數:讓模型遵守 DSL
            tools=[{"name": "ui_action_dsl", "schema": ACTION_SCHEMA}],
            temperature=0.2
        )
    
        actions = resp["actions"]
        result = execute_actions(actions)
    
        state["history"].append({"actions": actions, "result": result})
        return state
    
    # 任務循環(直到模型判斷完成)
    while not state.get("done"):
        state = run_step(state)
    

    關鍵設計點:

    • 使用 多步迭代:每次看最新螢幕 & DOM,再決定下一步 action,類似人類操作流程。
    • 將狀態(history)回饋給模型,讓它能做錯誤恢復與路徑修正。

    2. DSL Schema:限制模型輸出空間

    JSON Schema 方式提供 ui_action_dsl 給 Gemini(伺服器側 Stub 示意):

    export const ACTION_SCHEMA = {
      type: "object",
      properties: {
        actions: {
          type: "array",
          items: {
            type: "object",
            properties: {
              type: { enum: ["click", "fill", "scroll", "wait", "assert"] },
              target: {
                type: "object",
                properties: {
                  text: { type: "string" },
                  role: { type: "string" },
                  selector: { type: "string" },
                  ariaLabel: { type: "string" }
                }
              },
              value: { type: "string" },
              condition: { type: "object" },
              timeoutMs: { type: "number" }
            },
            required: ["type", "target"]
          }
        }
      },
      required: ["actions"]
    };
    

    把這個 schema 當作 tool 定義丟給 Gemini,模型就會傾向輸出符合 schemaJSON,而不是隨意產生指令文字。這比讓模型自己「猜 Playwright API」更穩。

    3. 錯誤恢復策略:從 E2E 測試角度看

    E2E 測試模式下,你可以:

    • 每個 step 後檢查 result 是否有錯誤(DOM element 找不到、timeout 等)。
    • 把錯誤詳細資訊(包含「按鈕找不到」等)回餵給模型,再跑下一個 step,讓 Agent 自己嘗試調整操作策略。

    示意:

    result = execute_actions(actions)
    if result.error:
        state["history"].append({"actions": actions, "error": result.error})
    else:
        state["history"].append({"actions": actions, "ok": True})
    

    這種「模型 + 真實環境回饋」的迭代,比傳統 Playwright 寫死 selector 更有韌性:UI 調整、小改版時,Agent 仍可能靠語意找到正確控件。

    💡 關鍵: 把錯誤結果當成下一輪輸入的一部分,能讓 Agent 自我修正,比單純重試同一段 script 聰明得多。


    建議與注意事項:和 RPA / Playwright 對比,以及安全邊界

    與傳統 RPA / Playwright 的優缺點對比

    優勢:

    • 選擇器韌性更高:不是全靠 #idxpath,模型會綜合文字、位置、上下文理解「這顆按鈕是做什麼的」。
    • 對自然語言任務友善:「幫我下載三月月報表」這種任務,不需要你事先拆成多條 script,Agent 自己規劃路徑。
    • 多模態容錯:螢幕上即使有動態廣告、複雜排版,模型也能分辨主要內容與干擾。

    劣勢 / 需要評估的點:

    • 成本與延遲:每一個 step 都要 call 一次 LLM,比傳統 script 直接執行慢且貴,適合複雜流程,不適合同一動作高頻批量執行。
    • 可預期性Playwright script 是 deterministic;Gemini Agent 則有一定隨機性(雖然可降低 temperature),需要監控與回滾機制。

    真實專案的安全與治理建議

    1. 明確劃定控制範圍

    2. 用獨立瀏覽器容器(例如專用 Chrome profileWebView),讓 Agent 只能看到業務系統,而非整個桌面。

    3. 對不同任務配置不同權限 profile,例如「只讀報表」「允許建立草稿但不可送出」。

    4. 強制人機協同節點

    5. 對敏感操作(刪除資料、匯出大量客戶名單)設計「人工確認」步驟,讓 Agent 停在「準備送出」頁面,由人點最後一個按鈕。

    6. 使用 UI 上的明確標記(例如「需管理員確認」)讓模型也知道哪些步驟不應自動完成。

    7. 完整審計 log + 可回放

    8. 記錄:模型輸入(螢幕縮圖、DOM 摘要)、模型輸出 DSL、實際執行的事件與結果。

    9. 可選擇在安全事件發生時回放整個操作過程,做事後分析。

    10. 避免敏感資料洩露

    11. screenshot 做遮罩(mask),例如遮蓋客戶姓名、金額等,再送給模型。

    12. DOM 摘要可做字段裁剪,只提供必要欄位(如 label、角色、結構),不要直接把完整表格資料送到雲端。

    13. 從小範圍 PoC 起步

    14. 先在「測試環境 + 低權限帳號」上跑 Agent,驗證行為穩定,再逐步提升權限。

    15. 與現有 Playwright / RPA 共存:把 Gemini Agent 用在「探索性操作」與「易變 UI」,穩定的核心流程仍用傳統 script

    總結:Gemini 3.5 的螢幕感知與控制能力,讓我們可以用更少的硬編碼 selector 和流程腳本,實作能「看得懂 UI、自己點按鈕」的辦公自動化 / E2E Agent。真正的工程重點在於:設計好操作 DSL、狀態管理與錯誤恢復機制,並在安全邊界、審計與人機協同上做好防護,讓這個 Agent 是可控的助理,而不是失控的超級巨鼠標。

    🚀 你現在可以做的事

    • 在你現有的 Playwright / Selenium 專案中,先為 1 個流程試做一個 ui_action_dsl,讓 LLM 產生 JSON 再轉成實際指令
    • 建一個測試用瀏覽器容器(低權限帳號 + 測試環境),接上 Gemini 3.5 Flash 多模態 API 做小型 PoC
    • 為預計自動化的系統列出敏感操作,先設計好「人工確認」與操作 log / 回放機制