D14 我把 legitimacy_reference 拆成四種可能的參照來源:政策標準、流程模型、歷史行為與任務目的。那篇最後留下的問題是,執行環境即使判定某個 Agent 行為「符合參照」,也只能證明這個行為符合目前採用的判斷標準,不能直接證明這個行為安全。這個問題放到歷史行為參照上尤其麻煩,因為政策或流程模型通常由人事先定義,但歷史參照的內容可能直接來自 Agent 過去的執行紀錄。
如果執行環境會持續收集 Agent 的執行紀錄,再利用這些紀錄更新「正常行為長什麼樣子」,那麼執行紀錄就不只是事後稽核資料,而是會反過來影響下一輪判斷的輸入。只要攻擊者能持續影響 Agent 的執行行為,就有可能進一步影響執行環境用來判斷正常與異常的參照。 今天要處理的問題,就是這個判斷標準本身的完整性。
這篇需要先和 D7、D8 的記憶汙染分開。D7、D8 討論的是 決策輸入被污染:攻擊者把惡意內容放進 Agent 會讀取的文件、網站、記憶或其他資料來源,讓 Agent 在後續推理與工具使用時做出錯誤決策。
D7 / D8
污染決策輸入 → Agent 做出錯誤決策 → Agent 執行錯誤 action
D15 的攻擊位置不同。假設執行環境會把 Agent 的行為和某個 legitimacy_reference 比較,再決定是否允許、阻擋或升級處理,那麼攻擊者不一定要直接繞過當下的偵測器。如果這份 reference 會根據歷史執行資料自動更新,攻擊者也可能改變未來的判斷標準。
D15
影響執行紀錄 → 紀錄進入參照更新 → legitimacy_reference 發生偏移 → 後續執行環境判斷失準
Barreno 等人對對抗式機器學習的分類可以拿來說明這個差別。當判斷器本身已經固定,攻擊者主要是在既有決策邊界上尋找可以繞過的方法,這類攻擊屬於 exploratory attack;如果攻擊者能影響訓練資料或學習流程,使判斷器本身產生變化,則屬於 causative attack。
放到 Agent 執行環境裡,可以簡化成:
固定 reference → 找出可以避開偵測器的行為 → exploratory attack
reference 持續更新 → 影響參照更新的資料 → 改變之後的判斷標準 → causative attack
因此這篇關注的不是單純「攻擊者怎麼騙過偵測器」,而是 如果偵測器使用的 reference 會自己更新,誰有能力影響這個更新過程?
把投毒簡化成「攻擊者塞入一些異常資料」會漏掉重要部分。攻擊是否能成功,除了資料內容本身,也取決於系統如何利用新資料更新模型狀態。
Kloft 與 Laskov 研究的是線上中心點異常偵測。最基本的中心點偵測器會先根據已知的正常資料計算中心:
n
c = (1 / n) × Σ xᵢ
i=1
新樣本 x 進來後,系統計算它和中心 c 的距離:
f(x) = ‖x − c‖
如果距離超過設定門檻 θ,系統就將資料判定為異常:
f(x) > θ
如果偵測器的模型固定不變,攻擊者只能尋找仍然落在判斷範圍內的輸入。但在線上學習裡,系統還會利用新資料更新中心點。一筆資料因此可能同時具有兩個角色:它先接受目前偵測器的判斷,接著又可能成為下一輪偵測器的更新資料。
新資料 → 目前偵測器判斷 → 被接受 → 學習/更新 → 模型狀態改變 → 下一筆資料使用新的模型狀態
投毒利用的就是這個回寫機制。攻擊者不一定要一次送進一筆明顯異常的資料,而可以持續提供仍落在目前容忍範圍內、但會把模型往特定方向推動的樣本。每一筆資料單獨看都可能不足以觸發異常,但這些資料一旦持續參與更新,累積效果就可能改變模型的正常基準。
Kloft 與 Laskov 的分析不能只簡化成「攻擊者慢慢拖動中心點」。攻擊效果高度受到資料窗口與更新方式影響。
如果系統採用 infinite-horizon,也就是所有歷史資料都一直保留,訓練資料集會隨時間持續增長。對這類學習器而言,第 i 次攻擊資料對中心點造成的相對位移有上界:
Dᵢ ≤ ln(1 + i / n)
其中 n 是原始訓練資料的數量,i 是攻擊者後續注入的攻擊資料數量。歷史資料越多,單一新樣本對整體模型的影響通常越小,因此攻擊者如果想持續把中心點推向某個方向,需要控制更多資料。
這個結果不能直接當成 Agent 執行環境的數學模型,但可以用來說明一個工程上的關係:投毒的影響程度和攻擊者能控制的更新資料比例、原始資料量與更新窗口都有關係。
實際系統往往不會永久保留所有歷史資料。Agent 的任務分布會變,工具會更新,業務流程也會調整。如果執行環境永遠把很久以前的行為放進 reference,舊資料可能反而妨礙系統適應新的正常行為。因此工程上可能採用有限更新窗口,或提高近期資料的權重。
完整歷史資料 → 單筆新資料的影響逐漸下降 → 投毒較難累積 → 新行為適應較慢
有限更新窗口 → 新資料相對權重提高 → 正常變化適應較快 → 攻擊資料也更容易影響 reference
在有限時間範圍的情況下,如果系統只保留最近 n 筆資料,攻擊者控制最近資料的比例就會直接影響模型。在 Kloft 與 Laskov 討論的簡化平均更新規則下,如果攻擊者在窗口內控制 i 筆資料,中心點的相對偏移可以和 i / n 直接相關。
換到 Agent 執行環境,假設 reference 只根據最近 1000 次執行建立,而攻擊者有能力反覆觸發其中 50 次行為,那麼攻擊者實際上已經控制了這個更新窗口中 5% 的資料。如果這 50 筆執行紀錄會直接參與 reference update,它們就不再只是系統紀錄,而會成為定義「正常行為」的一部分。
把傳統中心點偵測器換回 Agent 執行環境,問題會更清楚。
假設一次正常退款流程的執行紀錄長這樣:
order_lookup → payment_verify → refund
執行環境不一定只保存工具名稱,也可能把一次執行轉換成更完整的行為特徵,例如工具呼叫順序、資源類型、參數類型、呼叫頻率、權限使用狀況、跨服務跳轉、資料流向,以及錯誤與重試模式。
可以把一次執行紀錄記成 τₜ,再利用特徵抽取函式 φ 轉成行為表示:
φ(τₜ)
如果執行環境會利用目前這筆執行更新 reference,更新關係可以抽象寫成:
Rₜ = Update(Rₜ₋₁, φ(τₜ))
其中 Rₜ 是更新後的 legitimacy_reference。下一次 Agent 執行時,執行環境再拿新的紀錄和 Rₜ 比較:
score(τₜ₊₁, Rₜ)
執行紀錄不只是被 reference 判斷的對象,它也可能反過來參與 reference 的形成。
如果攻擊者只能控制當下的 τₜ,影響範圍還停留在這一次執行。但如果 τₜ 會進入 Update(),攻擊者的影響就可能延伸到 Rₜ,進一步改變下一輪偵測器的判斷結果。
假設 Agent 原本只有一條常見退款流程:
查詢訂單 → 確認付款 → 執行退款
攻擊者真正想得到的流程可能是:
查詢訂單 → 讀取額外資料 → 呼叫外部服務 → 將資料送出
如果完整路徑第一次出現時就直接執行,執行環境很可能會發現工具序列、資料流向或資源存取和歷史 reference 差異太大。
但如果 reference 會從歷史執行持續更新,攻擊者可以嘗試把行為差異拆成多次較小的改變。例如一開始只多讀取一個額外欄位,接著開始呼叫新的內部服務,再慢慢加入外部服務。
原始流程
查詢訂單 → 確認付款 → 執行退款
階段 1
查詢訂單 → 讀取額外欄位 → 確認付款 → 執行退款
階段 2
查詢訂單 → 讀取額外資料 → 呼叫內部服務 → 確認付款 → 執行退款
階段 3
查詢訂單 → 讀取額外資料 → 呼叫外部服務 → 確認付款 → 執行退款
這裡需要分開兩個判斷:執行環境是否允許這次執行,以及這次執行是否有資格成為未來的 reference 資料。
目前允許執行 ≠ 具有資格更新 reference
某個行為可能因為風險分數仍在允許範圍內而被執行環境放行,但這不代表執行環境已經確認這個行為具有足夠可信度,可以拿來定義未來的正常行為。
ALLOW 和 LEARN 不應該是同一件事如果 reference update 的條件只是:
if detector.allow(trace):
reference.update(trace)
系統其實把兩個不同的安全問題合併在一起。
第一個問題是:
這一次執行是否可以繼續?
第二個問題是:
這一次執行是否可以成為未來判斷正常與否的證據?
前者屬於執行環境的管制;後者屬於參照納入審核。兩者需要的信任程度不一定相同。
比較合理的結構應該是:
執行紀錄 → 執行環境偵測 → 是否允許本次執行? → ALLOW → reference admission → 是否有資格進入 reference? → YES / NO
如果系統直接把 ALLOW 等同於 LEARN,就可能形成:
行為被允許 → 行為進入 reference → reference 發生偏移 → 類似行為之後更容易被允許 → 更多類似行為進入 reference
因此 reference admission 應該是獨立的安全控制點,而不是偵測器通過之後自動發生的背景流程。
D13 已經談過執行環境管制對 Agent 執行流程的影響。Agent 先提出 action,外部執行環境再依照授權與安全政策決定是否允許、修改或阻擋該 action。這個決策會改變 Agent 後續真正執行的路徑。
如果 D14 的 historical reference 又是從執行紀錄建立,兩條線接起來之後就會形成:
執行環境管制 → Agent 實際執行 → 執行紀錄 → reference update → 新的 legitimacy_reference → 下一次執行環境管制
可以把這個關係寫成:
τₜ → Rₜ₊₁ → Dₜ₊₁ → aₜ₊₁ → τₜ₊₁
其中:
如果攻擊者能夠持續影響某些 aₜ,這些 action 又會產生新的 τₜ,而 τₜ 最後還會進入 Rₜ,攻擊者的影響就可能從單次執行延伸到後續的判斷標準。
這裡需要保留研究上的界線。傳統投毒研究已經證明學習型異常偵測器可以受到訓練資料污染;近年的 Agent 記憶研究也已經證明惡意內容可以透過持久記憶長時間影響後續行為。可是「Agent 執行紀錄被拿來更新 legitimacy reference,再回頭影響執行管制」這條完整執行環境回饋迴圈,目前比較適合當成工程上的攻擊假設,而不是已經被普遍實驗驗證的事實。
不能因為學習型 reference 有投毒風險,就直接得到「手寫政策比較安全」這個結論。不同 reference 的完整性問題只是出現在不同位置。
| 參照類型 | 建立方式 | 主要完整性風險 |
|---|---|---|
| Policy / specification | 人工定義 | 設定竄改、供應鏈問題、權限濫用 |
| Process model | 預先定義 | 流程模型錯誤、設定漂移、版本不同步 |
| Historical behavior | 從歷史執行建立 | 投毒、資料污染、參照漂移 |
| Online execution reference | 持續吸收新執行紀錄 | 回饋污染、投毒、漂移 |
| Task-derived reference | 從任務與計畫推導 | 任務理解錯誤、計畫操弄 |
手寫政策不會因為攻擊者反覆觸發某些 Agent 行為就自己改變,但它仍然可能被管理者誤設、被供應鏈修改,或被具有高權限的人直接更動。流程模型也一樣,完整性風險主要來自模型本身是否正確,以及實際業務流程和既有模型是否已經脫節。
對一份會持續更新的 reference,至少需要明確定義:
如果這三個條件都沒有明確限制,reference 本身就會成為執行環境的高價值控制面。
防投毒最大的麻煩,是 reference 本來就可能需要改變。
例如 Agent 原本只處理退款流程:
查詢訂單 → 確認付款 → 執行退款
後來系統加入修改配送方式的功能:
查詢訂單 → 修改配送方式 → 重新計算費用 → 確認付款 → 執行退款
修改配送方式 → 重新計算費用 這段 transition 以前可能完全沒有出現過,但它不一定代表攻擊。這就是概念漂移:正常資料分布或正常行為模式會隨環境、業務與時間改變。
問題在於,投毒和概念漂移從執行環境的角度可能長得非常接近:
正常業務變化 → 新執行模式持續出現 → reference 需要更新
攻擊者逐步推動 → 新執行模式持續出現 → reference 被污染
兩種情況最後都可能表現成「以前沒有出現,現在開始穩定出現」。因此執行環境如果只根據新穎程度或出現頻率判斷,就很難知道這次變化究竟是新的正常行為,還是攻擊者正在逐步改變 reference。
reference update 因此不能只看執行模式本身。系統還需要保留行為發生時的情境,例如:
其中來源脈絡特別重要。假設十萬次執行都來自已知可信的業務流程,而最近多出來的某種模式幾乎全部由同一個低信任來源觸發,執行環境如果只把所有 trace 混在一起計算統計分布,就會直接丟掉「這些行為到底從哪裡來」這個安全訊號。
最直覺的防禦方法,是不要讓 reference 自動更新。但 reference 如果完全凍結,系統又會遇到另一個問題:正常業務一旦改變,新流程就可能持續被判定為異常。
因此更新速度本身就是一個安全參數。
更新越快,reference 越容易追上正常的概念漂移,但單批新執行對 reference 的影響也越大;更新越慢,攻擊者需要控制更多資料才能推動 reference,但系統也更容易把真正的新流程判成異常。
適應速度
↕
投毒抵抗能力
工程上需要處理的不是單純「要不要更新」,而是 誰可以更新、更新多少、更新多快,以及哪些資料有資格參與更新。
Kloft 與 Laskov 的分析提供了一個可以轉成工程設計的觀察:攻擊者可以控制的訓練資料比例越低,能造成的模型偏移通常也越有限。
換成 Agent 執行環境,可以拆成幾個控制項。
第一個是 update rate。不要讓短時間內大量執行直接重寫 reference。例如最近 1000 次執行即使全部通過偵測器,也不代表 1000 筆都需要立刻進入 reference。執行環境可以限制每個時間窗口真正參與 reference update 的資料量。
第二個是 contributor quota。如果同一個 Agent instance、session、tenant 或資料來源可以佔據整個 reference window 的大多數資料,那麼攻擊者只要控制其中一個來源,就可能獲得很高的實際投毒比例。限制單一來源的貢獻比例,可以降低這種影響。
第三個是 reference admission。沒有被偵測器阻擋的執行紀錄,可以先保留成 observation,但不一定立刻加入 trusted reference。只有符合額外條件的執行紀錄,才允許參與 reference update。
第四個是 update window。窗口越短,最近資料對 reference 的影響越大;窗口越長,舊資料的影響越強。這個參數不能只從模型準確率決定,也需要從投毒抵抗能力的角度一起考慮。
最後是 provenance。reference 不應該只知道「這種行為曾經出現」,還需要保留這個行為是從哪裡來的。
behavior → source → task → authorization context → timestamp → policy version → agent version → tool version
如果 reference 後來發生異常漂移,這些中繼資料才讓執行環境能回頭分析是哪一批執行紀錄造成偏移,而不是只看到最後已經變形的統計結果。
如果 legitimacy_reference 最後會影響 ALLOW、DENY 或 ESCALATE,那麼修改這份 reference 的能力,本質上就接近修改政策。
因此 reference update 不應該被當成單純的背景維護流程。比較合理的結構是:
執行紀錄 → 紀錄驗證 → reference admission → reference update → new legitimacy_reference
其中至少需要區分兩個地方。
trace validation 處理的是執行紀錄本身是否可信,例如紀錄是否完整、來源是否可驗證、是否經過竄改。
reference admission 處理的是另一個問題:即使這份執行紀錄是真的,它是否有資格成為「正常行為」的證據。
一筆執行紀錄完全可能是真實發生、紀錄完整,也確實被執行環境允許執行,但仍然不適合直接進入 reference。例如某次 execution 是人工緊急批准的例外流程,這筆紀錄是真實的,也可能符合當下授權,但如果執行環境把它當成正常模式長期學習,之後就可能錯誤放寬判斷標準。
所以 reference 的信任鏈不只需要保護儲存,也需要保護納入審核和更新。
D15 補上的不是另一種 prompt injection,而是 判斷標準本身也有完整性問題。如果執行環境使用 Agent 的歷史執行紀錄建立或更新 legitimacy_reference,那麼這些紀錄就同時是被判斷的對象,也是未來判斷的依據。傳統異常偵測器投毒已經證明,只要攻擊者能影響一部分更新資料,就可能改變學習出的正常分布;Agent 執行環境如果把執行紀錄直接回收到 reference update,這個問題就會進一步和執行管制形成回饋。
目前還不能把完整的 execution trace → reference update → enforcement → execution trace 閉環直接寫成已經被 Agent 實驗證實的攻擊模式。比較準確的說法是:既有投毒研究提供了理論與實驗基礎,而以執行紀錄為基礎的 reference 則把這個問題帶進 Agent 執行環境的設計裡。 執行環境必須同時處理概念漂移與投毒:reference 完全不更新會錯擋新的正常行為,更新得太自由又可能讓攻擊者參與定義「正常」。因此 reference update 應該被視為執行環境的安全控制面,而不是預設可信的背景流程。