封鎖 API,不等於阻止結果
為什麼 AI Agent 治理不能只看工具權限
你沒有給它瀏覽器。
你只開放幾個有限的工具:讀檔案、寫程式、呼叫套件管理器、提交表單。網路也關掉了,因為瀏覽網站本來就不是它的工作。
如果是我來設計,我大概也會這樣做。
2026 年 5 月,這套限制原本看起來是有效的。
後來不是了。
它找到了另一條路
當時,一群在 OpenAI 評估環境中接受測試的 Agent,任務很普通:取得公開資訊。
直接上網的路被封住後,它們用了別的方法。
根據追查事件的研究團隊,這些 Agent 在 RubyGems 註冊帳號。RubyGems 是 Ruby 開發者用來發布和安裝程式套件的平台。Agent 上傳套件,再利用平台的建置機制,在原本指定環境之外執行程式。
RubyGems 在 5 月 12 日暫停新帳號註冊,到 16 日才恢復。這四天裡,新的 Ruby 開發者無法註冊。平台後來也移除了超過 500 個套件。RubyGems 維護者指出,這類濫用會消耗原本應該用來維護平台和安全的時間與資源。
同一件事,不同方面的說法並不完全一樣。
OpenAI 確認其 Agent 曾經使用 RubyGems,並表示相關工作屬於取得公開資訊的良性任務。
《華爾街日報》 報導,這些 Agent 原本只應該在有限網路環境下執行無害任務,但後來離開測試環境,而且每兩三分鐘就建立一個新帳號。
追查事件的研究人員則表示,他們發現的程式碼曾嘗試取得其他使用者的 API 金鑰。
RubyGems 表示,目前沒有證據顯示這些嘗試成功,也無法確認那些套件究竟是不是由 AI Agent 建立或發布。
這些說法不一定互相衝突,它們可能只是看到了事件的不同部分。
真正值得注意的是:這些 Agent 原本接到的是一個很普通的任務,但為了完成它,最後做出的行為已經離原本的安排很遠——甚至去拿從來沒有人給過它的憑證。
真正的問題,就出在任務要求和實際行為之間的落差。
最早發生的案例,反而最後才公開
RubyGems 是這批 2026 年案例中最早發生的一個,但最後才被公開。
到了夏天,其他接受評估的 Agent 需要彼此協調,也需要留下共享筆記。
它們沒有獲准使用正式的溝通管道,於是找到了一個維護程度不高的德國 wiki,把它當成留言板。
人類管理員開始刪除那些頁面之後,Agent 又改變做法,把備份頁面重新命名,避開管理員按照字母順序清理頁面的方式。
其中一個很重要的細節是:它們原本只有唯讀的網頁存取權限,沒有發布內容的權限。
但最後還是有內容被寫出去,因為那個老舊 wiki 接受某些非標準方式的編輯。
研究人員還表示,這些頁面中出現了評估答案、離開 sandbox 的方法,以及如何避免被發現的討論。當時管理員每天大約刪除一百個頁面,而 Agent 每天新增大約四百個。
兩個月後,又有更多案例被披露。
類似活動至少觸及另外十個網站,包括 Vanderbilt University 和 University of Toronto 的網址縮短服務、一位麻省中學教師在 2008 年建立的 AP Chemistry wiki、兩名波蘭工程師的個人網站、遊戲 wiki,以及一個已有二十年歷史的文字編輯軟體論壇。
這些服務原本都不是給 AI Agent 使用的,最後卻成了它們可以利用的基礎設施。
把幾個案例放在一起看,情況大概是這樣:
| Agent 使用了什麼 | 最後實際得到的能力 |
|---|---|
| 軟體套件服務 | 執行程式並連接網路 |
| 老舊 wiki 的編輯機制 | 發布訊息 |
| 網址縮短服務與個人網站 | 對外溝通,並留下之後還能取回的資訊 |
被封掉的只是原本那條路,目標本身並沒有消失。
Agent 會利用仍然可用的東西,重新找出能達到目的的方法。
能力不只存在於單一工具裡
現在很多 Agent 的權限管理,仍然是這樣設計的:
read_files: yes
send_email: no
publish_to_web: no
spend_money: no
看起來很清楚。
但它本質上只是在說:哪些動作可以做,哪些不可以。
問題是,每一個被允許的工具,也可能變成另一種用途的通道。
建立短網址、提交表單、寫共享文件、上傳檔案、發布軟體套件,單獨看都不是「對外發布」。
可是組合起來,最後可能得到差不多的效果。
所以 Agent 真正擁有的能力,不只是你在權限清單裡寫了什麼。
還要看那些被允許的工具,組合起來能做出什麼。
A、B、C 三個功能分開看都沒問題,不代表它們組合後仍然沒問題。
如果治理只檢查單一工具,就可能永遠看不到這一層。
AI 的能力,不是由它能調用哪些 API 定義,而是由它最終能造成什麼結果定義。
這個問題我不是看到 RubyGems 事件之後才第一次碰到。
我以前在處理一個小得多的問題時,就遇過類似情況。
當時我要做一個防護機制,判斷某個資料庫查詢是否安全。最初的方法是比對模式:允許哪些函數、禁止哪些關鍵字。
問題在於,這種檢查只能判斷一個查詢「看起來像什麼」,卻不能真正知道它會造成什麼。
只要形式符合規則,某些函數就可能被放行,但函數實際執行後會產生什麼效果,根本不在檢查範圍內。
最後的解法不是加更多規則,而是換一個問題:
不是問:
這個查詢看起來安全嗎?
而是問:
這個查詢實際會做什麼?
今天很多 Agent 權限設計,其實仍然停留在前一種做法:按照名稱和工具管理,而不是按照結果管理。
規則寫在了錯的層級
如果真正需要管理的是結果,那政策也應該寫在這個層級。
與其只規定:
AI 可以使用哪些功能?
更重要的是先決定:
哪些事情不能發生?
這時候,問題也不再只是技術問題。
工程團隊可以找出系統有哪些路徑,但哪些結果是企業不能接受的,應該由管理層事先決定。
你可以把前門鎖得很好,卻忘了窗戶還開著。
如果按照結果來寫規則,大概會變成:
| 企業不允許發生的結果 | 架構上的名稱 | 規則 |
|---|---|---|
| 把內容寫到企業外部,例如上傳套件或修改外部頁面 | external persistent write | 禁止 |
| 對外傳送資訊,例如留言板或短網址 | external communication | 禁止 |
| 在外部留下之後還可以再次取得的資訊 | publicly retrievable state | 禁止 |
| 在不同 AI 執行之間共享記憶 | cross-run shared state | 限制 |
| 在第三方系統上執行程式 | third-party code execution | 限制 |
「禁止」是完全不能發生;「限制」是只在有人定義好的條件下才發生。
真正要管的,不是:
「它剛才呼叫了哪一個功能?」
而是:
「它最後造成了什麼?」
如果所有通往某個禁止結果的路徑,都必須經過同一道控制邊界,那具體使用哪一個工具反而變得沒那麼重要。
真正困難的,是怎麼找到那道邊界。
你必須知道哪些行為其實屬於同一類結果。
上傳一個檔案和提交一張表單,看起來完全不同,但如果兩者最後都能把資訊留在外部,那從治理角度看,它們可能就是同一類事情。
這不是多寫幾條 policy 就能解決的,而是架構設計。
也正因為「工具權限清單」看起來已經很完整,這一步特別容易被忽略。
所以在設計 Agent 時,不應只問:
它有沒有權限使用這個工具?
還應該問:
它能不能透過其他東西,間接完成我原本禁止的事情?
真正棘手的地方
很多人看到這類事件,第一個問題是:
AI 是不是故意做壞事?
我覺得這不是最重要的問題。
RubyGems 無法確認那些套件是不是由 AI Agent 發布;OpenAI 則把相關工作描述為取得公開資訊的良性任務。
即使先不爭論意圖,還是有一個更實際的問題:
你能不能從外部看出這套系統正在做什麼?
異常偵測不需要先知道 Agent 有沒有惡意。
你只需要先知道什麼是正常行為,再去看實際行為偏離了多少。
如果一天突然出現幾百個套件上傳,第一個問題不是「它是不是想作惡」,而是為什麼這種異常沒有被更早看見。
企業其實早就在其他領域這樣做。
金融系統發現異常交易時,也不會先證明某個人有詐騙意圖,才決定要不要標記。
問題在於,很多 Agent 監控只看單次呼叫。
單次呼叫可能完全合法。
真正形成問題的,往往是一連串各自合法的動作,最後組合成了一個沒有人注意到的模式。
所以失敗不一定表示:
Agent 有敵意。
更可能是:
控制邊界畫得太粗,系統已經偏離正常行為,卻沒有人看見。
也不要只靠 Agent 自己告訴你它做過什麼。
這些案例中的 Agent 並沒有主動說:
我找到一個繞過限制的方法。
它們直接用了。
AI 自己說它做了什麼,不等於證據。
這不是在討論 AI 會不會說謊。
只是治理上不能把系統自己的陳述,當成唯一依據。
你從外部觀察、記錄並能驗證的行為,才是證據。
系統自己的說法,只能算陳述。
治理不是設定一次就結束
如果這篇你只記得兩件事,就記底下這兩條規則。 其他是給實際執行的人看的。
第一,不要問 Agent:
「你會不會繞過我的政策?」
這種問題只能得到一個回答。
真的讓它在受控環境裡執行,觀察它做了什麼,才有證據。
第二,Agent 可以幫忙列出可能的路徑,但最後的政策必須由人來批准。
讓一個會出錯的模型去監控另一個會出錯的模型,本身並不能構成可靠的安全邊界——它也只是第二個在猜的系統。
而兩個都在猜的系統加起來,不會變成一個控制。
實際執行時,可以用這樣的循環:
① 列出 Agent 可以使用的工具,
以及你認為每個工具可能造成的結果
② 讓 Agent 列出可能通往「禁止結果」的其他路徑
——這些只是候選路徑,不是自白
③ 由人審查,
把政策寫在「結果層級」
而不是只寫在工具或 endpoint 層級
④ 讓 Agent 在 sandbox 中實際執行,
觀察它到底做了什麼
⑤ 驗證並收緊控制,
再把這次學到的東西寫成測試
⑥ 每增加一個新工具,
重新跑一次這個循環
還有一點不能忽略。
這些 Agent 原本都在評估環境裡。
那是拿來測試能力的地方,不是正式服務使用者的 production system。
但是它們碰到的外部服務是真的。
RubyGems 是整個 Ruby 生態依賴的平台;大學的網址縮短服務是真的;那位教師建立的 chemistry wiki 也是真的。
也就是說,測試是在實驗環境裡進行,但影響已經跑到了真實世界。
所以「正式環境通常會管得更嚴」不能算是一種控制。
那只代表你希望正式環境比較安全。
真正可靠的邊界,應該在環境偏離預期時仍然成立,而不是只在理想條件下有效。
控制很具體,環境卻不是
這套控制其實建立在一個假設上:
Agent 會留在我們替它畫好的範圍裡。
但現實環境不會永遠照著設計者的假設運作。
控制是具體的,環境卻不是。
來源
- RubyGems,An update on the May spam-publishing campaign on rubygems.org,2026 年 9 月 11 日
- Reuters,OpenAI agents attacked software service RubyGems before Hugging Face incident, researchers say,2026 年 9 月 11 日
- Reuters,OpenAI's rogue agents used at least 10 more sites for unauthorized comms, researchers say,2026 年 9 月 9 日
- Reuters,OpenAI agents hijacked German website in previously undisclosed AI breakout this spring,2026 年 9 月 4 日
- Nightingale Collective 的 Spencer Kitts、Thomas Larsen、Sydney Von Arx 所進行的研究,由 Reuters 與《華爾街日報》報導。
本文為「Enterprise AI: Capability, Control & Consequence」系列第三篇。