用 AI 以 275 次提交更新我的 Side Project
最近我任職的公司迎來了年中休假,大家都在差不多的時間放了兩週的假。身為主管,我過去大多是用 AI 工具來做程式碼審查和技術探索,而不是真正拿來寫程式,我想改變這一點。
於是我利用這段休假埋頭改造我的 side project——Gifty Weddings。我之前已經在2016 年改用 Go 後端,又在2019 年改用 Elm 前端。但這次我有兩個目標:
- 把它從單純的婚禮禮物登記系統,升級成婚禮網站建置工具。
- 學習如何用 AI 工具寫出高品質的程式碼。
在同事的推薦下,我大部分的程式開發都使用 Claude Code 搭配 Opus 5。一些較小的任務則用Pi搭配開放權重的 GLM 5.2 模型。當然,我也有動腦。
開個玩笑,但我真的認為動腦正是區分大量生產垃圾與打造出讓人引以為傲的產品的關鍵。我們終究還是工程師。
在這篇文章裡,我會談談我對 AI 的懷疑,也會分享我認為讓這個專案成功的原因,以及為什麼我做得很開心。
我對 AI 的懷疑
我對 AI 抱持懷疑已經有一段時間了,一開始是早期有個 AI 聊天機器人愛上了《紐約時報》的記者,後來則是因為開始得處理大量由「貢獻者」產出的 AI 垃圾,懷疑就更深了。
我早在 2024 年就試過用它來寫程式,當時並不覺得驚豔。那時候,我花在收拾它產生的東西的時間,比我自己動手寫還要多。
最近,我又試了一次,一次到位幫我太太做了室內設計網站,然後又用它來修GoAWK裡的各種 bug(其中一次 Opus 4.6 還相當優柔寡斷)。
這兩次都讓我印象深刻:做網站那次是因為我本來就不愛寫 CSS,修 bug 那次則是因為它真的加快了流程,還給了我不錯的點子。
我的做法
首先,我算是個經驗相當豐富的網頁開發者。這代表我能有效地引導流程、審查 AI 代理產出的結果。順帶一提,我對 AI 最大的擔憂之一,就是新手開發者會想走捷徑,跳過這些得來不易的經驗累積。
再來,我是站在既有的基礎上開發。我從舊站的 CSS 樣式表(本身又是基於Skeleton)、大半個 SQL 資料庫結構,以及一份我想做的功能的規劃開始。此外,我還參考舊的 Gifty 程式碼,親手寫了最初的 Go 伺服器和幾個套件。我先用自己想要的程式碼風格打好基底。
接著我改採反覆迭代的開發方式,而不是想一次到位:每個階段我都保有技術與創意上的主導權。每次更動程式碼,我會先提出功能需求——通常就是幾句話的提示——然後審查它產出的程式碼,並在瀏覽器裡實際測試功能。
我做了適度的程式碼審查。我得放掉一部分對程式碼工藝的堅持——它寫的程式碼風格稱不上完美,至少很多地方不是我會那樣寫。當然,我會指出 bug、挑戰結構上的問題,但整體來說,我對它寫的程式碼還算滿意。
不過,我沒有仔細審查測試。AI 代理似乎會寫一大堆測試——有時多到離譜,我刪掉了幾個我覺得效益不大的。一開始我還會看一下細節,但到後來就只是大致掃過而已。
過程中我學到了不少事:
- LLM 寫的註解都非常冗長。我得不斷叫它精簡一點、只寫一行摘要。在一次「精簡註解」的提交裡,我把註解從大約 2500 行砍到 1500 行。
- 當我讓 Claude 安裝 headless 瀏覽器、自己截圖後,它寫 HTML 和 CSS 的能力大幅提升。在那之前,我得自己截圖再手動上傳。現在它像有了超能力:會自己啟動伺服器、用應用程式真正的表單加入假資料,再用 Chromium 存成 PNG 截圖並「檢視」它們。
- 話雖如此,每次更動都截圖處理會耗掉大量 token。最後我只在做較大幅度的前端更動時才叫它這麼做。
- 即使已經用容器隔離(我用的是 Canonical 的Workshop),Claude 還是會做出惱人的事。有幾次它執行了像
rm -rf $SOMEVAR/*.png這樣的指令,但因為SOMEVAR沒有設定,結果把我正在用的測試照片全刪了。我在它的記憶裡加了一些規則想阻止它——總之,LLM 一定要在容器或虛擬機裡跑。 - 不要把所有工作都放在同一個對話裡做。我一開始就是這樣,但脈絡很快就變得超長,沒多久就超過了 Claude Pro 的各種限制。所以我學會了compaction,開始定期開新的對話。
接下來看看我做了哪些功能。
功能
Gifty 讓新人可以建立一個簡單的多頁式婚禮網站,包含照片、文字和禮物登記清單。(舊版 Gifty 只支援禮物登記的部分。)

新人可以用 Markdown 區塊撰寫文字、上傳照片(會自動縮小並儲存在 Tigris 上)、新增與重新排序頁面等等。當然,我會收一點費用;付款是透過 Stripe 處理。
賓客可以瀏覽新人的網站,並在禮物清單上勾選已選購的禮物。
但我最喜歡的功能,是從舊版 Gifty 沿用來的:新人可以一鍵試用。
技術堆疊
我喜歡保持簡單,所以用了以下技術:
- Go 後端,並盡量少用非標準函式庫的依賴:用於上傳的 AWS SDK、Stripe SDK、圖片縮放函式庫、Markdown 渲染器、
modernc.org/sqlite模組,以及「算是標準函式庫」的golang.org/x/crypto模組。 - 超棒的 SQLite 資料庫。
- Htmx 處理較動態的部分:禮物登記清單和頁面編輯功能。
- 以及在適合的地方加上一點原生的 JavaScript。
網站代管在Fly.io 上,我非常推薦這類用途的服務:fly deploy 讓部署變得超級簡單,而且價格便宜。
滿懷感激
完成新網站大約花了 10 個完整的工作天。我非常感謝 AI 工具,特別是這次的 Claude。我跟我太太說,如果沒有 AI,大概要花三倍的時間。
最讓我印象深刻的其中一件事,是 Claude 把舊的禮物登記系統——一個 Go JSON API 搭配 Elm 前端——移植到新版本,變成 Go HTML 端點搭配截然不同的 htmx 前端。它幾乎一次就完美搞定,讓我又驚又喜,也省下了大量時間。
另一件它幾乎一次到位(加上後續幾個 bug 修正)的事,是做出了資料庫遷移工具,把舊的 Gifty 資料庫遷移到新版。雖然不是什麼高深技術,畢竟兩個資料庫很相似,但結構上還是有一些差異,我原本預期會需要更多次反覆修改。
但既然我整體上對 AI 抱持懷疑,為什麼還會這麼樂在其中?我覺得有兩個原因:
第一,我喜歡動手打造東西。大約 10 天內就完成了一個實用又好看的網站。
第二,我享受寫程式這門工藝,而我依然有那種感覺。我會先想好下一個功能,請 AI 寫程式、審查程式碼、修 bug,然後提交。不斷重複,做了 275 次。小的功能花 10 到 15 分鐘,大的要一兩個小時,但能持續朝目標推進的感覺真的很棒。
我依然有很多顧慮,也希望我們不會用這些工具去建造一座通天塔,搞到上帝得來挫挫我們的銳氣。但我還是很感謝這些新工具。
最後一件事:如果你最近要結婚,或認識要結婚的人,歡迎把新的GiftyWeddings.com 推薦給他們。如果你想結婚但還沒有對象——抱歉,那就是另一個網站的事了!
隨機一篇部落格
留言
登入後參與討論