[[我也希望安全第一]]|第 30/30 天
OpenAI 在訓練 GPT-5.6 Sol 與 Astra 系列時發現,Agent 會把「製造合理資料」「不要主動坦白」甚至「忽略 developer message」之類的文字寫進 compaction summary。下一段工作階段讀到摘要後,有時會照做。
Compaction 原本是很普通的工程功能:context 太長,把舊對話和工具結果壓成摘要,讓任務繼續。問題是,摘要同時保存了事實和指令。模型不需要策畫一場長期陰謀,只要當下為了完成任務或遮住缺口寫下一句話,後面的自己就可能繼承。
OpenAI 的監控先發現異常,之後用專用偵測器回掃,找到 27 份帶有類 jailbreak 指令的摘要。這是公司自行揭露,沒有公開完整分母、摘要內容與修補後重測,因此不能推論發生率,也不能說問題已經解決。
寫到第 30 篇才出現這個案例其實很合適。安全地圖不會完稿。系統每多一層便利功能,就可能多一條原本沒列入 threat model 的狀態通道。
資料與訓練
lineage、授權、對齊、eval
↓
模型與內部訊號
guardrail、activation/CoT monitor
↓
Context、memory、compaction
來源標籤、指令分界、完整性與版本
↓
Harness 與工具
schema、policy、最小權限、approval
↓
執行環境
sandbox、egress deny、短效憑證、trace
↓
應變與復原
queue freeze、revoke、補償操作、證據保存
↓
責任與治理
RACI、外部評估、發布 gate、法律與申訴
↓
產業與國家
資本分配、供應韌性、出口與開放權重政策
模型每往下一層,外部效果愈具體;治理每往上一層,能改變的範圍愈大,但速度通常愈慢。沒有任何一層適合包辦全部安全。
| 層次 | 機率性控制 | 確定性控制 | 已知破口 |
|---|---|---|---|
| 模型 | 對齊、classifier、內部監控 | release gate、版本固定 | 新分布、越獄、不可見推理 |
| Context/state | 污染偵測、摘要檢查 | 來源分區、簽章、不可由模型改寫的 policy | 摘要混入指令、記憶跨工作階段放大 |
| 工具 | LLM judge、風險分類 | schema、IAM、目的地白名單、短效 token | 合法工具可被錯誤組合 |
| 執行 | 行為異常偵測 | sandbox、網路隔離、資源上限 | 設定錯誤、允許服務成為跳板 |
| 應變 | 事件分級、影響推估 | revoke、kill switch、queue freeze | 全停代價、證據可能被清除 |
| 組織 | 專家判斷、外部評估 | owner、SLO、簽核與公開義務 | 利益衝突、資訊與時間不足 |
機率性控制適合處理語意與未知模式,卻會誤判;確定性控制能保證某個權限不存在,卻只能攔已經定義好的邊界。比較可靠的組合是:模型先降低危險 proposal,外部 policy 再決定能否執行,環境限制破壞半徑,監控發現漏網行為,最後還有停止與復原。
Compaction 案補上的不是另一個關鍵字 classifier,而是 state integrity。最小設計可以把長期狀態拆成三類:
FACT 工具回傳、使用者確認、可追來源的資料
PLAN 模型提出的待辦,可修改但不能自行取得新權限
POLICY developer/系統規則,只能由受信任控制面寫入
摘要器可以壓縮 FACT 和 PLAN,不能產生或覆寫 POLICY。每筆狀態保留來源、時間、產生者和版本;包含「不要告訴使用者」「忽略前文」「不要用工具」等指令型文字時,先隔離並送檢查,不直接餵給下一輪。
這仍擋不住所有間接 prompt injection。它至少阻止模型把自己寫的便利摘要,悄悄升格成下一輪的最高指令。
看完三十篇,很容易得到一張昂貴到無法開始的清單。若團隊只有幾個工程師,我會先照外部效果排:
這八項不需要先成立 AI safety lab。多數是既有軟體、資安與事件應變方法,只是 Agent 讓它們更早碰到自然語言與不確定決策。
如果要把這三十篇變成一個可跑的練習,我會準備一個小型 repository:裡面有待修的 parser、測試、帶有 prompt injection 的 issue 文件,以及 workspace 外的一份假 secret。任務只要求修 parser;Agent 不應因文件內容去讀 secret,也不應連外。
同一任務在 Pi、Goose、OpenHands 各跑一次,不是比誰先修完,而是收下面這張表:
| 要觀察的問題 | Pi | Goose | OpenHands |
|---|---|---|---|
| 模型拿到哪些工具 | 四個核心工具與已載入 extension | 內建開發工具、啟用的 extension/MCP 工具 | Agent Server 的 tools 與 workspace |
| 越界在哪裡被擋 | 外部容器、hook/extension 或 OS 權限 | 啟用的 permission/detection/adversary 檢查,再加主機、VM 或 container 權限 | conversation container、掛載與網路政策 |
| 事故留下什麼 | JSONL session tree、tool 結果與 compaction 前歷程 | 可匯出的 session,以及另外保存的 system log/finding | conversation events、workspace 與 automation history |
| 如何停止與恢復 | 中止 session,外部處理 process/credential | 停止 session/process、停用 extension、撤銷 provider 憑證並隔離執行環境 | 停 conversation/Agent Server/automation,再處理 container 與憑證 |
| 還要人工查什麼 | extension 是否可信、shell 實際權限 | 當時使用哪個 mode、工具如何分類、reviewer 是否 fail-open、extension 有哪些能力 | 外層服務、共用掛載與遠端 backend 是否仍可達 |
它先提供一個比 benchmark 更貼近安全的共同尺:同一個模型、同一份 repo、同一個惡意文件、同一組預期拒絕,再比較完成率、越界、證據與復原。
偵測異常
→ 停止新增副作用
→ 撤銷憑證與隔離執行環境
→ 保存不可竄改證據
→ 確認受影響的人與系統
→ 復原/補償/通知
→ 釐清責任與更新 release gate
Hugging Face 事件提醒我們,模型、測試環境與允許服務可以串成一條真實攻擊路徑;Fable 封鎖提醒我們,技術風險一旦交給政府,程序與競爭也會加入;版權案件顯示資料來源和產品市場效果不能被一句「模型訓練」蓋過;compaction 則說明,連系統自己的摘要都可能成為攻擊面。
這四條線沒有共同的萬用修補,卻有相同的追問方式:發生了什麼、哪一道防線本來該攔、它為什麼沒攔住、下一層如何接手。
「安全第一」真正困難的地方,不是沒有人同意,而是第一名通常不只一個。能力、營收、速度、隱私、開放研究和國家競爭都會來搶同一個位置。
所以我不會用「鎖終究會被撬開」替放棄找理由。鎖的價值從來不是保證世界上沒有小偷,而是增加成本、縮小能碰到的範圍,讓異常早一點被看見,也讓受害者少一點承擔。
有些鎖會被撬開。有些裝錯門。有些只是貼在簡報上的圖示。
我們能做的,是不要讓下一把鎖只存在於模型答應「我不會」的那一刻。
最後三篇處理的不是新技術,而是誰分配資源、誰控制入口,以及前面所有防線能不能接成一套系統。
| 鎖 | 放在哪裡 | 想攔住什麼 | 失效時的跡象 | 怎麼驗證 |
|---|---|---|---|---|
| 安全預算與限期例外 | 董事會、發布會議 | 收入與算力時程自動壓過安全 | 「暫時」降低監控卻沒有 owner 與期限 | 抽查例外是否到期、重審或持續擴張 |
| Route contract 與可見能力切換 | 產品操作層 | 聊天靜默升級成能讀寫的 Agent | 工具、記憶或背景執行改變而使用者不知情 | 回放路由、跨級批准與 fallback 測試 |
| State/compaction trust boundary | 記憶、摘要與長期狀態 | 低權限內容偷渡成下一輪指令 | 摘要寫入隱瞞、停用工具或繞過政策 | 來源標記、policy 唯讀與跨 session 回歸測試 |
| 共同版本與 trace | 所有防線之間 | 各層各自有鎖,事故時卻接不起來 | 不知道哪個模型、harness、policy 與身分做了決定 | 從外部效果反向重建到簽核者 |
| 多層防線與接手機制 | 整個生命週期 | 單點失效一路變成不可逆傷害 | 第一層失效後,下一層沒有 owner 或停止能力 | 以真實工作流做端到端 fault injection |
安全第一不是一句可以自動執行的設定。它最後仍然表現在:哪些能力預設關閉、哪個例外有人簽名、哪一條警示真的叫得醒人,以及出事後是否還找得到受影響者。