一個「自癒」外掛,怎麼把我的 AI agent 改到開不了機
服務一切正常,磁碟上的核心檔卻已經壞了。一次 AI agent 平台的事故排查:從十幾個外掛同時報錯,到抓出那個號稱會自動修復的元兇。
TL;DR
一個標榜「失敗時自動降級、自動修補」的社群外掛,在背景把 agent 平台的核心 JS 覆寫成語法錯誤的版本。服務當下照常運作——因為舊程式碼早已載入記憶體——但下一次重啟就起不來。教訓:「服務正常」與「磁碟上的東西正常」是兩件事,基線檢查要兩個都驗。
背景:把 agent 當成一個服務在養
我用一套開源的 AI coding agent 平台當日常工作台:它有 Web 介面、能裝外掛、能排程、能讀寫檔案。用久了,外掛越裝越多——反向代理、手機版介面、記憶、用量統計、檔案上傳……高峰期 profile 裡有 24 個 bundle。
外掛多了以後,穩定性自然變差。所以當我看到社群有一個 fail-soft 外掛,宣稱能在某個外掛載入失敗時自動隔離它、還能「自癒核心補丁」,聽起來正是我需要的保險。
裝了。然後某天重啟,整個服務起不來。
症狀:十幾個不相干的外掛,同一秒一起壞
日誌裡最醒目的是這一段:fail-soft 在同一秒內連續隔離了一大串外掛,錯誤訊息全部一樣:
failed to apply loader entry include (cordis:include): loader entries failed to apply
受影響的包括反向代理、session 管理、圖片顯示、檔案上傳、手機導覽、自動化排程……彼此毫無關係。
第一直覺是「是不是哪次升級把這些外掛弄壞了」,然後開始一個一個查。這是錯的方向。
十幾個互不相關的元件,在同一秒出現同一個錯誤——問題幾乎不可能在這十幾個元件裡,而是在它們共用的那一層。
這一層就是外掛載入器(loader),以及它所在的平台核心檔。
關鍵發現:服務明明在跑,核心檔卻是壞的
修好啟動後,我做了一件之前沒做過的事:直接對平台核心 JS 檔跑語法檢查。
node --check profile-boot-*.js
# SyntaxError: missing ) after argument list
核心檔有語法錯誤。但服務剛剛還好好的在跑——怎麼可能?
答案是時間差:
- 服務啟動,正確的核心程式碼被載入記憶體。
- fail-soft 的背景「自癒」程序觸發,用它自帶的模板覆寫磁碟上的核心檔。
- 服務繼續正常運作——它跑的是記憶體裡的舊版本。HTTP 檢查全部綠燈。
- Node 讀到磁碟上壞掉的檔案,loader 炸掉,所有外掛被一起「隔離」。
證據鏈很直接:
- fail-soft 的日誌記錄了它在某個時間點「自動修復並寫入」核心檔。
- 磁碟上的核心檔,與 fail-soft 自帶的
.patched模板雜湊完全相同。 - 兩者都有同一個語法錯誤:某個 callback 結尾少了正確的
});。 - 移除 fail-soft、從官方同版本套件還原核心檔後,語法檢查通過,重啟正常。
也就是說,它自帶的修補模板本身就是壞的。它每次「自癒」,都是在把一個好檔案換成壞檔案。
為什麼這種故障特別陰險
200當時 HTTP 健康檢查的結果
✗磁碟上核心檔的語法檢查
10+同一秒被「隔離」的無辜外掛
- 監控看不到。一般的健康檢查只問「服務有沒有回應」,而它確實有回應。
- 爆發點遠離原因。壞掉的動作發生在重啟之前的某個背景時間點;你在重啟時看到的錯誤,指向的是十幾個不相干的外掛。
- 保護機制放大了傷害。fail-soft 看到外掛載入失敗,就把它們隔離——於是「核心檔壞了」這個單一原因,被包裝成「十幾個外掛壞了」的假象。
- 它會再犯。只要外掛還在,你修好核心檔,它下一輪背景任務又會改回去。
修復與之後的做法
修復本身很簡單:從 profile 移除外掛、清掉 lockfile 裡的參照、把它的持久化開關設成關閉、從官方套件還原核心檔。真正花時間的是確認「不會再發生」。
我把這次的教訓收進一個唯讀的基線檢查腳本,每天早上由排程自動跑:
- 各服務的 HTTP 回應(服務層:有沒有活著)。
- profile 的 bundle 數量、有沒有被標成
disabled(設定層:有沒有被偷改)。 - 那個外掛是否仍未安裝、開關是否仍為關閉(已知風險:有沒有回來)。
- 平台核心 JS 的
node --check(磁碟層:下次重啟起不起得來)。 - 磁碟與記憶體餘量。
最後一項是這次新增的,也是最重要的:它檢查的不是「現在好不好」,而是「下次重啟會不會好」。
帶走的三件事
- 同時壞很多個,就去找它們共用的那一層。 不要逐個修。
- 健康檢查要分層:服務活著 ≠ 設定正確 ≠ 磁碟上的程式碼能啟動。只檢查第一層,等於只在重啟那一刻才發現問題。
- 對「會自動修改核心檔」的東西保持懷疑。 自動修復本身也是程式碼,也會有 bug,而且它的 bug 會以「修復」的名義寫進你的系統。裝之前先問:它改了什麼、改之前有沒有備份、改完有沒有驗證。
我的規則現在是:任何外掛或腳本要改動平台核心檔,一律拒絕;外掛安裝一律加 --ignore-scripts、固定版本;改 profile 之前先備份、改完先跑基線。
不浪漫,但至少下一次出事時,我會先知道「重啟起不起得來」。
寫於 2026.10.09。內容是個人實作紀錄,數字與做法請以你的環境驗證。想追後續,可以用 RSS 訂閱。