Lab-confirmed:OpenClaw 的 IR pattern,我(Maki)在個人 agent / inbox automation 流程裡實際用過。evidence preservation 的 reference 設計則整理自自家 mk-brain / audit log 習慣。Code snippet 仍是 reference 版本,不等於 production 原碼。
你的 agent 開始做奇怪的事了,接下來 5 分鐘怎麼辦
這不是 SOC 團隊才會遇到的問題。現在很多 builder 手上的 agent,已經能刪檔、發訊息、改設定、打 API。
一旦它開始失控,你沒有時間先開 IDE 慢慢 debug。
2026-02-23,TechCrunch 報導 Summer Yue 的 OpenClaw 刪信事故。她不是被駭,而是看到 agent 忽略停止指令,最後只能跑回電腦手動終止。
2026-03-20,The Guardian 報導 Meta 內部 AI agent 建議導致敏感資料對員工暴露兩小時。工程師只是套用了 agent 給的 access control 解法,問題立刻從「建議品質不好」升級成資料事故。
這兩件事共同提醒一件事。你以為的 incident response,和 agent 真正需要的 incident response,不是同一份手冊。
傳統 IR 習慣先看帳號、流量、惡意登入、服務可用性。Agent IR 更常先看到的是行為失常、工具濫用、context 汙染、AI 建議被直接套用。
所以第一個問題不是「模型怎麼會這麼笨」。而是「接下來 5 分鐘,怎麼先把它停住」。
Agent IR:先止血,再問為什麼
Agent 事故的第一份 playbook,不該是 transcript 分析,而是給 operator 的時間盒手冊。
第一階段(0-5 分鐘)— 暫停執行
先 pause external action,不是先關 agent UI。真正該停的是 tool execution、worker queue、webhook、API token、排程器。
Kill switch 的順序也要現實一點:external endpoint > UI button > 電話 > 重開機。先讓血止住,不要邊看 log 邊讓 agent 繼續動。
第二階段(5-30 分鐘)— 證據保存
先收 evidence pack。最少要有當前 prompt、model version、context window snapshot、最近 N 個 action log。
環境先凍結。不要急著重啟,也不要急著清 context,因為很多關鍵 state 只會在事故當下存在一次。
螢幕截圖和 quick screen recording 也值得做,因為 UI 狀態常常比 log 更早消失。
第三階段(30-60 分鐘)— Blast radius 評估
把 agent 動過的 resource 全列出來。檔案、DB、API call、寄出的訊息、權限變更,都算。
接著把它們分成可逆和不可逆。可逆的是 rollback 工作量,不可逆的是 disclosure 壓力。
這一段就該通知 stakeholder 了。業務、客戶、法務,比起事件本身,更怕你沉默太久。
第四階段(1-4 小時)— Rollback or Degraded mode
如果操作可逆,就立刻 rollback。git revert、soft-delete recovery、transaction rollback,都是這一類。
如果操作不可逆,就別假裝能完整復原,直接準備 disclosure 和 remediation plan。
而且 agent 不該立刻重啟。先切成 degraded mode,每個 action 改成人工審核,先恢復最低限度可控能力,再談自動化。
第五階段(事後 24 小時內)— Postmortem + 規則化
Postmortem 不要寫成「AI 很笨」,要寫成「為什麼我們把這個決定交給它」。
5 Whys 追到最後,常常不是模型問題,而是你把 stop control 放錯層、把高風險 action 做成不可逆、或把 advisory 直接當 execution。
真正有價值的收尾,是把這次教訓規則化,寫進 rules、agent harness、tool policy。
每次 agent 犯錯,就把它工程化成未來更難再犯的限制。這就是比事故報告更有用的 HumanLayer pattern。
事故前就該準備好的最小配備,大概是這四樣。
| 不該等到事故才有的東西 | 落地點 | Builder 行動 |
|---|---|---|
| External kill switch endpoint | infra layer | 監聽一個 emergency token signal file 或 HTTP endpoint |
| Reversible action wrapper | tool layer | destructive tool 強制走 N-minute soft-delete |
| Action audit log(5 欄位 minimum) | observability | principal / agent_id / tool / args_hash / outcome 必記 |
| Evidence preservation script | tooling | 一個指令收齊 prompt / context / logs / screenshots |
Reference 實作(示意非 production code,依你環境調整):
from collections import defaultdict
from datetime import datetime, timedelta
from pathlib import Path
import json
def agent_emergency_freeze(agent_id: str, audit_store, signal_dir="signals", evidence_dir="evidence"):
Path(signal_dir).mkdir(parents=True, exist_ok=True)
Path(f"{signal_dir}/{agent_id}.freeze").write_text("freeze=1\n")
since = datetime.utcnow() - timedelta(hours=1)
actions = audit_store.list_actions(agent_id=agent_id, since=since)
clusters = defaultdict(list)
for action in actions:
resource = action.get("resource", "unknown")
clusters[resource.split(":", 1)[0]].append(action["tool"])
pack = {
"agent_id": agent_id,
"captured_at": datetime.utcnow().isoformat(),
"recent_actions": actions,
"resource_clusters": {k: sorted(set(v)) for k, v in clusters.items()},
}
Path(evidence_dir).mkdir(parents=True, exist_ok=True)
out = Path(evidence_dir) / f"{agent_id}-{datetime.utcnow():%Y%m%d%H%M%S}.json"
out.write_text(json.dumps(pack, ensure_ascii=False, indent=2))
for step in [
"0-5 分鐘:pause external action",
"5-30 分鐘:freeze context and capture logs",
"30-60 分鐘:map blast radius and notify stakeholders",
"1-4 小時:rollback or degraded mode",
"24 小時內:postmortem and rule it in",
]:
print(step)
這段 code 的重點,不是 signal file 很帥,而是 freeze、evidence、blast radius,在同一個 operator 動作裡一次完成。
你真正需要的是能止血的順序感,不是出事後才臨時發明流程。
對應 OWASP:這篇先看哪幾條
LLM06:2025 Excessive Agency:當 agent 能直接執行外部動作,任何失控都會從回答錯誤放大成真實事故。ASI03 Identity and Privilege Abuse:很多 agent 事故不是模型亂講,而是它拿著你的身份去改你的東西。ASI06 Memory & Context Poisoning:如果 context 已經被污染,事故應變就不能只看當前輸出,還要保住整段狀態證據。
想先補事故前防線? 這篇文可以接著看: Context Compaction 砍掉了你的 Safety 如果你想把 kill switch、降權、degraded mode 做成完整設計,直接接: 權限邊界 101 → 攻擊面邊界 101 →