今天在修一套排程系統的重試邏輯時撞到一個坑:離開碼非 0,不代表「這支任務沒做完」。它也可能代表「用來判斷任務有沒有做完的檢查程式,自己出錯了」——這是兩種完全不同的失敗,混在一起處理,會讓系統把自己的 bug 誤判成別人的責任,然後拿去重跑一個其實沒問題的任務。
目錄
症狀:故意模擬一次,離開碼 2 卻不是「沒做完」
這套系統用一支程式判斷「這支任務今天到底做完了沒」,任務跑完之後由排程主腳本呼叫。為了拆解舊邏輯的問題,我今天故意漏帶一個必要參數,手動模擬出「檢查程式自己出錯」的情境:
離開碼=2
訊息大意(改寫過,原始訊息含內部參數名稱):
拒絕判定,沒有指定必要的參考檔案。
範圍不明時撈得到別輪的產出,會把空轉的一輪判成通過。這段訊息裡完全沒有出現「沒做完:」四個字。它講的是「我這個檢查程式沒辦法判斷」,不是「你這支任務缺東西」。但舊版重試邏輯只看一件事:離開碼是不是 0。非 0 就當成「任務沒做完,可以重試」——把檢查程式自己拒絕判斷的訊號,原封不動當成任務的缺失,餵回 prompt 叫任務去補。任務什麼都補不了,因為壞的是呼叫方式,不是任務本身。這是我自己刻意重現出來的情境,用來檢驗舊邏輯撐不撐得住,不是排程當天真的這樣漏帶過參數。
真因:舊版邏輯只把離開碼分成兩類,失敗至少有兩種
舊版重試邏輯只把離開碼解讀成「是 0」跟「不是 0」兩類,不管實際數值是什麼;但「失敗」在語意上至少要分成兩種:受檢物件不合格,跟檢查機制本身跑不動。把兩者都塞進同一種「非 0」判斷,控制流程就沒辦法區分「該重試受檢物件」還是「該修檢查機制」。
同一個形狀今天在覆核過程裡被抓到三次,修了三版。第一版只認「某個特定離開碼」;第二版擴大成「輸出裡有沒有 traceback 字樣」——這兩版都還是在列舉壞掉的長相,漏掉了程式裡另一種寫法:離開碼非 0、但沒有 traceback 的例外拋出,一樣不是「沒做完」,一樣會被舊邏輯誤判。
怎麼修的:用正向特徵,不要列舉負面情況
不再列舉「哪些情況算判不了」,改成用正向特徵判斷「這是不是真的在講沒做完」——檢查程式唯一會印出「沒做完:」的地方是固定的一段邏輯:
非零離開碼,且輸出裡搜不到「沒做完:」這個字串
→ 不是任務的問題,是檢查程式這邊的問題
→ 不要拿這個訊息去重跑任務,先修這邊反過來說:只要輸出裡真的出現「沒做完:」,不管離開碼是什麼,都當成「任務沒做完」處理;其餘一律歸類為「判不了」,開事故單但不重跑任務。這樣以後檢查程式再多長出一種新的例外形狀,也不用回頭再補一次判斷式——不用窮舉錯誤的長相,只需要認一個固定前綴字串。
怎麼驗證:自己重現一次,不是照抄註解
驗證的方式是故意重現症狀,再照修正後的邏輯手動跑一遍:
判定:這是「判不了」,不是「沒做完」→ 不能拿去重跑任務。(修正後的邏輯)拿舊邏輯(非零就是沒做完)套同一組輸出,會得到「沒做完,可以重跑」——也就是把一次單純的呼叫方式錯誤,當成任務缺陷,去重跑一次完全正常的任務。
| 同一組輸出 | 舊邏輯:只看離開碼 | 新邏輯:找「沒做完:」 |
|---|---|---|
| 離開碼 2,訊息是「拒絕判定,沒有指定必要的參考檔案」 | 非 0 → 任務沒做完 → 重跑任務 誤判 | 找不到「沒做完:」→ 判不了 → 開事故單,不重跑 |
| 離開碼非 0,訊息裡含「沒做完:…」 | 非 0 → 任務沒做完 → 重跑任務 判對了 | 找到「沒做完:」→ 任務沒做完 → 重跑任務 |
| 離開碼非 0,例外拋出但輸出裡沒有 traceback | 非 0 → 任務沒做完 → 重跑任務 誤判 | 找不到「沒做完:」→ 判不了 → 開事故單,不重跑 |
列舉壞掉的長相,永遠會漏下一種。
同一天出現第二次,不是巧合
同一輪修復裡還撞到一個形狀很像的坑:排程用一個全域變數在多個任務之間傳遞「上一次為什麼沒做完」,但只有失敗那條分支會寫值,成功或別種失敗都不清空。結果是甲任務失敗、乙任務成功,如果乙之後的程式碼路徑又去讀這個變數,讀到的會是甲留下的舊值,而且不會報錯,看起來完全正常。修法是同一個原則:進函式第一行就無條件清空,不假設「沒被寫到就代表沒事」。
兩個坑的共同點:把「例外情況」當成邊角案例去列舉,而不是設計一個正向的、可以辨識的訊號。列舉容易漏掉下一種形狀,正向特徵比較不會。
下次怎麼認出這個坑
只靠「離開碼是不是 0」這種成功/失敗二分、又沒有再往下辨識失敗類型的重試設計,就是這個坑的早期徵兆——不限於這一套系統,任何跑外部檢查程式、依離開碼決定要不要重試的自動化流程都可能撞到。導入 AI agent 自動化系統之前要先想清楚的現實問題裡也談到類似的判斷:工具好不好用,很多時候不是看它平常跑得順不順,是看它出錯的時候,系統分不分得清楚「錯在哪一層」。
這篇文章由 AI 協助撰寫。裡面描述的情境與修法邏輯都是今天在自己機器上實際跑出來、驗證過的,草稿由 AI 起草後,對照原始紀錄逐句核對過。
