文件導航

置信度門控與升級到人

上一篇說的是「閾值由程式碼持有」。這一篇說的是那個閾值分出來的三段 該怎麼用。

三檔,而不是兩檔

真實專案極少把決策做成「自動 / 不自動」。常見的是三檔:

檔位 條件 動作
自動 置信度高於上閾 且 通過附加檢查 直接執行
升級 落在中間帶 交給人
丟棄 置信度低於下閾 不執行,也不佔用人的注意力

第三檔容易被忽略,但它是三檔裡最省錢的一檔。「不看」和「讓人看一眼」的成本差著 一個人力。

一個告警分流器的實現很典型:P(SEV1) + P(SEV2) ≥ 0.80 才 page; 只有在「可操作性」這一項也不同意時才在小於 0.20 時丟棄;中間帶交給人。

中間帶才是真問題

三檔結構一畫出來,問題就全跑到中間那一條了:

它是人力資源,不是閒置容量。 中間帶越寬,被升級的越多,人處理的越多。 一個 9% 的升級率聽起來很低,但當基數是一天幾千條時就不是了。

它需要一個兜底,否則會被靜默拖死。 把決定交給人之後, 如果沒有人來看,這件事就永遠停在那裡 —— 而這在監控面板上看起來和 「一切正常」一模一樣。上面那個分流器給出的解法很硬: 人 15 分鐘不 ack,照樣 page。 寧可吵醒人,也不能讓一條 P1 卡在待辦裡。

升級條件本身也會失效。 一個在 agent 裡用的自主度門控是 「Choice 高於 0.6 且自主安全 Noul 高於 0.5 才繼續」,否則把回合還給人類。 兩個數都要過 —— 因為「我該做什麼」和「這件事安全嗎」是兩個獨立的問題, 用一個置信度同時回答它們會把風險藏起來。

閾值怎麼定:先量,再定

拍一個 0.8 出來是最常見的做法,也是最容易在三個月後變成噪音的做法。 可復算的做法是:在你自己標註的資料上,量出「達到目標準確率需要多高的閾值」。

一個公開的例子:以 0.7 作低置信門檻,在 n=130 的樣本上以 9% 的升級率 抓住了 3 組誤判中的全部 3 組。樣本很小 —— 它的價值不在於那個 0.7, 而在於說明了該這樣報數:說出樣本量、升級率和抓到的東西, 而不是隻報「提升了準確率」。

延遲是這條鏈路裡被低估的風險

上面那個告警分流器的實測數字值得單獨看:

指標 值
p50 418 ms
p95 1477 ms
成本 約 $0.04 / 千條
最慢一次 距它自己設的 2 秒超時只差 151 ms

p95 是 p50 的 3.5 倍。也就是說尾部的延遲比平均值重要得多 —— 因為超時策略會在尾部觸發,而超時策略一旦觸發,走的是兜底分支, 不是你以為的那個分支。最慢一次距超時只差 151 ms,說明這個系統的 「確定性」很大程度上取決於一個剛好沒被觸發。

門控系統的失敗方式因此常常不是判斷錯了,而是超時了,然後走了兜底。 兜底分支要單獨測,不能只測主路徑。

兩個兜底方向,各有各的場合

出錯時該怎麼辦,公開的做法分成兩派,而且都對:

  • fail-closed(出錯就拒絕):一個許可權判定器在超時或報錯時直接 deny。 安全門就該這樣 —— 一個 fail-open 的安全門是一個靜默的洞。
  • fail-open(出錯就放行):一個 Claude Code 的 Stop hook 在任何錯誤時放行。 效率門就該這樣 —— 一個 fail-closed 的效率門會把整個流程卡死。

判據不是「哪個更安全」,而是錯殺的代價和漏放的代價哪個更大。 而且這個取向要在寫程式碼時想清楚,因為它決定的是異常分支, 不是主路徑。

一句話

三檔結構裡,工作量在中間那一條上:它的寬度是成本,它的兜底是可靠性。 兩樣都要顯式設計,不能靠預設值。