iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
AI Engineering

從 Claude Code 到無人值守:我的 AI Agent 工程化實戰系列 第 22 篇

Day 22|無人值守:沒有人可以問的時候

  • 分享至 

  • xImage
  •  

Day 22|無人值守:沒有人可以問的時候

Day 21 停在一個問題:隔離環境裡的執行者碰到拿不定主意的事,它能問誰?答案是沒有人可以問。所以我沒有教它自己拿主意,而是把規則改成:沒有人在的時候,一律不做。攔截層本來會跳出「詢問」的動作,在無人值守模式下直接改判「拒絕」。我原本預期這會讓失敗變多——該做的事被擋掉,總會有幾個任務跑不完。回頭去量,卻量不出這件事:能歸因到這條規則的失敗,紀錄裡找不到;唯一能量的代理指標,甚至往下走。這篇講為什麼量不出來,以及量出來的到底是什麼。

事故:「詢問」在沒有人的地方會變成什麼

Day 8 講過攔截層的三檔:拒絕、詢問、放行,這裡不重講。要看的是中間那檔,它預設了一件事:現場有人可以回答。

前景的 session 有我在,跳出詢問我就點。背景 session 沒有終端機,碰到詢問會停下來等人批准;有人在場時這是刻意的設計,不可逆的動作不在沒人看的時候執行。問題出在根本不會有人來的情境。單輪即滅入口(Day 10 交代過它是為了把觸發權交給外部排程)跑起來時,終端機前沒有人。這時詢問的效果是靜默停等:不報錯、不結束,文件裡記過一次卡了 39 分鐘。更麻煩的是,模型端看不到自己被問過,它不知道自己在等。

所以無人值守模式的定位寫得很明白:這是收緊,不是放寬。單輪即滅入口固定帶這個旗標;2026-09-23 起,隔離環境內的執行也一起帶上。

那它實際觸發過幾次?紀錄資料庫裡,理由帶無人值守前綴的紀錄全期 21 筆,全部是拒絕。但其中 17 筆擠在 2026-09-07 的 9 分鐘內,沒有 session 識別,只有 3 種指令在同一秒成組反覆出現——那是功能上線當天,回歸測試把結果寫進真實紀錄留下的殘留,當時測試還沒有隔離紀錄目錄。排除這 17 筆測試殘留,真實的降級是 4 筆:09-08、09-18、09-20、09-27 各 1 筆,分屬 4 個 session、2 台機器。原本的判定類別是:動到權限設定或攔截層本身 2 筆、不可逆刪除 1 筆、命令替換拆解不完整而保守處理 1 筆。

4 筆只能說「發生過、機制照設計運作」,不能說常發生。還有一個口徑限制:隔離環境內的攔截紀錄留在那個帳號自己的設定目錄裡,沒有進資料庫,那裡實際降級了幾筆我取不到。這 4 筆只代表宿主端。

證據:同一道指令,三種狀態,三條路

先看規則本身。判定結果最後在同一個地方收斂,檢查順序是固定的:先看攔截是否關閉(Day 8 提過的影子模式),再看是否無人值守,最後才輸出決策。

同一道指令在有人在場、無人值守、攔截關閉三種狀態下,依原判定檔位走到的最終處置

三種狀態共用同一個收斂點。有人在場時,詢問會停等並在事後回填等待秒數;無人值守時,詢問改判拒絕,不停等、不回填;攔截關閉時,一律放行,原判會擋的才留紀錄。兩者同時設定,關閉優先。

這張圖回答了開頭的矛盾。降級之後,留下的是一筆普通的拒絕,不掛待回填,也不等任何人。模型收到拒絕,仍然可以把這一輪做完,所以單輪即滅入口的結束狀態不會因此變成失敗。這條規則造成的是「這個動作被跳過」,不是「這個任務失敗」。我預期中的失敗,在結束狀態這一層本來就不會出現。

能量的代理指標是隔離環境裡單輪即滅任務的非 0 結束:以 2026-09-23 加上旗標為界,之前 189 筆裡 6 筆,之後到 10-04 的 568 筆裡 8 筆。比例往下走,但同一次改動也是第一次在那裡裝上攔截層,兩件事分不開。我只把它當成「量不出上升」的佐證,不當成「變好了」的證據。

攔截關閉和無人值守在紀錄上也分得開:資料庫全期記成關閉-詢問的 855 筆、關閉-拒絕的 118 筆,帶無人值守標記的 0 筆。

那詢問在有人的時候要付什麼代價?本機攔截紀錄從 2026-09-09 20:49:25 到 2026-10-04 10:33:56,帶等待秒數的共 461 筆,放行 431、未放行 30。

人工回應等待秒數分五桶的筆數分布,時間窗 2026-09-09 至 2026-10-04

461 筆裡 295 筆在 10 秒內,中位 7 秒、p90 36 秒、最長 604 秒,超過 5 分鐘的 8 筆。以第二幕的截止點(截至 2026-09-20 中午)重跑仍是 368 筆,五桶逐項相同,其餘是之後新增的。

有人在,詢問多半幾秒就結束;但這 461 筆,每一筆都要有人在。最長那筆 604 秒,也在十分鐘左右就有了結果。沒有人的時候,同一個詢問沒有上限,它不會出現在這張分布裡,只會變成一段沒人發現的停頓。

解法:不做,而且要不做得看得見

第一條規則就是開頭那句:沒有人在的時候一律不做。詢問改判拒絕,理由帶上無人值守前綴,照常記錄、照常推播。它把一個懸而未決的狀態,換成一個明確、可查、偏保守的結果。

但有一類動作不能一律不做:提交。全域規則禁止自動提交,一律先審查、等我確認;例外只有四條,其餘一律不適用。跟無人值守有關的兩條,邊界合起來有四道,寫得很硬。第一,只限該輪或該筆工作自己產出的路徑,碰不到別的檔案。第二,只能一般推送,不准強制推送。第三,逐檔加入,禁止整批加入。第四,有收斂上限:審查要收斂到 0 個必修問題才可提交;審查 3 輪還沒收斂,或被標成阻斷,就還原、標成延後,不得提交。

另外兩條例外則明確擋在無人值守外面:一條明文不接受無人值守參數,另一條只在我親自輸入時才適用,模型不能自己呼叫。

我對這組例外的讀法是:它不是在「一律不做」上開洞,而是把「可以做」畫成一個框,框外照樣不做。框的每條邊都可以事後驗——路徑對不對、是不是逐檔、有沒有超過輪數——不靠執行者自己判斷。執行者在框裡不需要拿主意,碰到框外的事,答案永遠是同一個:不做。

新問題:看得見了,可是誰來重試

這條規則換來的是看得見。以前卡 39 分鐘是靜默的;現在被跳過的動作會留下一筆拒絕、一則推播,理由寫明是因為沒有人在。

可是「看見」的主詞還是我,而且要等我回來才算數。推播送出去,我可能在睡覺;紀錄寫進去,我可能隔天才查。被跳過的動作不會自己重試;紀錄只記到拒絕為止,那個動作後來有沒有被補做,不在這份紀錄裡,我也不推算。

無人值守把「卡住」換成了「停下」,這是進步。但停下之後,任務就躺在那裡,等下一個有人在的時刻。單輪即滅入口本來就是為了讓外部排程來觸發;觸發一次之後,下一次由誰決定、失敗之後由誰補,是另一層問題。

被跳過的動作看得見了,可是誰來叫醒它重試?


明日預告:Day 23|排程與看門狗:誰來叫醒它


上一篇
Day 21|跨機器的執行者:同一套規則搬到另一台
下一篇
Day 23|排程與看門狗:誰來叫醒它
系列文
從 Claude Code 到無人值守:我的 AI Agent 工程化實戰 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言