昨天那張表寫完之後,照理說下一步應該是開始做 AI。
我沒有。
第一版是一個靜態網頁。四個檔案,零 API,連一行跟 AI 有關的程式碼都沒有。
這篇講為什麼。
我先把當時的處境攤開來。那十一題要回答的知識,散在這些地方:
五個地方,五種格式,而且沒有任何一條線把它們串起來。
如果我這時候直接接上 AI,我會做出什麼?一個把這團東西照原樣吞進去、然後照原樣吐出來的東西。它會很會講話,而且會很有自信。
在你有東西可以檢索之前,談檢索是沒有意義的。
(這句話的完整版是這個系列最後的結論之一,Day 30 會回來。)
但還有一個更實際的理由,而且我覺得它更重要:
我想先知道「把知識寫下來」這件事到底有多難。
這是一個成本很低的實驗。如果連寫一個靜態網站、把已知的東西整理清楚我都做不到,那後面所有 AI 的計畫都是空的。
四個檔案:
index.html 版面骨架
style.css 樣式
app.js 切換頁面、語言切換、Q&A 板
pages.json 內容
內容是三塊:
這裡有一個決定,當時只是隨手做的,後來卻很關鍵:
內容不寫死在 HTML 裡,獨立成 pages.json。
當下的理由很單純:我知道內容會一直改,而我不想每改一句話就動到版面。
但它真正的價值是後來才出現的——那份 pages.json 是這整個專案的第一個「知識的資料格式」。 我第一次被迫回答:一個「頁面」的知識,到底由哪些欄位組成?
這個問題,我在後面統整 89 張卡的時候又遇到了一次,而且那次的代價大得多。(Phase 2 會講。)
部署在 Cloudflare Pages,一行 wrangler 就上去了。
兩個選項其實都很簡單:Cloudflare Pages 和 Vercel,都免費、都一行指令。我選了前者,理由跟技術沒什麼關係。
理由一:免費額度比較寬,而這份資料只會越長越大。
這個網站不會停在四個檔案。知識庫的內容只會增加,不會減少。
與其先住進比較小的房子、等到塞不下再去找更大的容器搬家,不如一開始就選大的那個。搬家的成本不是只有搬家本身,是搬家那天你手上其他事情全部得停下來。
理由二:建置期間我不想去想「會不會太大」。
這一點在做的當下感受特別明顯。當你一邊在整理知識、一邊要擔心「這樣塞下去會不會爆掉」,你會不自覺地開始自我審查——少放幾張圖、少寫幾頁、這塊先不要好了。
那是最糟糕的限制,因為它影響的不是成本,是內容本身。
理由三——這一條才是真正的理由:在沒有人使用之前,你要不到錢。
一個內部工具上線之後,需要一段時間培養使用習慣。在那之前它的使用數據很難看,而這是必然的,不是它不好。
而在使用習慣還沒養成的階段,跑去提「這個工具需要擴充容量,所以需要預算」——不太可能成功。 你手上沒有任何數據能支持這筆錢。
所以架構必須在一開始就設計成:在零預算的狀態下,一路撐到「有人在用」為止。
這條線後面會一再出現。它決定了我不 fine-tune、決定了我用本地小模型、決定了整條管線把推理成本挪到建置期。不是因為那樣比較優雅,是因為那樣不用錢。
這是這篇我最想講的部分。
一個很自然的驗收方式是:我自己從頭讀一遍,覺得寫得很清楚,那就完成了。
我沒有這樣做。 當時我寫下的驗收方式是這樣:
「我之後會請其他人或其他 AI 看著這個網頁,從建立 account 到匯入資料,最後確認訊息與行為有執行。我會給他們一些指令來模仿新人。」
差別在哪?
因為寫的人永遠看不出自己漏了什麼。
那些被漏掉的步驟,不是你偷懶不寫,是你在讀的時候腦袋自動幫你補上了。你看著「登入後點左側選單」這句話,腦中會自動浮現那個選單長什麼樣、要先展開哪一層。一個新人看到的只有一句話。
所以驗收不能由知道答案的人做。驗收要由不知道答案的人跑一遍。
這跟昨天那張表其實是同一件事:先定義怎樣算過,再去做。 差別只在昨天定義的是「要能回答什麼」,今天定義的是「誰來判斷它回答得對不對」。
而「找 AI 來扮新人」這招,當時我覺得很聰明:它不會客氣、不會因為跟你熟就自動腦補你們公司的慣例、而且要幾個就有幾個。
現在回頭看,這裡其實埋了一個問題:AI 會不會「腦補常識」?
它跟人一樣有自動補完的本能,只是補的內容不是你們公司的慣例,是它從網路上學到的通例。一份文件如果漏寫了某個步驟,而那個步驟剛好是業界常規,AI 扮的新人會順利走過去——然後給你一個假的通過。
這件事後來以更嚴重的形式又出現了一次。(Day 9、Day 10。)
寫到今天為止,這一步我還沒有做完。
驗收方式定好了、要給的指令想好了、團隊裡也確實有一位新人可以當最好的受測者。但「真的有人從頭走一遍、把卡住的地方記下來」這件事,還沒有發生。
我本來可以不寫這段,或者寫成「這部分之後會補」然後帶過去。
但那正好是這整個系列在批評的事——看起來完整,實際上沒有被驗證過。
而一個定好卻沒有執行的驗收條件,價值是零。它跟沒有驗收條件的唯一差別,是它讓你比較安心,而那是最糟的那種差別。
所以這裡先記一筆帳:Day 29 我會回來報告這一格到底有沒有被填上。
如果到時候還是空的,我也會照實寫。
第一版上線之後,有一個排版問題:文字只用到大約一半的寬度就斷行了,右邊空一大片。
這是小事,改掉就好。
但它讓我注意到一件事——我沒有辦法一眼看出這個網站哪裡壞掉。
排版歪掉是看得見的。那看不見的呢?如果是內容錯了、某個步驟少了一句、某個說明跟現在的畫面對不上,我要怎麼發現?
一個知識庫最可怕的失敗不是它掛掉,是它好好地站在那裡,說著已經不成立的話。
明天那個 bug 會把這件事講得更清楚——因為它是「整個站白畫面」那種等級的壞,而我一開始甚至以為是三個不同的問題。
最後講一下這一版做不到什麼,因為那就是後面 26 天的起點。
這個網站可以告訴你:這個頁面是什麼、這個流程怎麼走。
它沒有辦法回答昨天那十一題裡的任何一題。
它答不出「這張卡跟另一張卡是同一塊嗎」,因為它根本不知道卡片的存在;它答不出「這個當初為什麼決定不做」,因為那些理由從來沒有被寫下來過。
它是一份文件,不是一個可以被問的東西。
但它必須先存在。因為它逼我回答了一個我原本會跳過的問題:知識到底長什麼樣子、由哪些欄位組成?
那個問題的答案,後來變成了整條資料管線的第一個 schema。
明天講這個網站的第一個 bug:一行 const 讓整個知識庫變成白畫面。
而且我一開始以為是三個 bug。