
品質委員會的資料裡有一張年度統計:各單位的異常事件通報件數。異常事件通報就是你的 incident report——任何一件不該發生卻發生的事,不管有沒有造成傷害,都填一張送出來。
那年的表上,甲單位的件數是全院前幾名。乙單位掛零,整年一件都沒有。
會議上有人說了一句很自然的話:「乙單位很穩定嘛。」
我說,這張表上我唯一擔心的就是乙單位。
會議室安靜了幾秒。有人以為我在找碴。但這不是修辭,是這份工作最核心的一個判斷:通報數高的單位不是比較危險的單位,是比較看得見的單位。
一個整年沒有任何事件的單位只有兩種可能:它真的完美,或者它發生的事沒有被寫下來。在一個每天有數百人走動、數千個決策在發生的地方,第一種可能性小到我不會賭。
後來這件事的處理方式,也不是去查乙單位有沒有隱匿。是先去問:他們的通報表要填幾分鐘、送出去之後會不會被主管叫去問話、上一次有人通報之後發生了什麼。
因為一個沒有訊號的系統,問題通常不在訊號源,是傳輸路徑上有人把 alert 關掉了。
外面的人對品質管理最常見的想像,是我們在追求完美:訂高標準、稽核、要求大家做好一點。
不是。至少不是我每天在用的那個版本。
先把話說準:品質的定義我沒有要動它——符不符合需求、適不適用,那是品質,教科書第一頁就寫在那裡,而且沒寫錯。團隊日常還要關注另一件事,品質系統的健康程度:
一個品質系統健不健康,不看它多久出一次錯,看它出錯的時候多快會有人知道。
理由不玄:出錯的頻率你壓不到零,但「知不知道」是你控制得了的。
這兩件事常常被混成一件,而混在一起的代價很具體:你會拿「出錯次數」當品質指標,然後獎勵到那些不講的人。同一個誤置,在你們那邊叫做用 incident 數量考核團隊。
一家醫院不可能不出錯。每天上千次給藥、上百次交班、無數個要在資訊不完整的情況下做的判斷,任何一個環節都有翻掉的可能。所以我們不追求零錯誤——追求零錯誤的結果從來不是零錯誤,是零通報。
這句話有半邊常被忽略:要看得見,系統得先「壞得起來」。
壞得起來的意思是,講出一件事出錯的成本,必須低於把它藏起來的成本。醫療品質有一個講了幾十年的原則叫非懲罰性通報——通報的目的是取得訊號,不是找出誰要負責。這件事很少有醫院敢說自己做到了,但方向是對的,而且你們有一個一模一樣的東西:blameless postmortem。
兩邊要對抗的是同一件事:當講出問題的人會付出代價,訊號就會消失,而系統會看起來變好。
所以我看一個品質系統健不健康,第一個看的不是指標數字,是壞消息傳上來要經過幾個人、每一關會不會被稀釋。
我要的不是一個不出錯的單位,是一個會早一點噴、講得清楚、而且噴在有人 on-call 的地方的單位。
現在講接縫在哪裡。
把「看得見」拆開,它其實是三層,而且是串聯的:
醫院的前兩層,二十年前就資訊化了。線上通報表單、自動路由到品管室、依嚴重度分流、逾期未結案自動催辦。這一段做得相當好,好到通報單進來的速度,遠遠超過有人把它們逐份讀進去的速度。
第三層還是人。而第三層是整條鏈路吞吐量最低的一層。
於是出現一個很荒謬但很常見的結果:前兩層越有效率,第三層堵得越嚴重。蒐集自動化的成果,是製造了一個沒有人有空逐份細讀的資料池。
我們花二十年做完的,是把 log level 從 WARN 調到 DEBUG。第三層還是一個人在讀。
「看不見」於是變成「來不及看」。而這兩件事,在出錯的那一刻效果一樣。
一則通報的內容是一段自由文字:誰、在什麼情況下、做了什麼、後來怎麼處理。它是不是一件該往下查的事,取決於讀完之後的判斷。通報單上沒有一個欄位可以拿來設 threshold——要判的東西根本不是數字。
所以接縫的位置非常清楚:第一層第二層是資料工程問題,早就解決了;第三層是判準問題,而判準寫不下來的時候,整條可觀測性就斷在最後一哩。*(判準為什麼寫不下來,Day 1 那條形式化極限已經談過,這裡不重複。)
要把第三層接上資訊流程,我後來的做法是先要求三件事,順序不能換:
一、每一則觀察必須落成離散結果。 是、否、或者「判不出來」。一段文字描述不能當輸出——它沒辦法被統計、沒辦法被比較、沒辦法在三個月後告訴你趨勢有沒有變。
二、每一個判定必須附理由。 理由不是給讀的人看心安的,是留給稽核的痕跡。判錯的時候,理由會先壞——結論還碰巧對、但理由已經在胡說的情況非常多,而那是最早的預警。
三、判準要有版本。 因為判準會改,而改了之後,前後兩段時間的數字就不能直接比。我們修過稽核條目之後,那條趨勢線其實已經斷了一次,只是常常忘記在圖上標一刀——就像改過告警規則之後,前後的告警數放在同一張圖上其實沒有意義。(判準怎麼版本化是第五週的事。)
這三件事對你來說可能理所當然,但請注意它們原本都不存在。原本的第三層是一個人讀完通報單,在腦子裡判斷完,然後在會議上講出來。沒有離散結果、沒有留下理由、沒有版本。
把一段人的判斷接上資訊流程,第一步從來不是接 API,是先把這個判斷變成一個有輸出格式的東西。
到這裡為止都還是醫院的事。但這篇真正想講的是下面這段。
醫院需要「壞得起來要看得見」,是因為它是一個必然會出錯的系統。你上個月接進 pipeline 的那個模型也是。差別在於,醫院花了幾十年建立通報機制;而模型上線那天,它的通報機制是零。
傳統系統壞掉的時候會告訴你。它噴 exception、它 timeout、它回 500、它 return null。你的監控接得住這些,原因很單純:失敗的形狀跟成功的形狀不一樣。
LLM 不是這樣。
它壞掉的時候,會給你一段結構完整、欄位齊全、語氣自信的答案。它不會停、不會空白、不會告訴你它剛才在猜。schema 驗證過得了,下游程式收得很開心。
這是我在這件事上最不安的地方:
LLM 系統的預設狀態是零可觀測性。它的失敗形態,長得跟成功形態一模一樣。
你的 pipeline 不會紅燈,dashboard 全綠,而它可能已經連續三個星期,把同一類通報單穩定地判反。等到有人回報「這個結果怪怪的」,中間那幾批已經發出去了。

所以昨天那句話今天要收在這裡:一個看不見自己何時出錯的系統,沒有資格上線。這句話對醫院成立,對你的服務成立——對一個用自然語言下判斷、而且永遠會給你答案的模型,它成立得更兇。
既然它不會自己喊痛,就只能設計成讓它每次都留下可以被檢查的痕跡。所以我要的從來不是一個結論,而是一組欄位,每一個欄位都是為了讓某一種失敗變得看得見:
| 輸出欄位 | 它讓什麼變得看得見 |
|---|---|
| 判定結果 | 大家唯一想要的東西,也是唯一沒有觀測價值的東西 |
| 判定理由 | 錯在哪一步。理由壞掉通常早於結論壞掉 |
| 引用的原文位置 | 它到底有沒有讀到那句話,還是自己補的 |
| 把握程度 | 只拿來排序,決定哪幾筆先進人工複核佇列 |
| 「判不出來」 | 讓棄權變成合法輸出,而不是逼它硬給一個答案 |
最後一欄是最重要、也最難的一欄。
模型天生不願意棄權。 你不給它「判不出來」,它一定會給你一個判定;你給了,它還是很少用。所以這個欄位本身就要被監測——如果棄權率是零,那不代表資料很乾淨,那代表這個欄位沒有在運作。
跟開場那張表是同一件事。
通報數掛零的單位,是我最擔心的單位。從來不說「我不確定」的模型,是我最不敢用的模型。
順帶一提,「把握程度」我只拿來排序,不當機率用。它整體偏高,而且高低之間的差距不見得對應到對錯的差距。當排序用它還堪用——把最沒把握的那些先送去人工複核,這件事不需要它的數值準確,只需要它的相對順序大致成立。這是把一個不可靠的訊號用在它還撐得住的位置上。
上面那些欄位如果只是顯示在報表上給人看,那還停在使用者層次。要成為可觀測性,它必須自己動。
所以每一批跑完之後,我算三個數字。這三個數字有一個共同特性:算它們完全不需要知道正確答案。
第二個最好用。它不需要 ground truth,只需要模型自己跟自己不一樣——而模型自己跟自己不一樣,本身就已經是一個夠強的壞消息。
這三個數字有一個很俗氣的好處:你明天就可以算。不需要標註、不需要 ground truth、不需要任何人點頭。把你手上那條已經在跑的流程,同一批輸入重跑一次,比對兩次的結論——你會拿到一個你從來沒看過的數字,而且多半比你預期的難看。
這三個數字的價值不在於精確,在於它們比結論品質更早動。等到有人察覺判斷變糟,通常已經跑過好幾批;但一致率在那之前就會先掉下來。
這就是 AI 系統的通報率。它不告訴你哪一筆錯了,它告訴你「這批東西該去看一下」。
至於怎麼從「該去看一下」變成「確認它真的判得對」,那是完全不同的問題,需要另一整套東西——第四週會用六篇來談那個,那是我最想寫的部分。這三個數字往下走也會長出兩樣東西:一條把低把握案例挑出來給人複核的佇列,還有一張把這些比例畫成時間序列、看它有沒有悄悄位移的圖(Day 26)。都是後話。
今天只留一個結論:
在你有能力驗證它之前,你至少要有能力發現它變了。
一個會出錯但你看得見的系統,比一個看起來很準、但你不知道它何時開始失準的系統,安全太多了。這是醫療品質花了幾十年才學會的事,而現在輪到我們把它用在自己手上這台機器上。
明天換個角度:一個品管單位一年到底要處理多少電子紀錄,以及為什麼「量很大」從來不是把它交出去的理由。