Agent 自動化跑著跑著就停,問題往往不在模型或腳本,而在瀏覽器環境這一層。本文依四類高頻失敗,分別說明可觀測現象與對應的工程做法。
用 LangChain、AutoGen 或 CrewAI 建一個 Agent,讓它呼叫 Playwright、Puppeteer 操作網頁,搭起來不難。難的是讓它持續穩定地跑下去。
剛上線時通常看不出問題。任務量一增加,異常就會密集出現:任務被網站攔下、帳號登入狀態突然失效、幾個 Agents 同時執行時互相干擾。多數人的第一反應是回頭檢查程式碼,最後卻發現程式碼本身沒有問題。
問題往往落在瀏覽器環境這一層。對大量執行的專案來說,失敗型態其實集中在幾種類型;辨認出來之後,處理並不算複雜。

環境還沒就緒就開始跑
新建立的瀏覽器環境,如果第一次就直接拿來執行任務,常見結果是無法登入、頁面元素載入不完整,或第一步就跳出驗證。原因不複雜:這個環境沒有歷史造訪紀錄、沒有 Cookie,也沒有任何瀏覽軌跡。平台看到的是一台完全陌生的裝置,信任度自然偏低。
可觀測的現象是:失敗集中在環境剛建立後的前幾次任務;把同一個任務移到一個已經使用一段時間的環境,就能正常跑完。
對應做法是把環境就緒設成明確狀態,而不是預設它一定可用。環境建立後先讓它進行一段低強度瀏覽,等狀態穩定再交給正式任務;排程器在派發任務前先確認這一步,而不是拿到環境就直接使用。
幾個任務搶同一個環境
併發一上來,最直觀的表現就是程序越堆越多、記憶體被吃滿、系統變慢。更麻煩的是隱蔽問題:兩個任務先後用了同一套 Cookie 和本機儲存,A 的登入狀態把 B 頂掉,從日誌看起來只像某個不固定的任務偶爾失敗,很難定位。
這時要把瀏覽器環境當成可申請、可回收的資源:任務開始時申請一個環境,結束後釋放,任務和環境維持一對一。不同環境的儲存彼此不可見,因此一個任務的登入狀態不會滲到另一個任務裡。擴展到幾十個 Agents 平行執行時,這種方式和「在腳本裡自己啟一堆瀏覽器程序」的差異會非常明顯。
如果場景本身涉及多帳號,隔離還要更徹底:一個帳號固定一套環境,指紋參數和儲存都不與其他帳號重疊。PurpleMark 在這裡提供的就是環境隔離與集中排程這一層能力,讓帳號與環境維持穩定的一對一對應。
工作階段過期卻沒人發現
這一類最容易被忽略,因為它不一定報錯。任務還在往下跑,日誌也持續輸出,但實際回傳的可能是登入頁面或空資料,直到結果進入資料管線才被發現,排查必須從下游往回推,成本很高。
做法是把登入狀態當成前置條件明確檢查:任務開始前先確認目前工作階段仍然有效,失效就走一次完整登入流程,而不是讓任務帶著無效狀態繼續執行。狀態本身應該放在環境層,Cookie、本機儲存、瀏覽歷史都存在環境裡,環境再次啟動時能完整恢復,帳號任務就不必每次重新初始化。
順帶一個經驗:長期執行的帳號,如果登入狀態頻繁變動,本身就容易被平台視為異常訊號並觸發額外驗證。能不做無謂的重新登入,就盡量不要做。
被攔下之後整批停擺
還有一種失敗會突然成批出現,一大批任務同時交不出結果。網站不一定給出明確拒絕,更常見的是回傳降級內容或空白頁,Agent 拿到沒有意義的資料後仍繼續往下跑,最後才在資料環節暴露問題。
遇到這種情況,第一件事是把攔截和一般失敗區分開。如果同一批環境在相近時間點集體異常,基本可以判斷問題出在環境這一層。這時繼續重試只會擴大範圍,應該先把這批環境停下來並隔離,再回頭查觸發原因。
常見觸發點有三個方向:多個環境使用高度重疊的指紋設定,例如 WebGL、Canvas、字型清單、核心版本幾乎一樣;出口 IP、時區、語言三者對不上,例如美國 IP 配亞洲時區;以及操作間隔過於規律,讓節奏本身變成特徵。把參數設定核對一致、控制好節奏,並把環境狀態與任務結果都留下日誌,才能在成批失敗之前先看到徵兆。
把這一層單獨拆出來
成熟專案通常會把瀏覽器環境從 Agent 裡拆出來,單獨當成一層:Agent 負責規劃與決策,環境層負責身分與狀態,執行層仍然使用原本的 Playwright 或 Puppeteer。拆開之後,身分是否合理、狀態是否能恢復、任務之間是否隔離,這三件事都有明確的管理位置。
回頭看,上面四類失敗有一個共同點:它們都不在模型裡,也不在腳本邏輯裡。模型和程式碼當然還要持續最佳化,但決定自動化能不能長期穩定執行的,往往是更下面這一層。
以上內容用於技術研究與開發實務分享,自動化手段應在合法合規的前提下使用,並遵守目標平台的服務條款與當地法律法規。


