AI agent 需要的不是確認按鈕,是看得懂的批准邊界
最容易讓人放鬆的,往往是一個看起來很正常的確認按鈕。
Agent 跳出提示,問你要不要修改某個檔案。路徑看起來在專案裡,檔名也合理。你手上還有別的事,心裡大概只想趕快繼續往下跑,於是按下 Accept。
這一刻很像 human-in-the-loop。
但我越來越覺得,這個詞太容易被講得太便宜。有一個人按過確認,不代表那個人真的理解自己批准了什麼。尤其當 agent 可以改本機檔案、跑命令、讀 repo、開瀏覽器,甚至同時處理幾個長任務時,確認按鈕本身不夠。
真正重要的不是「有沒有確認」。
真正重要的是:人按下去之前,看不看得懂那個行動的真實邊界。
## 有確認,不等於有授權
這件事在 coding agent 上特別明顯。
傳統的自動補全大多只是建議幾行 code。它煩的時候會打斷你,但它通常不會自己去改一串檔案、跑一個安裝腳本,或把某個設定寫到你沒注意的位置。
Agent 不一樣。
它會把「幫我修一下」理解成一段工作流程。它可能先讀檔,再改檔,接著跑測試,看到錯誤又去查另一個檔案。這種能力很有用,也正是大家開始認真使用它的原因。
問題是,一旦工具從建議變成行動,授權介面就變成工作流的一部分。
假設畫面上顯示的是 `./config/settings.json`,但實際寫入的是 symlink 指向的另一個位置。假設 agent 在你按 Accept 之前就已經把內容寫進去了,按 Reject 只是幫你 undo。假設它要跑的 command 看起來像一般 setup,實際上會碰網路、讀環境變數、改 shell 設定。
這些情況裡,確認按鈕還在。
可是它已經不像授權,比較像一個讓人安心的儀式。
我不是說確認提示沒有用。相反,它很重要。只是它不能只問「要不要」。它要先讓人知道「到底是什麼」。
## 路徑要顯示真實目標
對開發者來說,路徑很容易被當成安全感。
看起來在專案裡,就放心一點。看起來是暫存檔,就放心一點。看起來不是 `.ssh`、不是 secret、不是全域設定,就放心一點。
但 agent approval 的第一個基本要求,應該是顯示 resolved path,而不是只顯示一個漂亮的相對路徑。
如果檔案經過 symlink、alias、workspace mount,或任何會讓人誤判範圍的轉接,批准畫面應該直接講清楚:你看到的路徑是什麼,實際目標在哪裡,是否離開目前 repo,是否碰到使用者家目錄或敏感位置。
這聽起來很細。
但安全感本來就常常死在這種細節裡。人類 review 時會看 diff,會看檔名,會看目錄。工具如果在這一層給人一個不完整的表示,後面再多問一次「確定嗎」也補不回來。
小團隊其實可以先用很樸素的規則處理。
陌生 repo 裡,agent 只能先讀不能寫。
跨出 workspace 的檔案修改,一律停下來人工確認。
所有 symlink resolved target 要顯示出來。
修改全域設定、憑證、shell profile、package manager 設定時,不允許一次批准整包。
這些規則不酷,但很實際。它們讓「批准」從一個情緒性的按鈕,變成一個有資訊的邊界。
## 批准應該發生在改變之前
另一個容易被忽略的問題,是批准的時機。
如果 agent 先把檔案寫了,再跳出畫面問你要不要接受,那這不是授權流程。這比較像 undo 流程。
Undo 當然有價值。很多編輯器和工具都靠這件事讓使用者放心探索。但在 agent 工作流裡,undo 不能取代 approval。原因很簡單:有些事情不是改回檔案就結束。
跑過的 script 可能已經建立快取。
安裝步驟可能已經下載套件。
測試可能已經碰到本機服務。
命令可能已經讀過環境變數。
瀏覽器操作可能已經送出請求。
檔案 diff 可以回復,不代表副作用不存在。
所以比較好的設計不是「先做,讓使用者接受或拒絕結果」,而是把高風險動作拆開。低風險的讀取可以自動進行;要寫入、執行、連網、讀 secret、改全域狀態時,先停。停下來時,不只顯示命令本身,也要顯示預期效果和影響範圍。
這會讓 agent 看起來慢一點。
但那個慢,是工程流程需要的慢。就像 production deploy 前要看變更清單,不是因為大家喜歡儀式,而是因為某些門檻本來就應該在狀態改變前出現。
## 命令比文字更需要上下文
很多 approval UI 對檔案 diff 比較友善,對 command 卻很粗。
它可能只顯示:
```bash
npm install
```
或:
```bash
./setup.sh
```
對熟悉專案的人來說,這還勉強能判斷。對 agent 正在處理的陌生 repo 來說,這其實資訊很少。
`npm install` 會不會觸發 lifecycle script?
`setup.sh` 會不會 curl 一段東西下來執行?
測試指令會不會啟動服務、連資料庫、碰網路?
錯誤訊息看起來像 DNS 問題時,agent 會不會照著文件去查一個外部地址?
我不是要把每個 command 都妖魔化。開發工作本來就需要執行命令。只是 agent 的「helpful」會讓它比人更願意照著錯誤訊息往下試,而這正是風險開始變難看的地方。
人類工程師看到一個陌生 setup script,多少會有一點警覺。Agent 則可能把它當成完成任務的下一步。
所以命令批准畫面至少應該回答幾個問題:
- 這個 command 會在哪個目錄執行
- 它可能讀寫哪些檔案或目錄
- 它是否需要網路
- 它是否可能讀到 secret 或環境變數
- 它失敗時,agent 會不會自動嘗試替代命令
- 這一步完成後,reviewer 可以檢查什麼證據
這些資訊不一定都能自動推得很準。但推不準時,工具也應該承認不確定,而不是把不確定藏在一個乾淨的 Confirm 按鈕後面。
## 長任務會放大壞邊界
如果 agent 只做三分鐘的小修,approval boundary 不清楚已經很麻煩。
如果它開始做一小時、三小時、八小時的任務,這個問題會變成日常管理成本。
現在很多人不只開一個 agent。有些工作流會同時跑幾個 session,有些團隊會把固定指令寫成 skill,有些任務已經接近「交給它一段時間,晚點回來看結果」。
這不是未來想像。這已經是很多 builder 正在摸索的工作方式。
多 agent 和長任務的麻煩,不只是花 token,也不是只怕它寫錯 code。真正的麻煩是中間狀態太多。如果每一段都沒有清楚邊界,最後 reviewer 看到的只是一包結果:一些 diff、一串輸出、一個看似合理的摘要。
這很難 review。
比較成熟的做法,是把長任務拆成可以批准、可以停止、可以回放的小段。
先只讀 repo,整理計畫,不改檔。
接著列出會碰到的檔案、命令和風險。
批准第一個最小修改,不准順手重構。
跑指定測試,失敗兩次就停下來交代。
每一段都留下命令、diff、判斷理由和不確定點。
這樣做會讓 agent 少一點魔法感,但多很多可接手性。
我會把這當成團隊導入 agent 的成熟指標。不是 agent 能不能一路跑到底,而是它跑到任何一個中間點時,下一個人能不能看懂、接住,必要時把它停掉。
## 小團隊先寫工作規則,不要只寫 prompt
很多團隊開始共享 agent 使用方式時,會先寫 prompt 範本。
請你謹慎。
請你像資深工程師。
請你不要 overengineering。
請你先思考再行動。
這些句子不是完全沒用,但不夠。
真正有用的是工作規則。尤其是跟批准邊界有關的規則。
例如:
- 陌生 repo 預設只讀,不跑 setup
- 任何網路請求都要先說明目的
- 不讀 `.env`,除非任務明確需要且人類批准
- 不修改 shell profile、SSH key、global git config
- 不把測試失敗自行擴大成大型重構
- 每次交付都附上改檔清單、命令紀錄、測試結果和剩餘風險
- 如果 approval 畫面無法說清楚真實目標,預設拒絕
這些規則不像 prompt 技巧,卻更接近工程。
因為它們處理的不是 agent 會不會講漂亮話,而是它被允許做什麼、什麼時候要停、什麼證據可以讓人 review。
對小團隊來說,這比追最新工具更重要。工具會變,模型會變,CLI 介面會變。但團隊對權限、執行、review、回滾的基本態度,應該要比工具穩。
## 最後要問的不是有沒有按過 Accept
我不覺得 agent approval 的答案會是一套完美 UI。
有些資訊很難完整顯示。命令副作用不一定能準確預測。太多提示會讓人疲乏,最後又變成一直按確認。安全和效率之間也一定有取捨。
但這不代表我們只能接受形式上的 human-in-the-loop。
至少,團隊可以開始把問題問得更準。
不是問:這個工具有沒有 confirmation prompt?
而是問:它顯示的是不是真實目標?
不是問:有沒有人按過 Accept?
而是問:那個人是否看得懂實際被批准的行動?
不是問:agent 最後有沒有完成任務?
而是問:中間每一步是否能被停止、檢查和回放?
AI agent 進入日常開發後,批准邊界會變成一種產品介面,也會變成一種團隊流程。
如果人只是靠近按鈕,卻看不懂按鈕後面發生什麼,那不叫 human-in-the-loop。
那只是 human-near-the-button。