霧中前行, 第 1 篇: 那張試算表
「霧中前行」第一篇 — 一個關於建造 Ridgeline 的系列,Ridgeline 是為 Outward Bound Hong Kong 設計的野外糧食配給決策引擎。
雞尾酒會
Wilson 帶我去香港會所參加五十五周年慶典。我是他的同伴 — 請柬上寫着 Ms. Augustin Chan。我們是衝着飲品和食物去的。
一個高大的白人男子向我們走過來。Wilson 立刻轉身:我們去拿點食物吧。 我心想 — 這人好心走過來,我們在場也不認識誰,不如跟他聊聊。
他原來是 Aaron Funnell,Outward Bound Hong Kong 的行政總監。
我提到 Digital Rain,我的公司。我提到 AI Tinkerers HKGBA,我所參與的社群。我推銷我本來想推銷的東西:青年工作坊、AI 素養、裝備下一代。Aaron 聽着。很有禮貌。但 OBHK 是做戶外活動的 — 划艇、行山、露營。不是 hackathon。
然後他說了類似這樣的話:你知道我們真正頭痛的是什麼嗎?我們的食物供應鏈。
兩星期後,Aaron 發了電郵給他的團隊。大意是:一個義務項目,改善 OBHK 的野外口糧系統 — 餐單、訂購、包裝、飲食需求、卡路里追蹤、食物浪費。他抄送了 Rocky(他們的營運主管)和幾位同事。電郵提出要安排一次實地考察 — 參觀口糧系統、了解如何打包、搬運和煮食。午餐在飯堂。
我完全不知道自己將要面對什麼。
實地考察
的士載我沿着一條沒有路標的路上山,盡頭是一個美麗的沙灘和一片意想不到的海景。OBHK 的設施就在海邊。
先是一個小組會議 — Aaron 的團隊、互相介紹、講述我如何從雞尾酒會到了這裏。然後,就在午餐前,Rocky 把我拉到一旁。
Rocky 是一位資深導師,轉任營運主管的時間不算長。他負責將幕後的運作現代化 — 倉庫、訂貨、打包。有一位物資主任處理日常事務,但 Rocky 是那個嘗試為流程建立架構的人。
那個試算表是他的 — 他嘗試把配給工作系統化,讓其他人也能跟着做。那是一個 Excel 檔案,計算為 14 名青少年在五日遠征中需要購買多少食物。涵蓋 4 頓晚餐、3 頓午餐、4 頓早餐,以及一份共用零食包。第一天從晚餐開始(參加者已吃過午餐才到達)。第五天早餐後結束。基本內容 — 數量和成本。還沒有處理飲食限制。
他帶我參觀了倉庫、打包站、供應商關係。我在倉庫旁邊的小辦公室架好手機錄音,他解釋一切 — 限制條件、季節性、保質期邏輯。六段錄音,用廣東話和英文。我之後用 Whisper 轉錄,再整理成結構化筆記。1
Rocky 描述的餐單設計很巧妙。初期用新鮮食材和完整烹飪 — 肉醬意粉、咖喱烏冬。後期轉為即食碳水和煲水 — 即食飯、即食麵。午餐是冷盤組裝:麵包沙律、墨西哥卷。整個編排蘊含着一種我一開始沒能完全領會的智慧。
這是保質期排序。沒有野外雪櫃。營地有發電機但不是廿四小時運作。所以餐單是漸進式降級:
| 日 | 新鮮蔬菜 | 蛋白質 | 複雜度 |
|---|---|---|---|
| 1 | 高(5 種) | 新鮮(雞肉腸、豬肉漢堡) | 完整烹飪 |
| 2 | 中(葉菜 + 耐放) | 混合(火腿、魚蛋) | 中等 |
| 3 | 低(只有耐放) | 罐頭(吞拿魚、午餐肉) | 低 |
| 4 | 極少(椰菜、洋蔥) | 罐頭(午餐肉) | 煲水即可 |
| 5 | 無 | 罐頭(肉鬆) | 煲水即可 |
這不是隨意安排的。這是 Rocky 多年野外經驗,嘗試用格子和公式捕捉下來。
不算問題的問題
事情是這樣的。試算表是可以用的 — 就它做的事而言。它處理了基本需求:14 人的數量和成本。但這是 Rocky 系統化流程的初步嘗試。它不處理飲食限制。它對不同人數的調整效果不好。它沒有記錄為什麼第三天用罐頭蛋白質而不是新鮮的,也沒有記錄哪個供應商有什麼貨。
這是沒有人會預先警告你的需求收集:有時候你收集不到完整的需求,因為根本沒有人擁有完整的需求。知識是分散的 — 一部分在試算表裏、一部分在物資主任的習慣中、一部分在 Rocky 多年帶隊的腦海中。需求收集對每個人來說都很痛苦,所以你收集到剛剛足夠做出合理設計決定的資訊,然後繼續前進。
試算表寫着「意粉:1.5kg」。但沒有說明那 1.5kg 是給 14 人的(應該按人數線性調整)還是一鍋的用量(固定不變直到需要第二鍋)。每個數字背後的意圖都沒有記錄 — 只有數字本身。所以我們最後做了很多第一原理推算:他們為 14 人的一組買了 N 包意粉,那我們假設是平均分配到每人。這種推理,應用到餐單上的每一個項目。
實地考察之後,我回信給團隊。我的第一直覺:建一個輕量級的腦力激盪和數據收集工具 — Rocky 和其他人可以用來即時發現規律和建議的東西。不是指導性的。未知數太多,食物必須如何打包和設計才能適用於野外的限制也太多。
我把項目命名為 Ridgeline。Ridgeline 是你沿着山脊頂部走的那條線 — 是暴露程度最高的路徑,每個決定都至關重要,因為你已經投入了。你不能帶太多(重量拖慢速度),你不能帶太少(不夠會有危險)。
這個名字切合 Outward Bound 的場景。也切合我對這個項目的感覺 — 暴露、投入、前路未明。
工具需要理解什麼
處理完實地考察的錄音、評估文件和試算表之後,我寫了一份塑形文件。核心需求:
R0: 支援探索性思考配給 — 而非指導性優化。
R1: 在零野外數據的情況下從第一天起就有用。
R2: 隨着真實數據 — 浪費、消耗、回饋 — 的累積而愈來愈有用。
R3: 將現有餐單模板中隱含的邏輯變成顯式的、可查詢的。
R4: 處理「如果」情境 — 不同人數、餐單替換、飲食限制覆蓋。
最後一條是之後所有出錯的根源(以有啟發性的方式)。「如果我把人數從 14 改成 20 會怎樣?」看似簡單的問題。結果它是揭露試算表裏每一個隱藏假設的那個問題。2
第一個 commit
我搭建好項目:Next.js 15、Supabase、Google Auth、雙語支援(英文和繁體中文,因為 Rocky 講廣東話,而且不是每位 OBHK 員工都能輕鬆閱讀英文)。我給團隊開了 @ridgeline.works 的電郵帳號用於驗證。
第一個真正的功能是食材數據庫 — 從試算表中導入了 67 個項目。每個食材有類別(碳水化合物、蛋白質、新鮮蔬菜、醃製品、調味料)、單位類型和保質期等級。第二個功能是餐單模板檢視器:試算表的五天餐單,數碼化為 menu_templates、meals 和 meal_items 表,以逐日分解的方式呈現。
clients/outward-bound-hk/assessment.md | 222 +++
clients/outward-bound-hk/shaping.md | 461 ++++++
clients/outward-bound-hk/ration-menu-assessment.md | 139 +++
14 files changed, 3129 insertions(+)
在寫出任何一行應用程式碼之前,先有 3,129 行文檔。這個比例對一個最難的部分不是建造、而是理解要建造什麼的項目來說,感覺是對的。
我還不知道的
此刻,試算表已經數碼化了。食材在數據庫裏。餐單模板在手機上顯示得很好看。看起來像是有進展。
但我還沒有碰 scaling。我還沒有問過改變人數會發生什麼事。我還沒有看過卡路里。我還沒有想過如何處理試算表完全沒涉及的飲食限制 — 清真、素食、那個兩者都是的小朋友。
這些問題中的每一個,都會打破我以為自己已經理解的東西。
下一篇:第二篇 — The Scaling Problem,把人數從 14 改成 20,輸出卻幾乎沒有變化,以及 35 個項目被重新分類。