排程技能失敗後的重試策略,指的是為「失敗」預先分類並訂出對應反應的一套規則,核心是兩個機制的組合:retry policy(要不要重試、重試幾次、間隔多久)跟 fallback instruction(重試用盡後或判定不該重試時該怎麼收尾)。這跟一般理解的「失敗要發通知」不是同一件事——單純發通知只處理了「人什麼時候該知道」,沒有處理「知道之前,系統該不該先自己試著解決」,這正是多數排程任務設計裡被跳過的一步。
這件事會被需要,是因為排程任務跟人手動操作有一個根本差異——人遇到暫時性錯誤時,通常會憑直覺再試一次,這個判斷幾乎不用思考;但排程任務沒有人在旁邊,遇到任何失敗都只能照寫死的邏輯反應。如果邏輯是「失敗就通知」,系統會把本來 15 分鐘內就會自己好的暫時性問題,也一律當成需要人立即處理的事件,長期下來會製造大量假警報,讓值班的人對通知逐漸麻木,等到真正該處理的結構性問題發生時,反而因為「上次也是誤報」而被拖慢反應。retry policy 跟 fallback instruction 存在的理由,就是把人在遇到暫時性錯誤時那個近乎直覺的判斷,寫成系統可以自動執行的固定規則。
實務上要處理三件事。第一,把常見錯誤訊息分成暫時性與結構性兩類:逾時、連線中斷、5xx 伺服器錯誤歸暫時性;認證失敗、4xx 請求錯誤、資料驗證失敗歸結構性,這份分類清單直接寫進排程任務的錯誤處理指示裡。第二,針對暫時性失敗設定重試規則,例如指數退避的等待間隔(1 分鐘、5 分鐘、15 分鐘)與最大重試次數(通常 3 次),三次都失敗才升級通知人。第三,針對結構性失敗跟重試用盡的情況,明訂 fallback instruction:是切換備用資料來源、產出標記不完整的部分結果、還是直接停下等人,這個決定要看任務本身能不能接受「先給一份不完整的結果」還是必須完全正確才能用。三者合起來,整份錯誤處理邏輯就能在排程任務第一次失敗前先設定好,不必每次失敗都臨場決定。
對你來說,這套設計把「值班的人半夜要不要被吵醒」從臨場判斷變成事先訂好的規則,直接影響的是團隊對通知的信任度——通知太頻繁又常常是誤報,人會開始略過通知,這比完全沒有通知更危險,因為系統看起來在運作,實際上警訊已經失效。設定成本是一次性的,通常一到兩小時就能訂出分類清單跟重試規則;後續維護則是每次遇到新的錯誤類型,補進分類清單裡,讓規則持續反映真實情況。真正該留意的是:不要把 fallback instruction 設計成「靜默失敗」,也就是重試用盡後系統自己停下來卻沒有任何人知道,這比暴力重試更危險,因為問題會一直存在卻沒人發現,直到有人發現任務其實已經好幾天沒真的成功過。
凌晨三點,排程好的月結對帳任務因為對方 API 短暫逾時失敗了。系統可以做兩件事:默默重跑一次,通常第二次就成功;或者立刻發通知叫醒值班的人。多數團隊在設計排程任務時只想到「失敗了要通知」,卻沒想清楚「通知之前,要不要先自己試著救一次」——這個沒想清楚的空隙,決定了你團隊的手機半夜到底會不會響。
第一種是暫時性失敗:對方伺服器逾時、網路瞬斷、API 那端剛好在維護——這類失敗的特徵是「等一下再做同一件事,通常就會成功」,本質上跟你自己重新整理一次網頁沒有兩樣。第二種是結構性失敗:認證憑證過期、對方 API 格式改了、輸入資料本身就是錯的——這類失敗的特徵是「不管重跑幾次,結果都一樣」,因為問題不在「這次運氣不好」,而在「哪裡真的壞了」。
把這兩種混在一起處理,是多數排程任務設計失敗的起點。對暫時性失敗保持沉默、默默重試,是合理的;但如果對結構性失敗也套用同一套「先重試再說」的邏輯,只會讓系統對著一個永遠不會好的錯誤,不斷徒勞地敲同一扇打不開的門,直到真正該被叫醒的人,因為前面太多次空歡喜的「重試中」通知而選擇忽略,錯過了唯一重要的那一次。
這正是 retry policy(重試策略)要解決的問題:明訂遇到失敗時,重試幾次、每次間隔多久、以什麼方式遞增等待時間。常見做法是指數退避——第一次等 1 分鐘,第二次等 5 分鐘,第三次等 15 分鐘,三次都失敗才升級通知人。這個設計的用意是:給暫時性問題足夠的時間自己恢復(對方伺服器維護通常不會超過 15 分鐘),但不會無止盡地空等,也不會第一次失敗就立刻吵醒人——多數暫時性問題,其實在第二次重試前就已經自己好了。
但 retry policy 只回答「重試幾次」,回答不了「這個失敗到底該不該重試」。這就是為什麼它必須跟另一個機制搭配使用。
fallback instruction(備援指示)處理的是重試策略用盡之後、或一開始就判定是結構性失敗時該怎麼辦——是要切換成備用資料來源、還是先產出一份標記「本次資料不完整」的部分結果、還是直接停下來等人處理。沒有這個機制,重試策略用盡後系統往往就是靜默停擺,沒人知道任務其實已經放棄了。兩者合起來才是完整的失敗處理:retry policy 決定要不要再試一次,fallback instruction 決定試到最後還是不行時該怎麼收尾。
要區分兩種失敗,關鍵在錯誤訊息本身能不能被歸類。逾時、連線中斷、對方回傳 5xx 系列的伺服器錯誤,大致可以歸為暫時性;認證失敗、對方回傳 4xx 系列的請求錯誤、資料格式驗證失敗,大致可以歸為結構性。把這個分類邏輯寫進排程任務的錯誤處理指令裡,讓 Claude 依錯誤類型自動決定是重試還是直接升級,而不是每種失敗都套用同一套反應。
沒有 retry policy 的代價是兩種:要嘛半夜三點為了一個 15 分鐘後就會自己好的暫時性問題叫醒人,長期下來養成「收到通知先不管,反正等一下就好了」的心態;要嘛完全沒有重試機制,暫時性問題直接被當成任務失敗上報,產生大量原本不需要人處理的雜訊。真正該付出成本的,是設計 retry policy 跟 fallback instruction 這一次性的工作,通常一到兩小時;換來的是往後每一次失敗,系統都用同一套邏輯自動判斷該不該吵你,而不是每次失敗都由當下值班的人臨場判斷,判斷標準忽鬆忽緊。真正該花人力的,是那些真的壞了、重試也沒用的結構性問題,而不是把人力浪費在確認「這次是不是又只是網路抖了一下」。