Coding agent 會自己追 PR,人類該設計的是例外
想像一個很普通的 pricing page PR。Reviewer 要求補上 loading state 的測試,coding agent 改完、重跑 CI,這段工作沒有太多爭議。接著它遇到 merge conflict,衝突檔案剛好包含 pricing schema;另一則 comment 則要求刪掉頁面上的法律免責文字。
畫面上可能都只是紅色項目,工作的性質卻完全不同。前者也許能依既有規則修復,後兩者牽涉資料契約、產品承諾與責任歸屬。讓 agent 繼續猜,風險會被「仍在處理」的狀態蓋住;每逢 check 失敗就通知工程師,所謂自動化又只剩下另一種打斷人的方式。
VS Code 1.136 裡仍在 Preview 的 Agent Merge,已經能讓 agent 持續處理 review feedback、failed checks、merge conflicts,並重跑 workflow,直到 PR 進入 ready to merge 的狀態。它改變了 PR 收尾的節奏:原本由人逐次處理的零碎工作,開始變成一個長時間運作的修復迴圈。
當迴圈可以自己跑,團隊就需要一個能濾掉一般進度、只保留人類判斷的「例外收件匣」。
PR 收尾其實有三種工作
Agent 執行中的一般進度、可依規則修復的 blocker,以及需要人承擔的例外,不該混在同一條通知流裡。
Queued、running、正在重跑 checks 等狀態,留在活動紀錄就夠了。格式錯誤、可重現的單元測試失敗,或修改範圍明確的 review comment,可以交給 agent 在受限條件內處理。需求有歧義、測試結果與產品預期互相衝突、修改碰到敏感路徑,或需要新的權限時,工作才應停下來進入人的 inbox。
分類不能交給 agent 依「看起來好不好修」自行決定。團隊得先寫出 policy:哪些檔案可改、哪些驗證一定要重跑、什麼情況要找 domain owner,以及哪些決定不接受自動代行。
這個區分看似保守,實際上反而讓 autonomy 比較能成立。Agent 不必為每個機械性步驟等待確認,人也不會在最後才發現綠燈是靠擴大修改範圍換來的。
自動修復需要預算
長時間迴圈最容易製造一種假進度:agent 修掉一個失敗,另一個 check 又紅了;它換個做法再試,原本通過的測試卻再次失敗。系統一直有動作,PR 沒有更接近可接受的結果。
每一類 blocker 都應有 retry budget。除了次數上限,它還要列出每次允許碰觸的範圍、必須重新取得的證據,以及停止條件。比方說,agent 可以針對同一個 loading-state test 嘗試兩次,但不能因此修改 pricing schema;第二次仍失敗,就把目前 diff、測試輸出與兩次嘗試一起交回來。
預算耗盡後停下來,不代表 agent 失敗。這表示工作已經超出原本授權的機械性修復範圍,需要新的判斷。系統若沒有明確的停止語意,只要還能生成下一個修法,就會把重試誤當成進度。
例外卡不是縮短版聊天紀錄
工程師收到一句「CI 又失敗了」,仍得自己打開 PR、找 commit、翻 check log,再猜 agent 已經改過哪些地方。把完整 transcript 丟過來也沒有好多少,因為接手的人得從對話裡重建工作現場。
一張可處理的例外卡至少需要這些資料:
blocker 來自哪個 check、review comment 或 conflict
它綁定的 PR、current commit 與受影響檔案
agent 已嘗試的動作、目前 diff 和驗證結果
這次需要哪一位 owner 做什麼決定
可選的最小修法、可能風險與決定期限
Revision 尤其不能省略。GitHub 的 Copilot code review approval 可以由管理者依 enterprise、organization 或 repository 層級啟用,也能限制允許核准的檔案路徑;新的 commit 會讓既有 approval 失效。這項設計提醒了一件很實際的事:綠燈、review 與批准都只對特定版本有效。
若例外卡沒有 current commit,人按下的就不是一個可驗證的決定,只是對過期畫面的信任。
介面可以動態,事實來源不能漂移
例外收件匣不必永遠是一張固定表格。簡單的測試失敗適合顯示 diff 與重跑按鈕;涉及 schema 的 conflict,可能需要並排呈現資料契約、受影響路徑與 owner;產品文案爭議則應把原始 comment、目前文字與批准選項放在一起。團隊若要比較動態 status card、decision panel 或 agent-native UI 的做法,可以從生成式 UI 資源找現成的 renderer、SDK 與介面模式作為研究材料。
但生成介面只能整理可信系統交付的內容。Exception type、revision、check 結果和權限狀態,仍要來自 PR、CI 與 repository policy。介面若自行猜測某個 conflict 屬於低風險,或把 stale approval 畫成有效,再漂亮的 decision panel 都只是在加速誤判。
這也是「agent 建議」和「人的決定」必須分欄呈現的原因。Agent 可以提出最小修改方案,附上預期驗證與 rollback;owner 批准的則是具體產品行為、修改範圍或剩餘風險。兩者不能因為出現在同一張卡上,就被混成一個自動動作。
通知應該意味著需要決定
許多 agent 工作流的通知設計,仍沿用聊天工具的思路:有新動作就顯示,有狀態改變就推播。Agent 一旦開始追 PR,這會迅速變成噪音。每次重跑、每次補 commit、每次 check 轉換狀態都叫人回來看,人的注意力只是被機器執行節奏牽著走。
更有用的規則很單純:只有 scope 擴大、證據衝突、重試預算耗盡、等待 owner,或需要新權限時,才進入例外收件匣。其他進度保留在 log,讓需要稽核的人能回看,但不要求即時介入。
如此一來,人打開 inbox 時,看到的不是 agent 做了什麼,而是現在有哪個決定沒有人能代替他做。
Ready to merge 仍要留下決策收據
Agent 把所有可處理項目跑完後,最後交付的內容不該只有 completed。一份可接手的收據要列出 current head、已解決與未解決的 blockers、checks 結果、review 狀態、approval 是否仍有效,以及還有哪些決定尚未完成。
Ready to merge 表示修復迴圈走到了某個可交接點,不等於程式已被證明正確,也不會自動取得 merge authority。最終由誰合併、是否進 merge queue,仍由 repository policy 決定。
Coding agent 愈能持續工作,人愈不需要監看它的每一步。不過,人也不能只在最後替一片綠色背書。可重複、可驗證的修復可以放心交給 agent;超出範圍的工作,應帶著最新 revision、證據與清楚選項回到人的桌面。這樣的分工很清楚:agent 負責執行,人只在例外出現時接回責任。
Source notes