事故調查 · 續篇 · 2026-10 接回 一次加分的代價
撞礁是遲早的, 海圖只回答 一件事:會不會死
AI 是一條誰都能開的大船。沒開過船的人碰到礁是遲早的,差別不在撞不撞——在這片水域撞了會不會死、代價多大。四張帳單、一份被帳單打過卻沒改的海圖。
案例:Happy Toy Scout(半路工程師在矽谷)、FunClass 翻課星球(方方老師)、Seb Hoek 的瀏覽器遊戲、一則 Threads 貼文 · 依據:作者公開文章、公開 repo 的 commit 歷史與原始碼、網站實測標頭、前一份報告 · 未登入、未碰任何人的雲端帳號
TL;DR
三句話
撞礁不是變數。 四個案例——矽谷資深工程師、25 年資歷的開發者、國小老師、一位獨立開發者——沒有一個在上線前算過「使用者 × 次數 × 大小」。大船人人能開,閉環便宜到一晚上百次部署只是價格標籤;事前擋住這個錯的人,四個裡零個。
會不會死才是變數,而它查得到。 決定因素是計費單位和有沒有硬上限。有上限的兩個(免費額度會停、按次計費)撞了是「遇到再修」;沒上限的兩個(Blaze 隨用隨付、只設預算提醒)撞了是帳單。二對二,結果完全對齊,不需要知道誰是 Staff。
海圖是可以查的,查到的結果不好聽。 老師的 AI 技能裡有一道成本關卡——標了 Storage 和 Functions 兩顆礁。撞沉他的 Realtime Database 不在圖上,圖上也沒有「水深」這個概念,只有「有沒有礁」。技能 8 月 10 日一天發佈,9 月帳單 NT$2,854 之後零 commit;線上拆開存的試行名單今天還是 1 個帳號,昨天剛部署的一輪改的是寵物和動畫。帳單打到了他,沒打到他的海圖;而那張海圖已經發給了其他老師。
01 · 水域
大船誰都能開,所以每個人都是舵手
先把「資深」這個字拿掉,它在這篇裡不解釋任何事。
Brian 十天部署 122 次,媒體寫成熬夜的英雄故事。用 Claude Code,一個晚上上百次 commit 加部署是日常,擋住你的只有速率限制和 API 的錢。那個數字量的是迴圈多便宜,不是人多強。Seb Hoek 25 年資歷,讓 AI 寫的 N+1 查詢直接上線,「小規模時我沒注意到」。方方老師沒有資訊背景,用 agent 幾個月做出 5.4 萬月活的產品、18 個 Cloud Functions 防作弊、本機優先加每日備份。三個人的產出速度在同一個量級,因為速度是船給的。
Staff 工程師的工作本來就是拆任務、指揮人;2026 年只是指揮的對象換成 agent。從這個形狀看,三個人都在做 staff 的事:老師寫了一份技能檔指揮 Codex,那就是指揮。所以差別不在職稱,在指揮者剩下的三個判斷:
你指揮的是誰。 agent 是一個寫得很快、會把功能做出來、但會寫 N+1 和整塊廣播的中階工程師。把它當資深放行,就是 Seb 的錯。
這片水域撞了會不會死。 計費單位是什麼、有沒有硬上限。這是本篇的主題。
review 放在哪一層。 功能層 agent 自己會過;查詢層和計費層它不會,那是你的。
沒開過船的人撞礁是遲早的。海圖不幫你避開礁,海圖告訴你哪裡的礁會沉船。
02 · 暗礁
同一顆礁,四個人都撞
雲端帳單爆掉的故事,九成是同一道算式沒算:
每月帳單 ≈ 使用者數 × 每個使用者觸發的次數 × 每次送出的資料量 × 單價
前三項相乘叫扇出。做出第一版的那個晚上,使用者數是未知數——不知道會不會有人用,就沒有理由花一小時算「十萬人進來會讀幾次」。這不是粗心,是結構性的:事前沒有任何回饋能告訴你算錯了,第一個回饋永遠是帳單。四個案例的扇出:
2 天
Happy Toy Scout · 13,000 家門市全載、每個訪客都讀資料庫 · 免費額度打滿
NT$2,854
FunClass · 整班壓縮塊廣播給 30 台裝置 · 9 月帳單
100 萬次/日
Seb Hoek · N+1 清理、每請求讀 8–50 份文件 · 免費額度的二十倍
NT$8,000+
Places API · 以為方案含在內 · 一個晚上
四個人裡,事前算過的:零個。Brian 自己寫「不知道未來會不會有更多人需要」;Seb 自己寫「小規模時我沒注意到」;老師的技能檔沒有扇出這個字;Places API 那位問了 AI,AI 說方案含在內。撞礁這件事上,資深和新手沒有差別。
03 · 水深
會不會死,取決於兩件事
同一顆礁,兩個人撞了之後「遇到再修」,兩個人撞了之後收帳單。差在哪裡?不在誰比較會修——Brian 修得快,老師也在修,只是修錯層。差在撞的那片水有多深:
LEGEND · 水深
硬上限 爆了是「停」還是「寄帳單」?免費額度、配額上限、花費上限是停;隨用隨付加預算「提醒」是寄帳單。提醒不是上限——Places API 那位設了提醒,通知來的時候已經燒掉八千。
計費單位 按次、按位元組、按人頭、按秒。同一個技巧換了單位結果相反:整班壓成一塊,在按次計費的 Firestore 是省錢,在按位元組的 Realtime Database 是四百倍。
二對二,結果跟「有沒有硬上限」完全對齊。這條線的好處是它可以被推翻:找到一個有硬上限卻收到天文帳單的人,或一個沒上限卻從沒爆過的人,這一節就錯了。歡迎找。
四條航跡:同一聲警報之後,有無硬上限的兩組人各自走了哪幾步
警報
第一步
第二步
現況
有硬上限
A
Happy Toy Scout
第 2 天額度停 快取靜態資料 依視角載入、砍讀取 第 10 天修完
B
Seb Hoek
$10/月往上 三個儀表板 拿帳單問 AI 成本歸零
無硬上限
C
FunClass
夏天 一天 300 元 修頻率(大小沒動) 9 月摸到拆開存 正式環境仍整塊
D
Places API
問 AI,AI 給錯方案 一晚 8,000 元 設配額上限、申訴 拿回調整款
切在「使用者 × 次數 × 大小」上的一步
沒切到的一步(或錯的圖)
上半是有硬上限的水域,下半是沒有的。四個人撞的是同一顆礁,警報之後的航跡分成兩組——分組的不是人,是水深。
04 · 證據
老師的海圖,逐行查
上一篇說「沒人在選型時問過單位成本」。這次把他寫給 Codex 的技能 build-firebase-cloudflare-app 整個 repo 拉下來看,這句話要修正:他問了,但問的是「有沒有礁」,不是「水深」 。
repo 的 19 個 commit 全部在 2026-08-10 同一天發佈;到 2026-10-22 為止零 commit。9 月 NT$2,854 的帳單之後,公開版本一個字沒改。
技能裡有的:
一節叫「Cost and irreversible-choice gate」:Cloud Storage 需要 Blaze、部署 Cloud Functions 需要 Blaze、開 Blaze 前要說明哪個功能需要並給出純靜態或模擬器的替代方案。
「不可默默建立付費資源、啟用計費、改 DNS、刪部署、覆寫正式環境密鑰。」
交付清單要列出「可能產生費用的服務,以及預算警示和 App Check 是否還在」。
審計腳本 audit_project.py 會掃程式碼,偵測到 Storage 就警告「需要 Blaze 核准才能上正式環境」。
技能裡沒有的:
「計費單位」「位元組」「流量」「扇出」「下載」——整份技能零出現。成本在這張圖上是二元的:付費或不付費。
Realtime Database 只出現兩次:「別無故初始化」和 App Check 的保護清單。它不在成本關卡裡。審計腳本偵測 Firestore、Storage、Auth,不偵測 RTDB 。
新手模式再加一層靜音:「除非使用者問,否則不提定價、方案、配額、計費」。
所以這張海圖標了兩顆礁——Storage 和 Functions——而且標得不錯。撞沉他的那顆不在圖上,圖上也沒有水深這個維度。更要緊的是順序:Cloud Functions 需要 Blaze,他為了防作弊開了 Functions,技能照規矩問了「哪個功能需要 Blaze」然後放行——這一步把他推進了沒有上限的水域,接著 Realtime Database 的位元組計費在那片水裡等他,而那片水在圖上是空白。
然後是最不好聽的一段。帳單來了,他修了:分數加緩衝、寫入加冷卻、內容沒變不重發——修的是頻率,大小沒動;9 月摸到拆開存,只對一個帳號試行。這些都是修船。海圖呢?8 月 10 日發佈,之後沒有動過。帳單打到了他,沒有打到他的圖。而 8 月 10 日那天,他把這張圖連同「新手模式不提計費」一起發給了其他老師。
今天的船
2026-10-22 把線上前端拉下來看,船的狀態跟圖一樣:
拆開存還在試行,名單一個帳號。 bundle 裡兩條路都在:舊的整塊監聽 onValue(classPublicRef…),和新的每人一格節點(studentStateRef、studentTokenBalanceRef、studentSummaryRef、splitDelivery/publicationMeta)。切換靠 splitPilotOwners 名單——裡面只有 1 個帳號。其他所有班級,今天還是整班壓縮塊廣播給 30 台裝置。
夏天那版沒把帳單壓下來。 修頻率的 rtdb-cost-p2 標記還在線上;它上線之後的 9 月整月帳單就是那張 NT$2,854。同步路徑沒變,10 月合理預期同量級。
昨天剛部署了一輪,改的是功能。 幾乎所有 JS 和 CSS 的版本戳記都是 20261021:寵物收藏、寵物動畫、特效、文字雲、公平抽籤、活動、新手說明、教師工作區。同步層的檔案也有昨天的戳記,但試行名單還是 1。翻成第 01 節的話:速度又花在「加」,扣分的那格還空著。
網址還是 crimson-wind-7a22.changsheng0612.workers.dev。 Cloudflare 隨機產生的預設子網域,上線半年、5.4 萬月活、雜誌專訪,沒掛自己的網域。不是能力問題:技能把「改 DNS、掛自訂網域」跟「啟用計費、刪部署、覆寫密鑰」放在同一張「不可默默做」的清單上——這是對的護欄,agent 自作主張改 DNS 才可怕——但護欄擋的是動作,新手模式又不主動提議,整份技能的信仰又是免費,於是沒人開口、沒人要求、沒人付那一年十美元,網址就一直是預設的。跟計費單位不在圖上是同一種空白,只是這個空白便宜,人人看得見。
護欄擋的是動詞,暗礁是名詞
回頭看那張「不可默默做」的清單:建立、啟用、改、掛、刪、覆寫——全是動詞。agent 的護欄擅長擋動作,因為動作是離散的,執行前攔得住;技能的成本關卡和審計腳本也是這樣寫的,找的是「有沒有用到 Storage」「有沒有部署 Functions」。撞沉他的那顆礁不是動作:整班壓縮塊 × 30 台裝置 × 按位元組計費,三個東西各自都合法,沒有任何一步會觸發「不可默默做」。護欄擋的是「做了什麼」,暗礁是「做了之後會長成什麼」。這就是為什麼技能裡有一整節成本關卡、審計腳本也在跑,卻一條都沒攔到——它們都在找動詞。
夏天發現一天燒 300 元的確切日期,在 8 月 10 日之前還是之後,公開資料查不到。他私下可能有新版技能。CLASSROOMHUB 公開 repo 只有 5 月的五次上傳,沒有後續歷史。這一節講的是公開的那張圖。
撞礁之後修船是本能,修圖不是。沒被改過的海圖,會把下一條船帶到同一顆礁。
05 · 舵手
另外三個人,各自指揮了誰
A Brian:算過死不了,所以不做
週五深夜寫到週六早上,給灣區朋友用,「不知道未來會不會有更多人需要」,放在免費額度上。這三個條件下不做快取不是忘了,是算過:預期幾十個人、失敗有上限、先上再說。第二天額度打滿、停掉,他用十個晚上把讀取次數跟訪客數脫鉤——快取靜態資料、依視角載入、砍掉不必要的讀取。他自己說這些概念「平常出現在大公司的架構文件或技術面試裡」,是這次才「化作深刻的架構體悟」。知識本來就在,沒變成肌肉;免費額度是他的保險絲,所以可以等它變。
今天的網站實測:跑在 Cloudflare Workers 上(回應標頭有 x-vinext-cache),資料庫 Supabase,瀏覽器零直連資料庫、全走同源 /api/*,首頁在 CDN 節點快取 5 分鐘,收藏頁是發版時產生的快照,地圖用 Leaflet 加 OpenStreetMap 公用 tiles。
第一天用的是哪家雲、打滿的是哪個額度、帳單金額、有沒有用 AI 寫,公開資料都沒有;「Staff 工程師」是粉專自述。這一節不需要這些。
B Seb:把中階當資深,review 放錯層
25 年資歷,用 AI 助理寫瀏覽器遊戲入口,上線。AI 寫的夜間清理是 N+1——先載全部 500 個 profile,再對每個各跑一次子查詢,501 次讀取做 30 次的事;profile 端點五層疊加——多個 React 元件平行發重複請求、每次載不需要的子集合、每個請求檢查一次維護任務、每次呼叫前 getIdToken(true) 強制換 token、沒有快取;種子產生每個請求讀 8–50 份文件,200 個每日使用者就是 5 萬次。尖峰每天 100 萬次讀取,免費額度的二十倍。
他怎麼發現:不是驚嚇,是趨勢——每月約 10 美元但往上,加上延遲越來越差。三個儀表板:Billing Reports 說只有 Firestore 在花錢、Query Insights 指出哪三個集合被讀最多、Observability 指出哪個端點慢。然後拿三個具體問題去問寫出這些程式碼的同一個助理,一起修:collection group query 取代迴圈、權重預先算好存進一份文件、304 Not Modified、維護一天一次。每日成本歸零。
他的錯不是不會,是放行的層次:功能層他讓 agent 過,查詢層他也讓 agent 過。他自己的結論是人的審查「最好在成本爆炸之前」——意思就是 review 要放在查詢層。但他撞的水域是 Firestore 按次計費、5 萬次免費,爆了是 10 美元,所以這一課的學費是 10 美元和幾個晚上。
D Places API:海圖是 AI 畫的,畫錯了
專案大量用 Google Maps Places API,第一個月帳單逼近五萬台幣。問 Gemini,Gemini 說有一個月費 100 美元的 Starter Plan,列出涵蓋的 API。訂了,一晚燒掉八千多,用量 8,000 多%——方案根本不含 Places API。兩週申訴,拿回一筆調整款。他自己寫的教訓:預算「提醒」和「上限」是兩回事,提醒來的時候來不及反應,要設配額上限。
他有去看水深,問的是 AI,AI 給了一張錯的圖,而他沒有硬上限可以擋。這個案例是第 06 節的開場。
06 · 救生衣
AI 能不能替你看水深
能,但三個條件缺一不可,而且每一個都有案例撐。
一、問題要在流程裡,不能靠人想到。 計費單位、硬上限、扇出——AI 全都知道,問了就答。老師的技能沒問是因為規則寫了「不提計費」,而且它的成本概念裡沒有「單位」這個維度。地圖可以外部化成一道關卡:agent 碰任何會隨人數成長的功能前,先答第 07 節的四題。
二、AI 畫的圖可能是錯的,帳單才是對的。 Places API 那位就是證據。AI 的答案是機率抽樣不是查表——同一個問題換一天問可能不同。寫程式有編譯器抓,架構決策沒東西抓。所以關卡逼出來的必須是數字(單位、位元組、十倍時的月費),數字能跟定價頁對;逼出來的如果是「這樣應該沒問題」,那是對話,不是關卡。
三、事後比事前準。 事前問「我這架構會不會爆」,AI 只能給中位數答案,它不知道流量。事後把帳單截圖和程式碼一起丟進去問「為什麼是這個數字」,準得多——Seb 就是這樣修的,上一篇報告也是這樣寫的。所以撞礁那天最划算的動作,是把警報原封不動交給 AI,然後自己讀懂它回的圖、對著帳單核一遍。
裝一個「架構 review」技能,是不是免費的海圖
像 grill-me 這種動手前盤問你的技能——一次一題、附建議答案、問到每個分支定案才准寫——方向是對的,它是條件一的具體形狀。但要知道借到的是什麼:
技能裡的海圖是作者的海圖。 老師那份技能就是最好的例子——它有成本關卡,標的是作者撞過的礁。你裝一個別人的技能,借到的是別人撞過的礁;他沒撞過的,圖上是空白,而空白看起來跟安全水域一模一樣。
只有逼出數字的題才是關卡。 「這個架構有沒有問題」會得到一段流暢的意見,每次不一樣。「計費單位是什麼、單次扇出幾個位元組、十倍時月費多少」逼出數字,數字能核對——等於在帳單來之前先造一個便宜的警報。
它會替你補完海圖,但墨水同一個顏色。 你沒想到的,它擅長補——邊界條件、同類系統常在哪出事。你想歪的,它不擅長抓——它順著你的前提推,前提錯了它推得更完整。而查到的、算出來的、猜的,在它的輸出裡長得一樣。要它補圖,逼它每個答案後面標出處:定價頁查到的、從你的數字算的、它猜的——只信前兩種。
盤問型技能自己的說明就寫了最大的坑: 照單接受它附的建議答案,等於讓它自己盤問自己。那是回音,不是海圖。
AI 有海圖,但只在你問的時候給、給的可能是錯的、帳單來的時候最準。
07 · 出港前
第五條船是你的
四個人沒有一個是為了寫進報告才撞礁。你也會撞,問題只剩代價。所以這一節不講道理,給四個出港前的問題,順序是故意的——第一題答「寄帳單」,後面三題就必須答得出數字;答「會停」,後面三題可以等撞了再補。
在實作之前,先回答下面四題,答不出來就停下來問我:
0. 這個功能用到的每個雲端服務,爆了是「停」還是「寄帳單」?有沒有硬上限(免費額度、配額上限、花費上限)?預算提醒不算。
1. 每個服務的計費單位是什麼?(按次/按位元組/按人頭/按秒)
2. 使用者做一個動作,會有幾台裝置各自下載多少資料?算出單次扇出的位元組數。
3. 使用者變成 10 倍和 100 倍時,這個功能的月費各是多少?哪一項是線性成長?
每個答案後面標出處:定價頁查到的/從我給的數字算的/你猜的。
把四題寫成一張表,讓我決定要不要做,再開始寫程式。
然後,帳單來的那一天——不管是額度打滿的通知還是月底的數字——把它原封不動貼給 AI,連同程式碼,問「為什麼是這個數字」。它回的圖自己讀一遍,每一格對著帳單核;對不上的是它錯,不是帳單錯。
最後一件事,老師沒做的那件:修完船,回去改圖。 把這次撞的礁寫進你的技能檔、你的 CLAUDE.md、你給 agent 的規則裡。不然下一條船——可能還是你自己的——會撞在同一個地方,而且這次水可能更深。
撞礁是遲早的。海圖只回答一件事:這裡撞了,會不會死。
附 · 證據與限制
哪些是看到的,哪些是推的
直接看到的: Brian 在換日線的全文與世界日報、Tri-City Voice 的報導;Happy Toy Scout 今天的回應標頭、CSP、靜態資源清單;Seb Hoek 在 DEV 的全文;Threads 貼文原文;FunClass 的帳單截圖與三代程式碼(上一篇);build-firebase-cloudflare-app 公開 repo 的完整 commit 歷史、SKILL.md、references、audit_project.py 原始碼;CLASSROOMHUB 公開 repo 的 commit 歷史;FunClass 線上前端 bundle 裡的 RTDB 路徑、監聽呼叫、splitPilotOwners 名單長度、版本戳記(2026-10-22 讀取,未登入)。
推論: Brian 第一天的雲、打滿的額度、帳單金額、有沒有換平台、有沒有用 AI 寫;「Staff」為自述。老師夏天發現 300 元的確切日期與 8 月 10 日的先後;他私下是否有新版技能。
上一篇要修正的一句: 「沒人在選型時問過單位成本」→「技能有成本關卡,但關卡是二元的(需不需要 Blaze),沒有計費單位的維度,且不涵蓋 Realtime Database」。
沒做的: 沒有登入任何人的帳號、沒有讀寫任何雲端資料、沒有測量真實流量;沒有聯絡任何一位當事人。四個案例是說書,不是統計;第 03 節的二對二是可以被推翻的主張,不是分佈的證明。
資料來源