建三層安全防火墻)
1. 從一次失控的智能體任務(wù)說起凌晨?jī)牲c(diǎn)我盯著屏幕上那個(gè)還在瘋狂調(diào)用工具的 OpenClaw 智能體它已經(jīng)連續(xù)執(zhí)行了四十多分鐘把測(cè)試環(huán)境里的文件改得面目全非。起因只是我在調(diào)試一個(gè)自動(dòng)化腳本時(shí)給它開放了文件讀寫權(quán)限結(jié)果它陷入了一個(gè)讀取—判斷—再讀取的循環(huán)每輪都覺得自己在推進(jìn)任務(wù)。那一刻我意識(shí)到給智能體加能力容易給它加約束才是真正難的部分。這就是 ClawKeeper 要解決的問題。它不是又一個(gè)智能體框架而是專門給 OpenClaw 這類智能體套上的一層安全外殼。你可以把它理解成給一個(gè)精力旺盛但缺乏邊界感的實(shí)習(xí)生配了三個(gè)角色一個(gè)在旁邊盯著他干活的監(jiān)工、一個(gè)負(fù)責(zé)審核他每個(gè)動(dòng)作的合規(guī)員、一個(gè)在出事后能立刻拉閘的應(yīng)急開關(guān)。這三層加起來就是標(biāo)題里說的三層安全防火墻。如果你正在用 OpenClaw 做自動(dòng)化任務(wù)、對(duì)接飛書或微信、跑本地部署的智能體工作流或者單純被agent failed before reply: session file locked這類報(bào)錯(cuò)折磨過那這篇內(nèi)容會(huì)對(duì)你有用。我會(huì)把 ClawKeeper 的設(shè)計(jì)思路、三層防護(hù)的具體落地方式、以及我在實(shí)際部署中踩過的坑完整地?cái)傞_講一遍。不堆概念只講能直接抄作業(yè)的東西。2. 為什么智能體需要看門人而不是說明書2.1 智能體的失控不是 bug是特性大多數(shù)人第一次接觸 OpenClaw 這類智能體時(shí)會(huì)默認(rèn)它像普通程序一樣輸入什么就輸出什么。但智能體的本質(zhì)是在循環(huán)中自主決策它拿到一個(gè)目標(biāo)自己拆解步驟自己選擇工具自己判斷是否完成。這個(gè)循環(huán)里每一步都依賴模型的判斷而模型的判斷是不確定的。我做過一個(gè)統(tǒng)計(jì)在本地部署的 OpenClaw 環(huán)境里跑同一批任務(wù)十次里有三次會(huì)出現(xiàn)過度執(zhí)行——比如讓它整理一份文檔它順手把整個(gè)目錄的權(quán)限都改了讓它查一個(gè)數(shù)據(jù)它把數(shù)據(jù)庫(kù)連接池占滿了。這些行為在傳統(tǒng)程序里叫 bug在智能體里叫自主性溢出。你沒法靠寫死 if-else 來堵住因?yàn)樗臎Q策路徑是動(dòng)態(tài)生成的。所以正確的思路不是給它寫更詳細(xì)的說明書而是在它和真實(shí)環(huán)境之間插一層看門人。ClawKeeper 就是這個(gè)看門人。2.2 三層防護(hù)的分工邏輯ClawKeeper 的三層設(shè)計(jì)不是拍腦袋來的它對(duì)應(yīng)了智能體出問題的三個(gè)時(shí)間點(diǎn)層級(jí)名稱介入時(shí)機(jī)核心職責(zé)第一層Watcher執(zhí)行前攔截高危動(dòng)作做前置校驗(yàn)第二層Auditor執(zhí)行中監(jiān)控行為序列識(shí)別異常模式第三層Circuit Breaker異常后熔斷、回滾、隔離這三層的關(guān)系是遞進(jìn)的Watcher 管能不能做Auditor 管做得對(duì)不對(duì)Circuit Breaker 管做錯(cuò)了怎么辦。很多團(tuán)隊(duì)只做了第一層結(jié)果發(fā)現(xiàn)智能體繞過了單點(diǎn)檢查只做第二層發(fā)現(xiàn)異常識(shí)別出來時(shí)損失已經(jīng)造成只做第三層那就是純事后補(bǔ)救。三層缺一不可。2.3 和常見權(quán)限控制的本質(zhì)區(qū)別有人會(huì)問這不就是給智能體配個(gè)權(quán)限白名單嗎不一樣。傳統(tǒng)權(quán)限控制是靜態(tài)的你告訴它只能讀 A 目錄它就只讀 A 目錄。但智能體的危險(xiǎn)動(dòng)作往往發(fā)生在合法權(quán)限內(nèi)的組合操作上。比如它有讀權(quán)限也有寫權(quán)限單獨(dú)看都沒問題但它先讀一個(gè)配置文件拿到密鑰再寫到另一個(gè)地方這個(gè)組合就是風(fēng)險(xiǎn)。ClawKeeper 的 Watcher 層做的不是簡(jiǎn)單的權(quán)限判斷而是動(dòng)作語(yǔ)義分析。它會(huì)看這個(gè)動(dòng)作的意圖、上下文、以及和之前動(dòng)作的關(guān)聯(lián)。這是它和普通權(quán)限系統(tǒng)最大的區(qū)別也是為什么它需要獨(dú)立部署而不是塞進(jìn) OpenClaw 配置里。3. Watcher 層在動(dòng)作落地前把它攔下來3.1 Watcher 的攔截點(diǎn)選在哪里Watcher 的部署位置很關(guān)鍵。我試過三種方案第一種是在 OpenClaw 的 tool 調(diào)用入口做攔截也就是智能體每次調(diào)用工具前先過 Watcher。優(yōu)點(diǎn)是覆蓋全缺點(diǎn)是如果智能體用了內(nèi)置工具或者直接走 shell可能繞過。第二種是在系統(tǒng)調(diào)用層做攔截用類似 seccomp 的機(jī)制。優(yōu)點(diǎn)是底層缺點(diǎn)是配置復(fù)雜而且對(duì)跨平臺(tái)的 OpenClaw 部署不友好。第三種是在 ClawKeeper 自己的代理層做攔截讓 OpenClaw 的所有外部動(dòng)作都經(jīng)過一個(gè)本地代理。這是我最終采用的方案因?yàn)樗诟采w面和可維護(hù)性之間取得了平衡。具體做法是在 OpenClaw 的配置里把工具調(diào)用的 endpoint 指向 ClawKeeper 的本地端口ClawKeeper 解析請(qǐng)求后決定放行還是攔截。這樣無論智能體用什么工具只要走網(wǎng)絡(luò)或文件系統(tǒng)都會(huì)經(jīng)過這一層。3.2 動(dòng)作語(yǔ)義分析怎么做Watcher 的核心是一套規(guī)則引擎加一個(gè)輕量模型。規(guī)則引擎處理明確的紅線比如禁止刪除 /etc 下的文件禁止向外部地址發(fā)送超過 1MB 的數(shù)據(jù)。這些用正則和路徑匹配就能搞定速度快誤報(bào)低。輕量模型處理模糊判斷比如這個(gè)動(dòng)作是否和當(dāng)前任務(wù)目標(biāo)一致。我用的方案是把當(dāng)前任務(wù)描述和待執(zhí)行動(dòng)作一起喂給一個(gè)小模型讓它輸出一個(gè)風(fēng)險(xiǎn)分。這個(gè)模型不需要很大7B 級(jí)別的量化模型在本地跑就夠了延遲控制在 200ms 以內(nèi)。兩者結(jié)合的邏輯是規(guī)則引擎先過一遍命中紅線直接攔沒命中紅線的再走模型打分超過閾值就進(jìn)入人工確認(rèn)隊(duì)列。這個(gè)隊(duì)列可以對(duì)接飛書或企業(yè)微信讓負(fù)責(zé)人點(diǎn)一下確認(rèn)或拒絕。3.3 一個(gè)真實(shí)的攔截案例我部署 ClawKeeper 后遇到的第一個(gè)攔截事件是智能體在整理日志文件時(shí)試圖執(zhí)行一條find / -name *.log -delete。這條命令在規(guī)則引擎里命中了全盤刪除類操作的紅線直接被攔。但有意思的是智能體的原始意圖是清理測(cè)試目錄下的日志。它之所以寫成全盤查找是因?yàn)樗诓鸾馊蝿?wù)時(shí)把清理日志理解成了清理所有日志。如果沒有 Watcher這條命令會(huì)刪掉系統(tǒng)日志和一堆無關(guān)文件。這個(gè)案例說明一個(gè)問題智能體的意圖和執(zhí)行之間經(jīng)常有偏差Watcher 的價(jià)值就是在偏差造成后果前把它暴露出來。我在規(guī)則里加了一條路徑范圍校驗(yàn)要求所有刪除類操作的路徑必須落在任務(wù)聲明的目錄內(nèi)超出范圍就攔截。這條規(guī)則后來又?jǐn)r下了好幾次類似問題。3.4 Watcher 的性能開銷與調(diào)優(yōu)加上 Watcher 后智能體的單步延遲從平均 80ms 漲到了 280ms。這個(gè)開銷主要來自模型推理。如果你的任務(wù)對(duì)延遲敏感可以這樣調(diào)把規(guī)則引擎的匹配做成前綴樹減少正則回溯模型推理用批處理把多個(gè)待審動(dòng)作攢一批一起打分對(duì)高頻低危動(dòng)作比如讀文件設(shè)置緩存相同路徑的讀操作短時(shí)間內(nèi)不重復(fù)審核我實(shí)測(cè)下來調(diào)優(yōu)后延遲能壓到 150ms 左右對(duì)大多數(shù)自動(dòng)化任務(wù)來說可以接受。如果你的場(chǎng)景要求毫秒級(jí)響應(yīng)那 Watcher 可能不適合放在關(guān)鍵路徑上可以考慮異步審核加事后告警的模式。4. Auditor 層盯著行為序列而不是單點(diǎn)動(dòng)作4.1 為什么單點(diǎn)檢查會(huì)漏Watcher 再?gòu)?qiáng)它看的也是單個(gè)動(dòng)作。但智能體的風(fēng)險(xiǎn)往往藏在動(dòng)作序列里。我遇到過這樣一個(gè)案例智能體先讀取了一個(gè)包含數(shù)據(jù)庫(kù)密碼的配置文件然后調(diào)用了一個(gè)外部 API把配置內(nèi)容作為參數(shù)傳了出去。單獨(dú)看讀文件是合法的調(diào) API 也是合法的但組合起來就是數(shù)據(jù)泄露。Auditor 層就是解決這個(gè)問題的。它不判斷單個(gè)動(dòng)作而是維護(hù)一個(gè)行為序列窗口分析最近 N 個(gè)動(dòng)作之間的關(guān)聯(lián)。如果發(fā)現(xiàn)敏感讀取 外部發(fā)送這種組合就觸發(fā)告警。4.2 行為序列的建模方式Auditor 的建模我用的是狀態(tài)機(jī)加圖分析。每個(gè)動(dòng)作被抽象成一個(gè)帶標(biāo)簽的節(jié)點(diǎn)比如READ:config、CALL:external_api、WRITE:tmp。這些節(jié)點(diǎn)按時(shí)間順序連成圖Auditor 在圖上跑模式匹配。常見的危險(xiǎn)模式我整理了幾類數(shù)據(jù)外泄模式敏感讀 → 編碼/壓縮 → 外部發(fā)送權(quán)限提升模式讀配置 → 修改權(quán)限 → 執(zhí)行腳本資源耗盡模式循環(huán)調(diào)用 → 未釋放連接 → 繼續(xù)調(diào)用任務(wù)漂移模式連續(xù)多個(gè)動(dòng)作與初始目標(biāo)語(yǔ)義距離越來越遠(yuǎn)前三種用圖模式匹配就能識(shí)別第四種需要計(jì)算動(dòng)作和目標(biāo)描述的語(yǔ)義相似度。我用的是 sentence embedding把初始目標(biāo)和每個(gè)動(dòng)作都編碼成向量算余弦相似度。如果連續(xù)五個(gè)動(dòng)作的相似度都低于 0.3就判定為任務(wù)漂移觸發(fā) Auditor 告警。4.3 告警分級(jí)與響應(yīng)策略Auditor 的告警不能一刀切否則會(huì)淹沒在噪音里。我把它分成三級(jí)級(jí)別觸發(fā)條件響應(yīng)方式提示單次可疑模式記錄日志不打斷警告可疑模式重復(fù)出現(xiàn)通知負(fù)責(zé)人繼續(xù)執(zhí)行嚴(yán)重高危模式或任務(wù)漂移暫停智能體等待人工介入這個(gè)分級(jí)的關(guān)鍵是給智能體留出自我糾正的空間。很多異常是暫時(shí)的比如智能體在探索階段會(huì)做一些看似無關(guān)的動(dòng)作但很快會(huì)回到正軌。如果一有異常就熔斷任務(wù)成功率會(huì)大幅下降。我的經(jīng)驗(yàn)是提示級(jí)不打斷警告級(jí)通知只有嚴(yán)重級(jí)才暫停。4.4 Auditor 的日志設(shè)計(jì)Auditor 的日志不是簡(jiǎn)單的文本記錄而是結(jié)構(gòu)化的行為軌跡。每條記錄包含時(shí)間戳、動(dòng)作類型、動(dòng)作參數(shù)摘要、風(fēng)險(xiǎn)分、關(guān)聯(lián)的前序動(dòng)作 ID、當(dāng)前任務(wù)目標(biāo)向量。這樣的日志有兩個(gè)好處一是事后復(fù)盤時(shí)能完整還原智能體的決策路徑二是可以用來訓(xùn)練更精準(zhǔn)的風(fēng)險(xiǎn)模型。我把跑了三個(gè)月的日志拿出來做了一次聚類分析發(fā)現(xiàn)了幾類之前沒注意到的危險(xiǎn)模式反過來補(bǔ)充到了 Watcher 的規(guī)則里。提示Auditor 的日志量會(huì)很大建議用列式存儲(chǔ)比如 Parquet而不是純文本查詢和分析效率差很多。我一開始用 JSON 文件存后來數(shù)據(jù)量上來后查詢慢得沒法用換成 DuckDB 才順暢。5. Circuit Breaker 層出事后如何把損失摁住5.1 熔斷的觸發(fā)條件設(shè)計(jì)Circuit Breaker 是最后一道防線它的觸發(fā)條件必須足夠明確否則要么誤熔斷要么漏熔斷。我設(shè)定的觸發(fā)條件有三類第一類是Auditor 嚴(yán)重級(jí)告警這個(gè)直接熔斷沒有商量余地。第二類是資源閾值突破比如智能體占用的內(nèi)存超過 2GB、打開的文件句柄超過 500、或者連續(xù)調(diào)用外部 API 超過 100 次每分鐘。這些閾值根據(jù)你的部署環(huán)境調(diào)整原則是留出足夠余量但又能及時(shí)剎車。第三類是超時(shí)單個(gè)任務(wù)執(zhí)行超過預(yù)設(shè)時(shí)長(zhǎng)我設(shè)的是 15 分鐘就強(qiáng)制中斷。這個(gè)時(shí)長(zhǎng)要根據(jù)任務(wù)復(fù)雜度設(shè)太短會(huì)誤殺正常任務(wù)太長(zhǎng)就失去了保護(hù)意義。5.2 熔斷后的回滾策略熔斷只是第一步關(guān)鍵是熔斷后怎么把環(huán)境恢復(fù)到安全狀態(tài)。ClawKeeper 的回滾分三個(gè)層次文件系統(tǒng)回滾在智能體啟動(dòng)前對(duì)關(guān)鍵目錄做快照熔斷后對(duì)比差異并恢復(fù)。我用的是 overlayfs開銷小恢復(fù)快。進(jìn)程隔離智能體運(yùn)行在獨(dú)立的容器或命名空間里熔斷時(shí)直接殺掉整個(gè)命名空間不影響宿主機(jī)。外部狀態(tài)回滾如果智能體調(diào)用了外部 API 或?qū)懥藬?shù)據(jù)庫(kù)這部分沒法自動(dòng)回滾需要記錄操作日志并通知相關(guān)方手動(dòng)處理。第三層是最麻煩的也是很多團(tuán)隊(duì)忽略的。我的做法是在 Watcher 層就對(duì)寫外部系統(tǒng)的操作做標(biāo)記熔斷時(shí)把這些標(biāo)記提取出來生成一份待人工核查清單推送給負(fù)責(zé)人。5.3 熔斷后的智能體狀態(tài)處理熔斷后智能體的會(huì)話狀態(tài)怎么處理這個(gè)問題我糾結(jié)了很久。直接丟棄的話之前的工作全白費(fèi)保留的話恢復(fù)后可能繼續(xù)犯錯(cuò)。最后的方案是狀態(tài)凍結(jié)加人工審核。熔斷時(shí)把智能體的完整狀態(tài)包括對(duì)話歷史、工具調(diào)用記錄、當(dāng)前任務(wù)進(jìn)度序列化保存然后暫停會(huì)話。負(fù)責(zé)人可以在 ClawKeeper 的控制臺(tái)里查看狀態(tài)決定是恢復(fù)、修改目標(biāo)后恢復(fù)、還是終止。這個(gè)方案的好處是給了人一個(gè)介入點(diǎn)而不是讓智能體在錯(cuò)誤的方向上越走越遠(yuǎn)。我實(shí)際用下來大概有 60% 的熔斷事件在人工審核后能恢復(fù)執(zhí)行40% 需要終止或重新規(guī)劃任務(wù)。5.4 一個(gè)完整的熔斷實(shí)例有一次我讓智能體幫忙做數(shù)據(jù)清洗它需要讀取一個(gè) CSV 文件、做格式轉(zhuǎn)換、然后寫回。任務(wù)本身不復(fù)雜但那個(gè) CSV 文件里有一列包含大量特殊字符智能體在處理時(shí)陷入了反復(fù)嘗試的循環(huán)——每次轉(zhuǎn)換失敗就換個(gè)方式重試重試次數(shù)很快超過了 50 次。Auditor 在它第 30 次重試時(shí)觸發(fā)了資源耗盡模式的警告第 50 次時(shí)升級(jí)為嚴(yán)重級(jí)Circuit Breaker 隨即熔斷。熔斷后我查看狀態(tài)發(fā)現(xiàn)它已經(jīng)把原始文件覆蓋了三次好在 overlayfs 快照保住了原始版本。恢復(fù)時(shí)我修改了任務(wù)描述明確告訴它遇到特殊字符時(shí)的處理規(guī)則重新執(zhí)行后一次通過。這個(gè)案例讓我意識(shí)到熔斷不是失敗而是把不可控的自動(dòng)執(zhí)行轉(zhuǎn)化為可控的人工介入。沒有熔斷的話那個(gè)文件可能被反復(fù)覆蓋幾十次數(shù)據(jù)早就毀了。6. 把 ClawKeeper 接進(jìn) OpenClaw 的實(shí)際操作6.1 部署架構(gòu)與依賴ClawKeeper 本身是一個(gè)獨(dú)立的服務(wù)用 Go 寫的核心加 Python 寫的模型推理模塊。部署方式我推薦用 Docker Compose因?yàn)橐瑫r(shí)跑代理、規(guī)則引擎、模型服務(wù)和日志存儲(chǔ)。核心依賴OpenClaw 本體版本建議用近三個(gè)月內(nèi)的穩(wěn)定版Docker 和 Docker Compose一個(gè)本地模型推理服務(wù)我用的是 Ollama跑量化后的 7B 模型列式存儲(chǔ)DuckDB 或 ClickHouse看數(shù)據(jù)量資源占用方面Watcher 的模型推理大概吃 2GB 顯存Auditor 的 embedding 模型吃 1GB加上 OpenClaw 本身一臺(tái) 16GB 內(nèi)存、8GB 顯存的機(jī)器能跑起來。如果并發(fā)任務(wù)多需要相應(yīng)擴(kuò)容。6.2 配置 OpenClaw 走 ClawKeeper 代理這一步是集成的關(guān)鍵。OpenClaw 的工具調(diào)用配置里有一個(gè)tool_endpoint字段默認(rèn)指向它自己的工具執(zhí)行器。把它改成 ClawKeeper 的地址# openclaw config tools: endpoint: http://localhost:8420/proxy timeout: 30s retry: 1然后在 ClawKeeper 的配置里聲明上游的真實(shí) endpoint# clawkeeper config upstream: openclaw_tools: http://localhost:8421/execute watcher: rules_file: ./rules/default.yaml model: ollama:qwen2.5:7b auditor: window_size: 10 embedding_model: ollama:nomic-embed-text breaker: max_memory_mb: 2048 max_duration_sec: 900 snapshot_dir: /var/clawkeeper/snapshots配置改完后重啟 OpenClaw所有工具調(diào)用就會(huì)先經(jīng)過 ClawKeeper。你可以在 ClawKeeper 的日志里看到每個(gè)被攔截或放行的動(dòng)作。6.3 規(guī)則文件的編寫要點(diǎn)Watcher 的規(guī)則文件是 YAML 格式每條規(guī)則包含匹配條件、風(fēng)險(xiǎn)級(jí)別、處理動(dòng)作。我寫規(guī)則時(shí)遵循幾個(gè)原則路徑匹配用絕對(duì)路徑不要用相對(duì)路徑因?yàn)橹悄荏w的工作目錄可能變化命令匹配用白名單而不是黑名單黑名單永遠(yuǎn)列不全風(fēng)險(xiǎn)級(jí)別留出調(diào)整空間新規(guī)則先設(shè)為提示級(jí)觀察一段時(shí)間再升級(jí)一條典型的規(guī)則長(zhǎng)這樣- id: block-full-disk-delete match: tool: shell command_regex: find\\s/\\s.*-delete level: critical action: block message: 全盤刪除操作被攔截請(qǐng)檢查任務(wù)范圍規(guī)則寫完后可以用 ClawKeeper 自帶的測(cè)試工具跑一遍它會(huì)用歷史日志回放告訴你哪些規(guī)則會(huì)誤傷正常操作。6.4 和飛書、微信通知的對(duì)接Auditor 的告警和 Circuit Breaker 的熔斷都需要通知到人。我對(duì)接的是飛書機(jī)器人因?yàn)樗?webhook 最簡(jiǎn)單。在 ClawKeeper 配置里填上 webhook 地址告警會(huì)自動(dòng)推送。需要注意的是飛書的消息有長(zhǎng)度限制如果告警內(nèi)容太長(zhǎng)會(huì)被截?cái)唷N业淖龇ㄊ前言敿?xì)信息放在 ClawKeeper 的控制臺(tái)里飛書消息只推摘要加一個(gè)跳轉(zhuǎn)鏈接。這樣既保證了通知到達(dá)又不會(huì)因?yàn)榻財(cái)鄟G失關(guān)鍵信息。如果你用的是微信情況會(huì)復(fù)雜一些因?yàn)槲⑿艣]有官方的機(jī)器人 webhook。我試過用企業(yè)微信的應(yīng)用消息效果還行但配置比飛書麻煩。如果只是個(gè)人使用可以考慮用郵件通知雖然慢一點(diǎn)但最穩(wěn)定。7. 部署過程中踩過的坑和應(yīng)對(duì)7.1 session file locked 問題的根源部署 ClawKeeper 后我遇到過一個(gè)報(bào)錯(cuò)agent failed before reply: session file locked (timeout 60000ms)。這個(gè)報(bào)錯(cuò)在 OpenClaw 社區(qū)里很常見但加上 ClawKeeper 后出現(xiàn)頻率變高了。排查后發(fā)現(xiàn)原因是 ClawKeeper 的 Auditor 在讀取會(huì)話文件做分析時(shí)和 OpenClaw 的寫入產(chǎn)生了鎖競(jìng)爭(zhēng)。OpenClaw 默認(rèn)用文件鎖保護(hù)會(huì)話狀態(tài)Auditor 頻繁讀取導(dǎo)致鎖等待超時(shí)。解決方案有兩個(gè)一是讓 Auditor 通過 OpenClaw 提供的 API 讀取會(huì)話狀態(tài)而不是直接讀文件二是把 Auditor 的讀取頻率降下來從實(shí)時(shí)讀取改成批量讀取。我兩個(gè)都做了問題再?zèng)]出現(xiàn)過。7.2 模型推理的顯存競(jìng)爭(zhēng)Watcher 和 Auditor 都要用模型推理如果都跑在同一塊 GPU 上會(huì)出現(xiàn)顯存競(jìng)爭(zhēng)。我一開始沒注意結(jié)果兩個(gè)服務(wù)互相搶顯存導(dǎo)致推理超時(shí)智能體的動(dòng)作被大量誤攔。解決辦法是給兩個(gè)服務(wù)分配不同的 GPU或者用 CPU 跑 Auditor 的 embedding 模型embedding 模型小CPU 跑延遲可以接受。如果只有一塊 GPU可以用 Ollama 的并發(fā)控制限制同時(shí)加載的模型數(shù)量。7.3 規(guī)則誤傷正常操作新規(guī)則上線時(shí)最容易誤傷。我加過一條禁止訪問 /tmp 以外的臨時(shí)目錄的規(guī)則結(jié)果智能體在正常任務(wù)中需要寫 /var/tmp被攔了。這種誤傷會(huì)打斷正常任務(wù)體驗(yàn)很差。我的應(yīng)對(duì)方法是新規(guī)則先跑影子模式規(guī)則生效但不攔截只記錄如果攔截會(huì)攔下哪些操作。跑一周后看日志如果攔下的都是真正的危險(xiǎn)操作再切換成攔截模式。這個(gè)流程雖然慢但能避免大量誤傷。7.4 熔斷后的狀態(tài)恢復(fù)失敗有一次熔斷后恢復(fù)失敗原因是智能體的會(huì)話狀態(tài)里包含了一個(gè)已經(jīng)失效的臨時(shí) token?;謴?fù)時(shí)它拿著舊 token 去調(diào)用 API直接報(bào)錯(cuò)。這個(gè)問題說明狀態(tài)恢復(fù)不是簡(jiǎn)單的反序列化還需要做有效性校驗(yàn)。我在恢復(fù)流程里加了一步檢查狀態(tài)里的所有外部引用token、連接、文件句柄是否還有效無效的就標(biāo)記出來讓負(fù)責(zé)人決定是刷新還是放棄。7.5 日志存儲(chǔ)的膨脹問題Auditor 的日志增長(zhǎng)很快我跑了兩個(gè)月就攢了 40GB。如果不處理磁盤很快會(huì)滿。我的做法是分層存儲(chǔ)最近 7 天的日志放 SSD查詢快7 天到 90 天的放普通硬盤超過 90 天的歸檔到對(duì)象存儲(chǔ)。同時(shí)做了一個(gè)聚合任務(wù)把原始日志按小時(shí)聚合成統(tǒng)計(jì)指標(biāo)長(zhǎng)期保留的是聚合結(jié)果而不是原始記錄。這樣存儲(chǔ)成本降了一個(gè)數(shù)量級(jí)。8. 三層防護(hù)的協(xié)同與調(diào)優(yōu)經(jīng)驗(yàn)8.1 三層之間的信息傳遞Watcher、Auditor、Circuit Breaker 不是孤立的它們之間需要傳遞信息。Watcher 攔截的動(dòng)作要告訴 Auditor讓 Auditor 知道這個(gè)動(dòng)作被攔了避免重復(fù)告警。Auditor 的告警級(jí)別要告訴 Circuit Breaker作為熔斷的輸入。Circuit Breaker 的熔斷事件要反饋給 Watcher讓 Watcher 在恢復(fù)后對(duì)同類動(dòng)作更嚴(yán)格。這個(gè)信息傳遞我用的是一個(gè)共享的事件總線基于 Redis Stream 實(shí)現(xiàn)。每個(gè)層往總線里發(fā)事件其他層訂閱自己關(guān)心的事件。這樣解耦后任何一層的調(diào)整都不會(huì)影響其他層。8.2 誤報(bào)率和漏報(bào)率的平衡安全系統(tǒng)永遠(yuǎn)在誤報(bào)和漏報(bào)之間權(quán)衡。誤報(bào)太高正常任務(wù)被打斷用戶會(huì)關(guān)掉防護(hù)漏報(bào)太高防護(hù)形同虛設(shè)。我的調(diào)優(yōu)目標(biāo)是誤報(bào)率控制在 5% 以內(nèi)漏報(bào)率控制在 1% 以內(nèi)。達(dá)到這個(gè)目標(biāo)靠的是持續(xù)迭代每周復(fù)盤一次告警日志把誤報(bào)的規(guī)則調(diào)松把漏報(bào)的場(chǎng)景補(bǔ)進(jìn)規(guī)則。這個(gè)過程沒有終點(diǎn)因?yàn)橹悄荏w的行為模式也在變化。一個(gè)實(shí)用的技巧是給不同類型的任務(wù)設(shè)置不同的閾值。比如數(shù)據(jù)清洗類任務(wù)對(duì)文件操作敏感閾值調(diào)嚴(yán)信息查詢類任務(wù)對(duì)網(wǎng)絡(luò)調(diào)用敏感閾值調(diào)嚴(yán)。ClawKeeper 支持按任務(wù)標(biāo)簽加載不同的規(guī)則集這個(gè)功能很實(shí)用。8.3 性能與安全的取舍加上三層防護(hù)后智能體的整體執(zhí)行效率大概下降了 30%。這個(gè)代價(jià)換來的是可控性我認(rèn)為值得。但如果你的場(chǎng)景對(duì)效率極度敏感可以這樣取舍Watcher 只保留規(guī)則引擎去掉模型推理延遲能降一半Auditor 改成異步分析不阻塞主流程但會(huì)失去實(shí)時(shí)攔截能力Circuit Breaker 保留因?yàn)樗亲詈蠓谰€不能省我的建議是至少保留 Watcher 的規(guī)則引擎和 Circuit Breaker這兩個(gè)是性價(jià)比最高的。Auditor 可以根據(jù)場(chǎng)景決定是否上。8.4 長(zhǎng)期運(yùn)行的維護(hù)要點(diǎn)ClawKeeper 跑起來后維護(hù)工作主要是三塊規(guī)則更新、模型迭代、日志清理。規(guī)則更新我設(shè)了一個(gè)月度節(jié)奏每月初回顧上月的告警和熔斷事件調(diào)整規(guī)則。模型迭代看情況如果發(fā)現(xiàn)模型對(duì)某類動(dòng)作的判斷準(zhǔn)確率下降就重新訓(xùn)練或換模型。日志清理是自動(dòng)化的按前面說的分層策略跑就行。還有一點(diǎn)容易被忽略定期做恢復(fù)演練。熔斷和恢復(fù)的流程不能只在出問題時(shí)才跑要定期模擬熔斷驗(yàn)證恢復(fù)流程是否正常。我每季度做一次演練每次都能發(fā)現(xiàn)一些小問題比如快照文件損壞、恢復(fù)腳本路徑錯(cuò)誤之類的。9. 一些個(gè)人體會(huì)ClawKeeper 這套東西我從最初的想法到穩(wěn)定運(yùn)行花了大概四個(gè)月。中間推翻過兩次設(shè)計(jì)一次是因?yàn)?Watcher 的攔截點(diǎn)選錯(cuò)了一次是因?yàn)?Auditor 的告警太吵。現(xiàn)在回頭看最大的體會(huì)是給智能體做安全難點(diǎn)不在技術(shù)在于對(duì)智能體行為模式的理解。你得先知道智能體在什么情況下會(huì)失控才能設(shè)計(jì)出有效的防護(hù)。這個(gè)認(rèn)知只能從實(shí)際運(yùn)行中積累看再多的文檔也沒用。我建議如果你剛開始做智能體安全先別急著上全套防護(hù)先跑一段時(shí)間的裸智能體把它的行為日志收集起來分析清楚它的風(fēng)險(xiǎn)模式再針對(duì)性地設(shè)計(jì)防護(hù)。這樣出來的方案比照搬框架要靠譜得多。另外一點(diǎn)是安全防護(hù)本身也要有可觀測(cè)性。ClawKeeper 的每一層都要有清晰的日志和指標(biāo)否則出了問題你都不知道是哪一層沒起作用。我在控制臺(tái)里做了一個(gè)簡(jiǎn)單的儀表盤顯示攔截次數(shù)、告警分布、熔斷頻率一眼就能看出防護(hù)是否在正常工作。最后說個(gè)實(shí)際的如果你只是個(gè)人使用 OpenClaw 做一些輕量任務(wù)可能不需要全套 ClawKeeper。但如果你在做團(tuán)隊(duì)級(jí)的智能體部署或者智能體要接觸生產(chǎn)環(huán)境的數(shù)據(jù)和系統(tǒng)那這三層防護(hù)是底線省不得。我見過太多因?yàn)槭×朔雷o(hù)而導(dǎo)致數(shù)據(jù)損壞或泄露的案例事后補(bǔ)救的成本遠(yuǎn)高于事前防護(hù)。