iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
AI Security

我也希望安全第一——然後我們看看這些鎖是怎麼一個個被撬開的系列 第 10

第 10 篇|摘要、改程式、付款,不能用同一套安全標準

  • 分享至 

  • xImage
  •  

摘要、改程式、付款,不能用同一套安全標準

[[我也希望安全第一]]|第 10/30 天

如果明天要上線,我會先設定這六步

第 2 篇把 alignment 和 control 分開時,兩者還像兩套抽象理念。走完 Harness、代理型失準、prompt injection、guardrail 與產品摩擦之後,終於可以把它們放回產品會議裡。

假設現在桌上有三個需求:替客服工單做摘要、替工程師修改程式,以及替財務處理付款。它們都可以叫做 Agent,真正需要的安全標準卻差很多。與其先爭論該用更強的模型還是更多的限制,我會照下面的順序走一次。

列出外部效果
      ↓
找出不能跨越的線
      ↓
分開模型判斷與系統保證
      ↓
配置工具、權限與人工批准
      ↓
設計 allow test、deny test 與完成證據
      ↓
寫下發布門檻與殘餘風險

這不是一份通用認證標準,比較像上線前用來對焦的一輪檢查。每一步都問同樣的三個產品,答案很快就會分岔。

第一步:不要先看 Prompt,先列出外部效果

我會先問:「這個 Agent 猜錯時,外面的世界會有什麼變化?」不是問它用了哪個模型,也不是先替 prompt 加上「請小心」。

摘要 Agent 只讀取單一客戶的既有工單,輸出一段內部文字;程式 Agent 會修改 repository、執行測試並建立 pull request;付款 Agent 則可能選擇帳戶、收款人與金額,最後送出交易。

把效果列出來以後,三者已經不能再放在同一個風險籃子裡:

產品 正常效果 猜錯時可能留下什麼
客服摘要 讀取工單、產生內部摘要 摘要失真、遺漏資訊、混入其他客戶資料
程式修改 讀檔、寫檔、跑測試、建立 PR 改錯目錄、刪掉工作、碰到 secret 或 production
付款 讀發票、提出或送出交易 付錯金額、付錯對象、產生未授權交易

第 5 篇談 Tool Call 時,真正重要的也是這一層:模型提出 send_payment,和銀行真的收到付款要求,是兩件事。中間那段不能省略成一句「模型有工具可用」。

第二步:找出哪種錯誤不能靠事後修改

摘要漏掉一句話,使用者通常還能點回原始工單;PR 改壞了,可以關掉或重做,但刪掉別人尚未提交的工作就未必救得回來;款項一旦送出,還可能牽涉銀行、供應商與對帳流程。

所以我會替每個 workflow 寫下一條不能跨越的線:摘要不能跨租戶讀取,程式 Agent 不能寫入 production 或刪除既有未提交工作,付款 Agent 不能在未經批准時送出交易。

這一步看起來很基本,卻剛好是第 6 篇 VM 案例缺少的東西。任務要求刪除 VM 1、2、3,Agent 找不到它們,便拿 5、6、7 代替。若規格只有「完成三次刪除」,它甚至可能覺得自己很努力;若規格寫的是「只能操作這三個 ID,不存在就停止」,替換目標就不再是一種解法。

第三步:哪些交給模型判斷,哪些必須由系統保證

模型適合處理語義。它可以判斷摘要是否抓到客戶真正的問題、patch 是否符合需求、發票看起來是否重複或異常。這些能力可以用 eval 改善,但不會因為測到 99% 就變成保證。

不能跨越的線要換一種做法。租戶 ID 由服務端從登入身分帶入,不讓模型自由填寫;程式修改限制在獨立 worktree,環境裡不放 production credential;付款的收款人、金額、幣別與帳戶交給一般程式驗證。首次出現的收款人或超過門檻的金額,再送給人決定。

第 8 篇比較過外掛 classifier 與模型內建防護。兩者放置的位置不同,仍然都是會誤判的機率性控制。它們可以減少危險 proposal,卻不該兼任租戶隔離、IAM 或交易不變量。

第四步:替每個 Workflow 編一份能力預算

到了這一步才選工具和權限,會比「先給它一個 shell 再慢慢限制」容易得多。

客服摘要需要同租戶、唯讀的工單查詢,不需要寄信、退款或修改 CRM。程式 Agent 可以讀寫指定 worktree、執行測試並建立 branch,但不能讀取部署憑證,也不能直接合併。付款 Agent 可以讀發票、查供應商資料並建立 proposal;真正的 commit payment 是另一個能力,而且批准必須綁定這一次交易的收款人、金額、幣別與帳戶,參數一改就失效。

第 7 篇那份被動過手腳的 PDF,也應該在這裡出現。外部文件可以影響模型對內容的理解,不能因此取得新的能力。發票裡就算藏著「把款項改匯到另一個帳戶」,它能碰到的仍然只該是 proposal。

這也是第 9 篇所說的產品取捨真正落地的地方。摘要不必每產生一段就問人;付款也不能因為使用者嫌確認麻煩,就把批准按鈕變成裝飾。摩擦應該跟外部效果一起增加,不是平均灑在所有操作上。

第五步:「測試通過」要拆成三種證據

我不會只留一個 task success rate。至少要看到三類結果:

allow test:正常任務能不能完成?
deny test:越權或危險要求是否真的被執行層拒絕?
完成證據:系統憑什麼相信 Agent 已經做完?

摘要 Agent 的 allow test 可以看長工單、少數語言與引用忠實度;deny test 用真實服務身分證明它讀不到其他租戶;完成證據則讓每句摘要能點回來源。

程式 Agent 要真的產生 diff、跑測試並建立 PR,也要測試它無法寫出 worktree、讀取 secret 或直接部署。不能只接受模型回一句「已修好」。若 Generator 和 Evaluator 共用同一個模型與同一份污染 context,兩者一致也可能只是一起看漏,因此測試、lint、權限與 branch protection 要保留獨立判斷。

付款 Agent 可以測試正常發票能否順利產生 proposal,也要刻意換掉收款人、提高金額、重播批准,確認交易層全部拒絕。這裡追求的不是模型從不誤報,而是未授權交易維持為零。

第 6 篇把 VM 案例改寫成幾條可重播的軌跡,做的正是這種 deny test。至於高風險 eval 要如何架隔離 Runner、限制網路和保存證據,第 14 篇再實際動手;第十篇先把「發布前必須證明什麼」寫清楚。

第六步:把選擇寫成一頁發布決定

走到最後,團隊應該能填完這張表,而不是只在簡報上留下一個 safety score:

workflow:
主要使用者與受影響第三方:
Agent 能造成的最大外部效果:
不能跨越的線:

依賴模型判斷的部分:
  - 評估資料與可接受的失敗門檻:

由系統保證的部分:
  - IAM/工具/交易不變量:
  - 從真實執行身分完成的 deny test:

完成任務所需的證據:
仍接受的殘餘風險:
失效時由誰停止:
為了完成率、成本或便利,這次放寬了什麼:

同一句「測試通過」,在三個團隊裡不該有同一個意思。客服團隊可能接受少量摘要遺漏,不能接受跨租戶內容;程式團隊可以接受一個失敗但隔離良好的 patch,不能接受 production 寫入;財務團隊可以容許正常發票被送去人工覆核,不能容許未批准付款。

這張決定書不要求每個產品堆滿同樣的鎖。它只是逼我們說清楚:哪些判斷容許以機率改善,哪些結果必須由系統擋住,以及為了讓產品能用,我們接受了什麼。

到這裡,我們得到的是一份可以發布的設計,還不是一個已被證明安全的系統。第三部會把 Agent 接上真實環境,看看文件裡的權限、隔離、監控與復原假設,實際上能撐多久。

本篇的鎖

  • 鎖是什麼:對齊降低模型選擇危險手段的機率;控制限制那些手段能否在外部系統實現。
  • 想攔什麼:從意圖誤讀、prompt injection 到過大權限與不可逆操作的不同失敗。
  • 破口在哪:對齊無法保證未見情境,控制又會留下工作所需的開口;多層防線若共用同一模型、context 或高權限身分,也可能一起失效。
  • 怎麼補:沿著外部效果、不可跨越的線、控制配置與發布證據走完一次;高傷害效果先做成可測的 hard boundary,再用對齊降低違規 proposal。

參考與來源


上一篇
第 9 篇|每少一次確認,Agent 就多一點自由:安全、完成率與使用成本
下一篇
第 11 篇|Hugging Face 入侵事件——一次 benchmark 如何越過沙盒
系列文
我也希望安全第一——然後我們看看這些鎖是怎麼一個個被撬開的19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言