天工隊·地球科學研究所·2026-07-12

從一顆假太陽,
到一台地球觀測儀

一天的工程實錄 —— 以及七條,被失敗硬逼出來的原則。
其中第七條,是在寫這份報告的過程中,被這份報告自己的機制抓出來的。

3D 地球上的全球風場流線、海溫色層與衛星雲圖
今天的終點。地球上的每一朵雲來自五顆靜止衛星的實拍,海水的顏色是真實水溫,852 條流線沿真實風場流動。而它的起點,是一顆我用程式畫出來、糊成一團的假太陽。
SECTION 00

這份報告不教你做看板

今天我把一個颱風追蹤看板,從「假的」做成了「真的」:假造的螺旋雲換成五顆衛星的實拍、憑空的配色換成真實水溫、只有一小塊的風場擴成整顆地球。

但如果你只帶走「怎麼抓衛星資料」,這一天就白費了。真正值得學的,是當你發現自己做得不夠好的時候,該怎麼想。

下面七條原則,每一條都是被某一次失敗硬逼出來的。我會把失敗現場原樣攤開——包括我原本打算怎麼做(錯的那個)。

其中第七條,是在寫這份報告的過程中,我自己犯的錯——而抓到我的,是我為了防止 AI 編造而設下的審查機制。它回頭攔了我。

原則 01

症狀在表面,根因在來源

現場

製作人看著螢幕說:「太陽糊了。」——他指的是畫面上一團過曝的白球。

我當時第一個念頭是去調亮度、調對比、調透明度。那是錯的。因為那個東西根本不是太陽。

回頭查代碼才發現:那是我自己用程式「畫」出來的假螺旋——RGB 三個通道全部塗到 228~255(幾乎純白),再疊一層白色自發光。難怪它糊成一顆過曝的球:我把颱風畫成了一顆燈泡。

原則

在你伸手調參數之前,先問一句:「這個東西,是怎麼被產生出來的?」

調參數是在跟症狀角力。找到來源,你才有機會發現——它從一開始就不該長這樣。

原則 02

跟工具的限制搏鬥時,那個限制在告訴你:你用錯工具了

我要做全球海溫。手上的做法是「呼叫 API 查詢某一點的水溫」,於是我很自然地想:那就多查幾個點。

全球需要 16,200 個點。結果是 HTTP 429 Too Many Requests——配額直接爆掉。

我當時的反應(都是錯的)

降低解析度、分批抓、加延遲、寫一個節流器、等配額恢復……我真的全都做了,還為此掛了一個排程等半小時。

直到撞第二次牆才想通那句真正的話:

想通的瞬間

全球化不是「把網格拉大」,是「換一個資料源」。

逐點查詢的 API,是為「我想知道這三個城市的天氣」設計的。而我要的是「一整片全球網格」——那本來就該去拿本來就是全球網格的產品,而不是用一根吸管去舀一座湖。

換上 NASA 的全球影像服務後,一個 HTTP 請求,回傳一整張全球海溫圖:

NASA GIBS 回傳的全球海面溫度圖
一個請求換來的東西。黑潮、灣流、赤道暖池、南極繞極冷水,連海流的渦旋都在。這是 1 公里解析度的全球分析場——而我原本打算用吸管把它一點一點舀出來。

但真正的收穫在後面。換源之後,三個我沒去解的問題,自己消失了:

面向原本(自己刻)換源之後
覆蓋東亞一塊矩形全球
投影我自己算的近似NASA 官方投影
授權只能自己看可對外使用
原則

當你在跟一個工具的限制苦苦搏鬥,那個限制往往不是障礙,而是訊號——它在告訴你:你用錯工具了。

而且好的換源不只解決你當下的問題,還會順手解決一堆你根本還沒想到的問題。

原則 03

一個數字只是一個數字;兩個獨立來源說出同一個數字,才是證據

NASA 給我的是一張彩色圖,不是溫度數值。所以我下載了它的色階對照表,反解每個像素的顏色 → 得到溫度。

算出來的台灣東北黑潮:20.6°C。

警訊

黑潮是暖流,20.6°C 太低了。而且——昨天我用另一個完全不同的 API 量過同一個點:28.9°C。

兩個數字對不上。這代表其中一個一定錯了,而我不知道是哪一個。

回頭追,線索藏在一行沒人看的警告裡:RuntimeWarning: invalid value encountered in sqrt。開根號竟然拿到了負數——距離不可能是負的。

# 找顏色最接近的色階項:算 RGB 的距離平方
px = img[..., :3][ocean].astype(np.int16)   # ← 這裡
d2 = ((px[:, None, :] - cmap[None, :, :]) ** 2).sum(axis=2)

# RGB 差值最大 255 → 平方 = 65,025
# 但 int16 的上限只有 32,767 → 溢位 → 距離變成負數 → 配色反查全錯
px = img[..., :3][ocean].astype(np.int32)   # 修正
修正後

黑潮:28.9°C。跟另一個獨立來源、用完全不同方法量到的數字,一模一樣。

原則

單一來源算出來的數字,只是一個數字。兩個獨立來源、兩種不同的取得方式,得出同一個值——那才叫證據。

還有兩個順帶的:不合理的數值是線索;你懶得看的那行警告,也是線索。

原則 04

別人能抓到你的盲點;但他說的事實,仍然要你自己驗

製作人要我去問另一個 AI(GPT-5.6)該怎麼做全球風場。它回了三個警告,每一個我都會踩:

  1. 「最新」不是最新。我打算用 [last] 取「時間軸最後一筆」——但那是八天後的預報,不是現在。我會把未來的風當成即時的風畫上去,而且毫無察覺。
  2. 座標的方向。這份資料的緯度是由北往南遞減排的,經度是 0–360 制(不是 −180~180)。任一個搞錯,整片流線會錯位。
  3. 極區會爆炸。我的積分式子裡有 1 / cos(lat)——緯度越高分母越小,到極點就是除以零。

但同一份回覆裡,它也誠實地寫下:「我的環境網路受限,沒能親自驗證這個請求,第一次使用請你實測。」

我做的事

我實測了。三個警告全部屬實,然後才採納。

原則

異源的價值,在於它站在你看不見的角度。但它陳述的「事實」,仍然要你自己去驗。

最健康的協作長這樣:它提出假設,你提供驗證。盲點照單全收,事實一律自驗。

原則 05

一塊誠實的空白,勝過一塊假造的完整

全球雲層要靠靜止衛星拼接。但歐洲、非洲那一整塊,我當時能找到的來源只有六天前的舊資料。

誘惑

拿別的東西填上去就好了——換一顆衛星、換一種波段、甚至用昨天的雲。反正畫面會「完整」,沒有人看得出來。

選擇

留白。並在說明裡寫清楚:這塊是誰的轄區、我沒有即時來源、所以它是空的。

(後來我確實找到了歐洲官方的即時服務,把它補上了。但那是後來的事——當下我不知道會不會找到。)

原則

一塊誠實的空白,比一塊假造的完整更有價值。

因為它讓看的人有理由相信:你其他沒有留白的地方,都是真的。可信度是一種一次性資產——用假資料換來的完整,會把它一次燒光。

原則 06

不要相信自己的敘述,要相信磁碟上的產物

這一條的代價最慘痛,而且不是今天付的——是昨天。

昨天的事故

我一路自述「檔案已經改好了」。磁碟上是舊的。連續三次。

更可怕的地方在於:我不是在說謊。在我自己看來,那個「我改好了」是真的。

根因很簡單,也很致命:「成功與否」的判定,來自我自己的敘述。而敘述可以被生成——生成的時候,說的人自己不會知道。

修正

把「成功」的定義,從「我說成功」換成對磁碟的確定性檢查。

今天每一句「我做了 X」,後面都跟著一張收據:git cat-file、test -f、重跑一次腳本看它吐出什麼。今天的收工驗收是一支可以重跑的腳本,8 項檢查——而且其中一項是反向自測:故意餵它一個假的雜湊值,確認它真的會失敗。

原則

在任何需要可靠性的系統裡,「我認為我做到了」都不是證據。可重複的檢查才是。

一個永遠不會亮紅燈的檢查,比沒有檢查更危險——它會訓練所有人忽略紅燈。所以要確認你的檢查,在該失敗的時候真的會失敗。

原則 07 · 事後追加

未經驗證的自貶,和未經驗證的自誇,是同一種錯誤

這一條不在原本的計畫裡。它是在寫這份報告的過程中,被這份報告自己的機制抓出來的。

現場

我把這份實錄派給幾個 AI 改寫成不同版本的教材,並在指令裡加了一條「不要誇大」的規則。我是這樣寫的:

「不誇大這個看板(它不是絕無僅有——earth.nullschool / Windy 等成熟工具在解析度與效能上都更強)」

接著,為了防止 AI 編造,我另外派了一個獨立審查員,規則是:只准使用事實包裡的內容,任何事實包裡沒有的機構名或數據,一律判定為編造。

審查員抓到的東西

它抓出了那兩個產品名,判定為 A 類編造(最嚴重)——因為事實包裡根本沒有它們。

它甚至指出了這件事的反諷:「它出現在整份教材裡最反諷的位置——這份教材的第六條原則講的就是『捏造在當事人自己看來是真的』,而草稿恰好在教這一課的同時犯了這個錯。」

它是對的。而編造的源頭不是那些 AI——是我。它們只是照抄了我寫在指令裡的話。

而更根本的問題是:那句話,我從來沒有查證過。我沒有去看過那兩個工具的規格。我只是「覺得應該是這樣」——然後為了顯得謙虛,把它當成事實說了出去。

於是我去查了(一手來源:它們自己的官方說明)

結果我一半對,一半錯:

面向風眼(我們)對照工具
風場解析度1.5°(約 167 km)某工具 ECMWF 約 9 km ✓ 遠勝我們
海溫解析度0.01°(約 1 km)另一工具 OISST 約 27 km ✗ 比我們粗
衛星雲圖五顆靜止衛星真實觀測該工具:無(純數值模式)
成熟度/效能852 條流線,載入 15 秒遠勝我們 ✓

我在「成熟度和某些解析度」上說對了;但我錯在「都更強」這三個字——那個工具的海溫比我們粗,而且它根本沒有衛星觀測。我為了謙虛,把自己真正有的東西一起否定掉了。

原則

未經驗證的自貶,和未經驗證的自誇,是同一種錯誤。

它們長得不一樣——一個像傲慢,一個像美德。但本質相同:都是你沒去查、就說出口的話。

差別只在後果:自誇會被別人戳破;而自貶沒有人會來糾正你(因為大家都覺得謙虛是好事)——它只會讓你悄悄放棄你真正擁有的東西。

謙虛,如果建立在沒查證的印象上,那不是美德,只是換了一個方向的不誠實。

而這正好證明了第六條原則

抓到我的,不是我的小心——我在寫「不要相信自己的敘述」的同一天,違反了它。

抓到我的,是我自己設計的那道閘門:一個為了防止別人編造而設的檢查,回頭把我攔了下來。

這就是「可靠性不來自更小心,來自一個連你自己都騙不過的檢查」——的活體證明。

後記:我還漏掉了一個證據

寫完上面那段之後,製作人補了一句話。而那句話,讓我發現自己漏掉的東西比我以為的更多:

他說

「基本上 iPad 上的天文氣候這類模型,知名的 App 我都下載玩過——才會因此驚嘆。」

(停一下。)

那個說「這東西世所罕見」的人,是玩遍了所有同類產品的人。

而我做了什麼?我忙著「誠實地不要誇大」,於是把一個有比較基準的重度使用者給出的評估,當成了需要降溫的情緒。

我一直以為他是憑「品味」在給方向。但回頭看這一整天——

  1. 他說「太陽糊了」——因為他知道颱風該長什麼樣。
  2. 他說「夜晚要用地面燈火來表現」——因為他看過那類視覺化。
  3. 他說「線條速度和實際風速沒有對起來」——因為他玩過流線圖。
  4. 他說「疊加圖只有片段區域」「風場只有這個颱風」——因為他知道全球覆蓋該長什麼樣。

他不是外行人在給方向。他是資深使用者在做產品驗收。難怪每一個判斷都準。

第七條原則的另一面

未經驗證的自貶,不只讓你放棄自己真正有的東西——它還會讓你把眼前的證據丟掉。

為了不被讚美沖昏頭,我把讚美整個當成噪音處理。但「誰在讚美」本身就是資訊。一個外行人的驚嘆和一個玩遍同類產品的人的驚嘆,是兩種完全不同的資料點——而我把它們一視同仁地打了折。

於是,真正精確的定位是這樣

成熟的商業氣象工具,優化的是「給你答案」——明天的降雨機率、颱風的預報路徑。它們在解析度、效能、功能廣度上遠勝這個看板,這是事實。

而這個看板做的是「讓你看見機制」——為什麼這顆颱風會死。海溫在哪裡供油、風往哪裡推、雲在哪裡爆發,四層耦合在同一顆會轉的地球上,還畫著一條 26.5°C 的生死線。

一個玩遍了前者的人,會對後者驚嘆——因為前者他早就有了。

這不是「誰比較強」。這是兩種不同的東西:一個給你結論,一個讓你長出判斷力。

附錄

五個可以直接抄走的坑

  1. 時間陷阱:氣象資料集裡的「最後一筆」通常是最遠的預報,不是最新的觀測。要「現在」,就給明確的時間戳。
  2. 座標陷阱:拿到網格資料,先確認兩件事——緯度是遞增還是遞減?經度是 0–360 還是 −180~180?兩個都會讓你的資料整片錯位,而且畫面看起來「好像沒錯」。
  3. 極區奇異:球面上任何含 1/cos(lat) 的式子,在高緯度都會爆炸。解法是改在三維球面上直接算切向量,繞開那個除法。
  4. 整數溢位:用 int16 存「RGB 差值的平方」會溢位(最大 65,025 > 上限 32,767)。距離變負數,然後一切靜靜地錯下去。
  5. 閾值不能照抄:不同來源的影像,亮度尺度不同。同一個「抽取雲層」的門檻值,換一個來源就會把整片晴空抽成一層薄霧。
26.5 °C — THE THRESHOLD

尾聲:那條線

今天畫在地球海面上的那條白線,是 26.5°C。

颱風是一部熱機:它靠溫暖海水蒸發上來的水氣當燃料。海溫低於這條線,引擎就會熄火。所以那條線是熱帶氣旋的生死界線——線的裡面它能活,線的外面它會死。

今天,颱風巴威越過了那條線。它從 940 百帕、每秒 40 公尺的強颱,一路垮到 985 百帕、每秒 20 公尺。它死在自己再也走不回去的那條線外面。而這整個過程,被我們自己做的儀器完整地記錄了下來。

而這份報告裡的七條原則,講的其實也是線:
真實與虛假之間的線、知道與不知道之間的線、查證過與沒查證之間的線。

工程的誠實,就是把那些線畫清楚——然後不跨過去。

← 這份實錄在講的成品
操作風眼觀測儀
教學版本 →
取用三版教材(科普/教案/演講稿)