systems

當結束碼開始說謊:一個響了七天沒人聽懂的警報

自動化系統的靜默故障:工具答對了卻回報失敗、警報每天都響卻喊錯名字。一次除錯的完整推理過程,以及三個可以直接拿去查自己系統的檢查項。

  • automation
  • debugging
  • reliability

一個人在燈下專注端詳一根羽毛,身後陰影裡停著一整車堆得極高的柴,近到快碰到他的背,而他毫無所覺

明足以察秋毫之末,而不見輿薪。 —— 《孟子・梁惠王上》(約公元前 300 年)

我叫一個 AI 命令列工具回答一個字。它回了 PONG,完全正確。

然後它告訴我,它失敗了。

三個訊號,三種說謊方式

那天我在查一件小事:為什麼派給 grok 的工作老是很慢。我寫了一支計時的小程式,同一句話跑七次,記錄兩個時間點——答案什麼時候出現,程序什麼時候結束。

七次的答案全對。但那兩個時間點之間的落差,是這樣的:

次數答案出現程序結束
1131 秒十分鐘上限,我砍的
2102 秒十分鐘上限,我砍的
3549 秒十分鐘上限,我砍的

答案一分半到兩分鐘就寫進輸出了。然後程序就掛在那裡發呆,直到被我殺掉。

七次裡有兩次自己結束了。其中一次回報成功,另一次回報失敗——而那次「失敗」的答案,跟其他六次一模一樣,都是正確的 PONG。

所以三個我平常拿來判斷「做完沒」的訊號,全部不可靠:程序活著不代表還在工作,程序死了不代表工作完成,回報失敗不代表答案是錯的。

真正的兇手,是一個「守規矩」的動作

繼續往下挖,找到一個更難看的東西。

我另一支腳本會明確指定要用哪個模型。這是我自己訂的規矩——排程一定要釘死模型版本,這樣供應商偷偷換掉模型的時候才看得出來。

我把這個參數拿掉試了一次,一百四十秒就答完了。加回去,三百秒零輸出。

換一個模型名試?一樣卡死。換成它自己的預設模型呢——就是那個你什麼都不寫它就會用的那個?

也卡死。

同一個模型,你不講它會用,你講出來它就死。而且錯誤訊息是空的:沒有警告、沒有說參數不對、沒有任何一個字。它就是停在「收到你的問題」那一步,不動了。

這件事最刺人的地方在於:這個參數是我因為守紀律才加的。不加的人沒事,加的人全死。

七天沒人發現,因為警報喊錯了名字

我去翻那支腳本的日報,四十三天份。

它從八月十四號開始出現空跑,中間好了一天,然後從八月十七號到八月二十一號連續五天,每一格都是空的。

警報有響嗎?有。而且七天每天都響。

問題在它喊的內容。那行字寫的是「偵測到模型漂移」——這句話的意思是「AI 的回答變了,去查一下會不會影響結論」。

實際情況是「一個字都沒收到,工具壞了」。

前者要去查判斷,後者要去修管線。兩件完全不同的事,共用同一個詞。所以每天看到那行警報的人,都不會想到要去看是不是連線都沒通。

警報有響,但沒有人聽得懂它在說什麼。這跟沒響的差別,比想像中小。

最難看的一段:我自己的腳本也在說謊

修到後面,我派了一個任務出去,順手看了一眼結果:

✅ 完成 902s,產出 162 位元組

打勾,完成,有產出。看起來很好。

但那個任務其實徹底失敗了。162 位元組的內容是這樣一句話:「我會先找一條可用的管道,然後只試那一條。」

一句開場白。它講完這句就卡住了,七分鐘沒動,跑滿逾時被砍。

我自己寫的驗收邏輯是「只要產出超過門檻就算成功」,門檻是一個位元組。所以一句開場白足以讓一個徹底失敗的任務被標成完成。

而且那行字裡其實有證據——「完成 902s」後面那個空括號,本來應該填「完成原因」,只有正常收工才會有值。逾時被砍的時候那裡是空的。

證據就在畫面上,但沒有人會去盯一個空括號。

你怎麼知道你的自動化還活著

寫到這裡你大概會想:這是他們家的工具有臭蟲,跟我沒關係。

我想講的不是臭蟲,是那個形狀。

上面三件事——明確指定版本、等程序結束、看回傳碼——每一件單獨拿出來看都是好習慣,是教科書會教你做的事。它們同時也是這次故障的入口。

而它們有一個共同點:失敗的時候不會叫。

系統不是不會壞,是壞掉的時候長得跟正常一樣。你每天看著綠燈,綠燈是真的亮著,只是它量的東西早就跟你關心的事情脫鉤了。

所以問題不該問「有沒有警報」,該問「這個警報有沒有可能永遠不響」。

三個可以今天就去查的東西

第一,找出你所有「連續亮了五天以上」的警報。天天亮的警報等於沒有警報——它要嘛是壞的,要嘛已經被你的眼睛自動略過。兩種情況都要處理。

第二,去看你的報表產生器裡,有沒有把「讀不到」寫成 0 的地方。程式碼裡那種「找不到就給預設值」的寫法,就是「一個字都沒收到」被讀成「這個值是零」的入口。這正是我那個「模型漂移」遮住「工具沒回應」的同一種病。

第三,故意讓你的工具逾時一次,看它會不會回報成功。這件事只要五分鐘,而且結果通常很難看。我就是這樣發現自己的腳本在說謊的。

帶得走的一件事

一個訊號要能當證據,前提是它有可能說「不」。

永遠回綠燈的檢查,跟沒有檢查,資訊量是一樣的。差別只在前者會讓你安心。

今天可以做的練習:挑一個你依賴的檢查——健康檢查、月結對帳、每週報表都行——問自己一句「什麼情況下它會亮紅燈」。如果你想不出來,或者你想得出來但從來沒真的發生過,那就去製造一次。

弄壞它,看它會不會叫。它不叫,你就找到了一個一直在騙你的東西。