AI Agent 上線一段時間之後,會遇到這種狀況:自動排程在跑,記憶系統在更新,Sub-agent 每天默默處理數十個任務,看起來一切穩定。

直到某天打開後台,發現一個 Sub-agent 已經卡了三小時。使用者在 Telegram 問了一個問題,Agent 回了句「稍等查一下」,然後消失。沒有任何警報,沒有任何通知,純粹是剛好被人發現。

Agent 掛了最麻煩的地方在於:當機卻沒人知道,比當機本身更難處理。

更糟的場景是:架了一個 LLM 監控來看 Agent 有沒有卡住,結果這個監控自己開始幻覺出不存在的工具呼叫,貢獻了當天大半的 error log,反而把真正的問題埋得更深。

下面整理的這套三層自癒架構,是踩過上述坑之後沉澱出來的版本。


一、傳統監控為什麼抓不到 Agent 的問題?

傳統監控問的是:「進程活著嗎?」

AI Agent 需要問的是:「Agent 有在做它說要做的事嗎?」

這是根本性的不同。AI Agent 有四種傳統監控看不到的故障模式:

  • 靜默卡死:進程在跑,HTTP 正常回應,但 Agent 已經 20 分鐘沒有輸出
  • 承諾未兌現:Agent 說「再五分鐘」,然後再也沒回來
  • 監控反噬:健康檢查 LLM 開始幻覺出不存在的指令,自己變成問題源
  • 孤兒任務:Session 中途死了,沒有人知道任務中斷

這些情況需要的是一套理解 Agent 語義行為的分層監控系統,而不是更精細的 process monitor。


二、三層防護:5 分鐘 → 15 分鐘 → 60 分鐘

採取三層架構,頻率呈 3 倍遞增。越底層越便宜,跑越頻繁:

頻率技術成本偵測什麼
L1每 5 分鐘Shell + Node.js0進程存活、HTTP、心跳存活、承諾偵測
L2每 15 分鐘Cheap LLM極低Session 死活、Sub-agent 卡死、abort 偵測
L3每 60 分鐘Shell → LLM(按需)極低Checkpoint 孤兒、Context 溢出、Log 分析

三層自癒架構示意圖

不採取單一方案的理由:

做法結果
純 LLM(Gemini Flash)error rate 極高,幻覺工具呼叫淹沒真正問題
純 LLM(Haiku API)成本太高,功能正常但長期不可持續
純 Shell抓不到語義卡死和承諾未兌現
Shell + Cheap LLM + 按需升級成本極低,各層只做自己擅長的事

L1 還負責監控 L2。 如果 LLM Heartbeat 超過 20 分鐘沒出現 HEARTBEAT_OK,L1 的 Shell 腳本會發出警報。監控系統需要有人監控監控系統,那個「人」必須是零成本的,否則 L2 自己掛掉的時候沒人接得住。


三、Prohibition-First:讓監控的 LLM 不要幫倒忙

最痛的一課:給 LLM 一個監控任務和一堆工具,它會幻覺出不存在的工具呼叫。

第一版 Heartbeat 用 gemini-flash 跑,曾經產生過這類 error:

canvas failed: node required              ×N
message failed: chat not found            ×N(拿 Discord ID 當 Telegram chat_id)
exec failed: command not found: rss-tool  ×N
edit failed: Missing required parameter   ×N

更嚴重的是:有一個 Sub-agent 讀到維護腳本的輸出,上面寫「Restart gateway to apply changes」,於是它真的去執行了 gateway restart,導致整個系統非預期重啟。

解法是 Prohibition-First Prompt Design(禁制前置設計):

## 你只能用這些工具(白名單制)

✅ sessions_list:查看 session
✅ sessions_send:發通知
✅ subagents kill:終止卡住的 agent
✅ message:僅限通知頻道

❌ 其他所有工具都禁止:exec/read/edit/web_search/gateway 等。

---

## 一切正常時,只回覆:
HEARTBEAT_OK

關鍵設計:白名單放在任務描述之前。 LLM 是順序處理 prompt 的。先讀到任務再讀到限制,它會在限制到達之前就開始規劃動作;反過來先讀到限制,規劃空間從一開始就被框住。

這個改動讓 Heartbeat 的 error 降到接近零。


四、承諾偵測:Agent 拋出承諾然後消失

這是整套系統最特別的部分。

傳統監控不會去讀 Agent 的對話內容。但實務上 Agent 最常見的「假活著」模式,就是:承諾了某件事,然後靜默。

承諾偵測流程示意圖

promise-watchdog(Node.js,零外部依賴)會讀取 Agent 的對話紀錄,用 regex 偵測承諾語句:

const promisePattern = /(
  give me \d+ minutes?|be right back|let me check|
  稍等|等等|給幾分鐘|現在就去|稍後回覆
)/i;

偵測邏輯:

  1. 待回覆偵測:最後一條訊息是使用者發的,Agent 超過 6 分鐘沒回 → 警報
  2. 承諾未兌現:Agent 最後一條訊息符合承諾 pattern,超過 7 分鐘沒有新進度 → 警報

通知會附上診斷脈絡:「這段期間 Gateway 重啟了 1 次」「目前看不到活躍 Sub-agent」。可以在幾秒內判斷是 Agent 當機、在忙、還是單純忘了。

重複通知用 SHA1 簽章去重,同一個 stall 在 20 分鐘內不會重複告警。


五、Checkpoint:任務中斷了不用從頭來

Session 會死,這是事實。API timeout、context overflow、進程重啟,原因百百種。重點在於:死了之後怎麼辦?

雙軌恢復策略:

有 Checkpoint 的情況:

Orchestrator 在 spawn Sub-agent 前寫一份 checkpoint 檔案,記錄任務名稱、目前步驟、已完成的步驟。Session 死了之後,L3(每小時)會掃描到這個孤兒 checkpoint,如果符合條件(時間夠新、重試次數未超標、不需要人類輸入),就自動 spawn 新的 session 繼續。

沒有 Checkpoint 的情況:

退一步,直接去讀對話歷史。找到使用者最後一條訊息(原始需求),帶著 thread 裡已有的部分結果,重新 spawn。這是 fallback,確保即使什麼都沒準備,系統也有辦法自救。

重啟計數是無狀態的。 不靠外部檔案記錄「重啟了幾次」,而是數 thread 裡的 🏥 恢復標記數量。對話本身就是狀態庫。最多 2 次自動重啟,超過就通知人類。


總結:自癒系統的設計原則

  1. 成本即架構:層級劃分屬於預算策略,能用 Shell 做的不要用 LLM
  2. 禁制前置:LLM 監控的 prompt,第一段寫它不能做什麼,再寫它應該做什麼
  3. 沒事不說話:零噪音原則。絕大多數的執行結果應該是 HEARTBEAT_OK
  4. 越便宜跑越頻繁:5m → 15m → 60m 的 3 倍遞增,讓零成本的層最先發現問題
  5. 監控監控系統:L1 監控 L2 的存活。監控本身也會掛,承接它的層必須是零成本

最貴的那台 LLM 只在真正需要判斷力的時候才醒來。其他時間,Shell 腳本和 regex 就夠了。

延伸閱讀


小企鵝的經驗

主力多 agent 架構是 OpenClaw 上的 ChatGPTClaude 多 agent 分工,這套自癒思路是踩過幾次 sub-agent 卡死、heartbeat 監控自己幻覺工具呼叫之後沉澱下來的。最有感的是「監控監控系統」這條:第一次的 LLM heartbeat 自己開始亂叫工具,真的會把整天的 error log 給污染掉,最後還是要回到 shell + regex 才壓得住。

常見問題

Q: AI Agent 為什麼需要自我修復機制?

AI Agent 的故障方式和傳統程式不同。它可以「活著但卡住」。進程在跑、HTTP 能回應,但 Agent 說了『等我五分鐘』之後就再也沒回來。傳統監控只檢查進程是否存活,抓不到這種語義層面的卡死。

Q: 三層自癒架構的成本大約多少?

整體可以壓到極低。最底層(Shell 腳本)完全免費;中間層用 Gemini Flash 等便宜模型;最上層每小時才跑一次,且多數時候 Shell 就處理完了,不需要呼叫 LLM。

Q: 沒有用 Claude Code 也可以用嗎?

可以。架構是通用的,只要 Agent 系統能輸出對話紀錄(transcript)並提供查詢 session 狀態的方式,就能套用。


整理:Penna|小企鵝 Penchan