前一天我們拆解了 Tool Calling 和 Tool Runtime。
模型產生 Tool Call,只代表它提出一個行動請求。
真正的 Tool Runtime 還要處理工具查找、參數驗證、執行、逾時、錯誤與輸出管理。
但就算工具存在、參數正確、執行方式也沒有問題,仍然不能直接開始執行。
因為還有一個更重要的問題:
這個操作被允許嗎?
Agent 能做某件事,不代表它應該被允許做某件事。
讀取公開文件和讀取私人金鑰,都可能使用同一個讀檔工具。
修改測試檔案和刪除整個專案,也可能使用同一組檔案權限。
傳送一封草稿 Email 和真的寄出 Email,對使用者造成的影響完全不同。
因此,Production Agent 必須把能力和權限拆開。
今天要介紹三個核心機制:
它們分別回答三個不同問題:
完整系列與程式碼範例收錄於 GitHub
先區分兩個常被混在一起的概念。
Agent 是否具備完成某個行動的能力。
例如:
Agent 在目前任務、使用者和環境中,是否被允許執行這個行動。
例如:
同一個 Capability,可以根據情境得到不同 Permission。
有工具
不等於
有權限
有權限
也不等於
這一次不需要確認
如果系統只控制工具是否存在,卻沒有控制工具可以對哪些資源做什麼,權限模型仍然非常粗糙。
很多 Agent 會在 System Prompt 中加入:
不要刪除重要檔案。
不要存取使用者的敏感資料。
在進行危險操作前先詢問使用者。
這些指令有價值。
它們可以幫助模型理解預期行為,降低錯誤決策的機率。
但它們不能取代真正的權限控制。
模型可能:
所以真正的安全規則必須由模型外面的程式碼強制執行。
可以把兩者分成:
Prompt
告訴模型應該怎麼做
Permission System
限制模型實際能做什麼
一個可靠的系統不只希望 Agent 不會越界。
它還要讓 Agent 即使判斷錯誤,也無法越界。
Permission 不只是「允許使用哪個工具」。
完整的 Permission Check 通常要看多個維度。
Agent 是否能使用這個工具?
例如:
Agent 可以對哪些資源執行操作?
例如:
同一個工具可能包含不同風險的行動。
例如資料庫工具可能同時支援:
允許查詢,不代表允許刪除。
Agent 可以一次影響多少內容?
例如:
目前是誰要求執行?
例如:
同一個行動在不同身份下,權限可能不同。
目前任務的目的是否允許這個操作?
例如:
Permission 是一個與情境相關的判斷,而不只是固定的開關。
一個實用的 Permission System,通常至少需要三種結果。
操作可以直接執行。
例如:
操作永遠不允許。
例如:
操作可以執行,但需要人類批准。
例如:
這三種狀態非常重要,因為不是所有高風險操作都應該直接禁止。
有些操作是任務必要的一部分,只是需要把最後決定交還給人類。
Approval 是 Agent 的人類確認機制。
它通常出現在:
模型選擇行動
↓
系統判斷需要批准
↓
向使用者顯示操作內容
↓
使用者批准或拒絕
↓
系統執行或終止
Approval 的目的不是讓使用者確認每一個步驟。
如果 Agent 每讀一個檔案都要詢問一次,系統會變得難以使用。
Approval 應該集中在有明顯副作用、不可逆或高成本的操作。
可以使用幾個問題判斷是否需要批准:
如果多個答案是肯定的,通常就值得加入 Approval Gate。
Approval 並不是單純顯示:
Agent 想使用
send_email,是否允許?
使用者真正需要知道的是:
因此,好的 Approval 需要呈現具體副作用。
例如:
準備寄出一封 Email
收件者:客戶 A
目的:回覆退款申請
內容:同意退款 120 美元
附件:無
是否批准?
Approval 的價值來自可理解性,而不是多一個按鈕。
如果使用者看不懂 Agent 要做什麼,批准就只是形式。
當 Agent 暫停等待批准時,任務不能消失。
系統需要保存:
這表示 Approval 不只是一個 UI 問題。
它也是 Task State 問題。
Running
↓
Waiting for Approval
├── Approved → Resume
├── Rejected → Return Observation
└── Expired → Stop or Ask Again
如果沒有明確狀態,Agent 可能在重新啟動後重複執行、遺失批准結果,或把舊批准套用到新的操作。
假設 Agent 說:
我需要修改五個檔案並重新執行測試。
批准可以有不同粒度。
每個 Tool Call 都要確認。
優點是控制細。
缺點是使用者很快會疲乏。
使用者批准 Agent 在某個限定範圍內操作。
例如:
tests/ 目錄這種方式通常更實用。
使用者允許某類操作在未來自動執行。
例如:
這類權限必須搭配:
批准不是越少越危險,也不是越多越安全。
重點是批准範圍是否清楚。
Permission 和 Approval 都在決定:
這個操作可不可以執行?
Sandbox 則在處理另一個問題:
即使允許執行,出錯時最多能影響多少?
Sandbox 是隔離的執行環境。
它可以限制:
例如 Coding Agent 可以在一個臨時 Workspace 中修改專案。
即使它刪除所有檔案,也只會影響隔離副本,而不是原始 Repository。
這種設計不是因為我們預期模型一定會犯錯。
而是承認任何複雜系統都可能犯錯,並限制錯誤半徑。
| 機制 | 核心問題 |
|---|---|
| Permission | 這個操作是否被允許? |
| Approval | 是否需要人類做最後決定? |
| Sandbox | 即使執行失敗,影響能否被限制? |
例如 Agent 想執行一個安裝套件的指令:
三者可以同時存在。
允許使用工具
不代表
允許所有參數
允許某個操作
不代表
不需要人類批准
獲得人類批准
也不代表
不需要 Sandbox
Approval 不能取代 Sandbox。
使用者批准一個看似合理的指令,不代表指令執行後一定安全。
Sandbox 也不能取代 Permission。
隔離環境仍然可能包含敏感資料或昂貴資源。
Permission System 最常見的原則是 Least Privilege。
也就是:
Agent 只獲得完成目前任務所需的最小權限。
如果任務只是摘要文件,就不需要寫入權限。
如果任務只是建立草稿,就不需要寄送權限。
如果任務只處理一個 Repository,就不需要讀取整台電腦。
如果子 Agent 只負責搜尋,就不需要繼承父 Agent 的所有工具。
Least Privilege 可以降低:
這也代表 Tool Scope 應該根據任務動態建立,而不是永遠把所有工具全部提供給模型。
當系統開始使用 Subagent 或 Multi-Agent 時,權限問題會變得更複雜。
父 Agent 可能擁有:
但它建立的研究子 Agent,可能只需要網路搜尋與讀取資料。
如果子 Agent 自動繼承所有能力,就會放大風險。
更好的方式是:
父 Agent
擁有完整任務權限
↓
建立子 Agent
↓
只下放完成子任務所需的工具與 Scope
權限應該被明確委派,而不是默認繼承。
當操作被拒絕時,Agent Loop 不一定要直接結束。
系統可以把拒絕原因作為 Observation 交回模型。
例如:
操作被拒絕
原因:目前任務只有唯讀權限
可選擇:
1. 改用不需要寫入的方法
2. 向使用者請求提升權限
3. 產生建議但不實際修改
模型可以根據這個限制調整策略。
這比只回傳「Permission denied」更有用。
但有一點不能讓模型決定:
模型不能因為任務需要,就自行提升自己的權限。
權限變更必須來自可信任的系統或人類。
方便 Demo,但 Production 風險很高。
工具應根據任務、使用者與環境縮小 Scope。
Prompt 可以輔助,不能執行安全規則。
會造成 Approval Fatigue,使用者最後可能不再仔細閱讀。
使用者需要看到真正副作用,不只是內部函式名稱。
高風險操作即使獲得批准,也可能需要 Sandbox。
應該根據子任務進行最小權限委派。
有些限制可以作為 Observation,讓模型改用安全方法。
如果系統還在早期階段,可以先從簡單分類開始。
可以自動執行:
限制 Scope 或記錄 Audit:
需要 Approval,並考慮 Sandbox:
永遠拒絕:
先建立清楚的風險層級,比一開始設計非常複雜的 Policy Language 更實用。
Day 3 的 Tool Runtime 已經可以:
今天加入:
Permission
Approval
Sandbox
Least Privilege
Risk Level
Permission Observation
因此,系統不再只問:
這個工具能不能執行?
而是進一步問:
這個 Agent、在這個任務、對這個資源、使用這組參數,是否應該被允許執行?
一個 Agent 是否可靠,不只取決於它能不能完成任務。
還取決於它犯錯時能造成多少影響。
Permission、Approval 和 Sandbox 分別建立三道邊界:
最重要的原則是:
能力應該由工具提供,權限應該由系統控制,風險應該由隔離環境限制。
下一篇會繼續拆解 Hooks:
如何在不修改 Agent Loop 核心邏輯的情況下,加入驗證、紀錄、阻擋與自訂行為?
完整系列與程式碼範例收錄於 GitHub