曹德偉 ← Portfolio
★ 旗艦 2026-04-28 8 分鐘閱讀 回顧

MCP 監控:14 天的稽核,砍掉了我自己的計畫。

我以為監控採集會涵蓋所有 Brain 流量。兩週後,數據告訴我我錯了 ~450×

TL;DR
  • 設計了一條異常偵測管線(採集 → 儲存 → 偵測 → 判斷 → 告警)來監控 Brain 流量。
  • 14 天稽核發現涵蓋率只有 0.22%。真實流量繞過了 decorator 所在的 MCP 層——預期每天 30–60 筆事件,實際只有 ~4 筆。
  • 砍掉自己的 BQML benchmark 計畫,cron 留著(成本是零),把整個專案改寫成 portfolio 回顧文。驗證假設比捍衛假設值得做。

01 假設

紙上的計畫很乾淨。Brain(我的私人知識系統)說 MCP。所以只要我用一個小小的 decorator 把每一次 MCP tool call 包起來、把 tool_nameargs_hashlatency_msstatus 寫進 SQLite,我就能看到整個系統的脈搏。從這裡延伸:用 z-score 偵測器抓每小時的異常、用 Gemini 判斷過濾誤報、用 Telegram 告警發出真正的尖峰。

那個沒寫下來的隱含假設是——MCP 是大門。只要有流量,它就會以 MCP tool call 的形式存在。建模層暖機完之後,我預期會看到每天 30 到 60 筆事件——夠用,至少當下我這樣以為。

02 建置

五個小模組,每個只做一件事。我把它們部署到 EC2、用一條 15 分鐘 cron 串起來。Pipeline 長這樣:

Pipeline — 5 個模組,一條 cron
採集 decorator 儲存 SQLite 偵測 z-score 判斷 Gemini 告警 Telegram CRON 15 * * * * — python -m src.monitoring.hourly

端對端延遲大約 33ms / 筆。健康狀態很容易讀:cron 上次執行時間、列數、judge 呼叫成功率。全綠。

03 部署

異常偵測在冷管線上統計上沒意義——樣本太少 z-score 會狂飆。所以我把就緒程度切成三個明確的階段,每一階段行為不同:

Cold start < 7 天 完全跳過偵測,只收資料。
Warming 7–14 天 執行偵測,輸出標註為「tentative」。不發 alert。
Ready ≥ 14 天 完整 pipeline。Alert 上線。

第 14 天到了。Pipeline 進入 READY。Cron 每 15 分鐘準時跑。Health check 全綠。所以我做了一件第一天就該做、卻沒人——包括過去的我——想到要做的事:問那個顯而易見的問題。

我們實際收到的資料,是不是當初說好要收的那份資料?

04 稽核

我數了監控系統觀察那段時間裡,Brain vault 內檔案異動的次數,再對照監控資料庫實際抓到了什麼。

涵蓋率稽核 — 14 天區間

監控看到的 vs. 實際發生的。

涵蓋率

0.22%

的 Brain 流量真的被監控採集抓到。
2 筆事件入庫  /  897 次檔案異動
每日預期事件數 30–60
基於 pipeline 修法後觀察到的 Brain 活動量。
每日實際事件數 ~4
9 天累積 21–29 筆。差了一個數量級。
~450× 監控能看到的世界,跟 Brain 實際身處的世界,落差這麼大。

管線在跑。管線是健康的。管線幾乎什麼都沒看到。

Brain 99.78% 的真實流量根本不從 MCP 進來。它從 Telegram bot 進來,或從內部 REST handler直接呼叫核心函式進來——繞過我採集所在的 decorator 層。MCP 大門只是三道門裡的一道,而且看起來是最少人走的那一道。

05 歸因

落差一旦看見,下一個問題就是漏點到底在哪裡。我目前有三個還活著的假設;根本原因還沒完全收斂。

要收斂這三個假設並不難——tail systemd 日誌、放一條 debug trace、重新數一次——值得花幾小時。但值得在還沒搞清楚是哪一個之前花好幾週重建管線。

06 決策

我原本的下一步是用抓到的資料跑一場 BQML TimesFM benchmark——把 zero-shot 基礎模型跟我的 z-score 基準比一比。每天 ~4 筆事件,這場比較統計上沒意義。所以我在同一個小時內做了三個決定:

× 砍掉 BQML benchmark 計畫 樣本量撐不起這場比較。再厲害的模型也救不了。
✓ 保留 Cron 不動 成本實質上是零。如果之後修好 instrumentation,它還能當 baseline。
→ 改寫 專案定位 從「成功運作的監控系統」改寫成「教會我東西的監控系統」。

07 核心反思

我蓋的東西全都正常。Decorator 33ms 跑完。Detector 算得出來。Judge 會回。Alerter 會送。Pipeline 沒有一個環節壞掉。

但它不重要,因為底下的假設錯了,而我所有的健康檢查永遠不會告訴我。健康狀態能告訴我「機器有開」;要知道「機器有對著正確的東西」,得另外算一個數字——涵蓋率。

自動化系統除了健康檢查,還要跑一次 14 天涵蓋率稽核。『有在跑』 ≠ 『有在做事』。

對一個正在運作的系統來說,最難的動作是回頭去問——「已經有的東西,是否真的指向現實」?我現在把這件事當作每套自動化系統的硬性 14 天交付物,跟建置本身並列:一個數字、一個驗證日期、以及如果數字不吻合就把專案砍掉的意願。

前面兩個其實不難。最後那個——砍掉的意願——我這次也是練了一輪才有的。

如果你正在徵人 · If you're hiring

你的 LLM 功能上線了。Health check 全綠。
但你不知道它有沒有在做正確的事——對吧?

我為自己的 MCP server 蓋監控,第一次發現 99.78% 流量沒被監控到,修完後第二次發現新假設又錯了。上面這段就是這個故事。

「程式在跑」≠「系統有效」——這是這次稽核教我最深的事。如果你需要一個會回頭稽核自己假設的人,我在你公司會這樣做事:

我寫不出 ML model,也沒當過資深架構師——我每次想到「資深架構師」這個詞都覺得跟自己無關。
但有一件事我大概比我認識的多數人都熟練:寫了三天的方案,發現方向錯了,隔天早上重來。
聽起來像優點,其實是因為我已經砍過很多次,砍到沒感覺了。


[email protected] · 開放遠端 / 台北