Vibe Coding 實戰課 — Stage 3 · 造系統
所有的坑走過一遍 — 然後用一份文件避開它們
按 → 或空白鍵開始
這堂課的節奏
先自由發揮注意事項 → 分類所有問題 → 引出 spec.md → 用 spec.md 重做 → 體感差距
每一輪新增一層理解,前面遇到的問題都是教材
選時段、填資料
收到確認信
設定可預約時段
查看預約清單
防衝突、防過期
自動寄通知信
ROUND 1 · 0:00–0:25
用一句話指令,看 AI 自由發揮的結果
做一個諮詢預約系統 讓別人可以選時段預約 我能看到預約清單
不給架構指引、不指定技術選型、不定義資料結構
用最自然的方式描述需求,看會發生什麼事
同樣的需求、同樣的工具、同樣的時間
AI 沒有收到規格 → 每次自由發揮 → 每個人拿到完全不同的東西
M2-2 踩過的坑又來了 — 沒有指定儲存方式,AI 預設用 localStorage
沒有時段衝突防護 — 兩個人同時點同一個時段,都預約成功
沒有時間驗證 — 昨天的時段今天還顯示「可預約」
使用者不確定預約是否成功 — 只有畫面閃一下
改一個功能壞全部 — 資料邏輯和畫面邏輯纏在一起
加功能時前後矛盾 — 第一次用物件,第二次用陣列,第三次又改回來
問題不在 AI 的能力 — 而是你沒有給它規格
接下來把所有坑攤開,找出共同根因
ROUND 2 · 0:25–0:45
不只是預約系統 — 是整個課程遇到的所有問題
| 類別 | 典型問題 | 根本原因 |
|---|---|---|
| 資料 | 消失 / 不一致 / 時段衝突 | 沒定義資料結構 |
| 安全 | Key 外洩 / 重複提交 | 沒定義安全規則 |
| 架構 | 前後端混亂 / 改壞 | 沒定義分工 |
| AI | 每次不同方案 / 衝突 | 沒給明確規格 |
| 範圍 | 越加越多 / 失控 | 沒定義功能邊界 |
| 驗證 | 過期時段還能選 / 沒通知 | 沒定義業務規則 |
不是寫給人看的文件
是寫給 AI 執行的規格
沒有 spec.md 的系統
等於沒有藍圖的建築
資料、安全、架構、AI、範圍、驗證
六類問題的解法都是同一個:
開始前寫清楚
ROUND 3 · 0:45–1:10
用 Claude Code 輔助,為預約系統寫規格書
系統要做什麼 — 列出所有功能點
前端、後端、儲存、通知 — 每一層用什麼
哪些 Sheet、哪些欄位、狀態怎麼定義
幾支 API、輸入什麼、回傳什麼
誰能做什麼、怎麼驗證、Key 放哪裡
# 諮詢預約系統 spec.md ## 功能需求 - 顯示可預約時段(排除已過期、已被預約的) - 預約(填姓名 + Email + 選時段) - 預約後寄確認信給預約者 - 講師收到通知信(含預約者資訊) - 講師可查看所有預約清單
每一條就是一個驗收標準
沒列到的,AI 不會主動做
## 技術選型 - 前端:HTML / CSS / JS(GitHub Pages) - 後端:GAS(API Proxy + 資料存取 + 寄信) - 儲存:Google Sheet - 通知:GmailApp
技術選型必須由人類決定,不是 AI
AI 會根據你的選型建立一致的架構
不指定 → AI 每次選不同的,後續改不動
## 資料結構 - Sheet "時段" 日期 / 開始時間 / 結束時間 / 狀態(可預約/已預約/已過期) - Sheet "預約" 時段ID / 姓名 / Email / 預約時間 / 確認信狀態
資料消失 → 因為沒指定儲存位置
時段衝突 → 因為沒有「狀態」欄位
寫清楚資料結構 = 一次解決兩個問題
## API 端點 - GET /slots → 取得可預約時段(自動排除過期 + 已預約) - POST /book → 預約(帶時段ID + 姓名 + Email) → 寫入 Sheet + 寄確認信 - GET /admin → 講師查看預約清單 → 後端檢查 admin session / token
不要把 key 放在 URL
secret 放 GAS PropertiesService
前端只送一次性或表單驗證資料
## 安全規則 - 後端驗證時段是否仍可預約(不信任前端) - 同一 Email 同一時段不能重複預約 - admin 端點需要 Key 驗證 - 前端不存任何 Key
安全規則不寫 → AI 不會主動幫你想
「不信任前端」這四個字,值整個系統的安全
# 諮詢預約系統 spec.md ## 功能需求 - 顯示可預約時段(排除已過期、已被預約的) - 預約(填姓名 + Email + 選時段) - 預約後寄確認信給預約者 - 講師收到通知信(含預約者資訊) - 講師可查看所有預約清單 ## 技術選型 - 前端:HTML / CSS / JS(GitHub Pages) - 後端:GAS(API Proxy + 資料存取 + 寄信) - 儲存:Google Sheet - 通知:GmailApp ## 資料結構 - Sheet "時段" 日期 / 開始時間 / 結束時間 / 狀態 - Sheet "預約" 時段ID / 姓名 / Email / 預約時間 / 確認信狀態 ## API 端點 - GET /slots → 取得可預約時段 - POST /book → 預約 + 寫入 + 寄信 - GET /admin → 講師查看清單,後端檢查 admin session / token ## 安全規則 - 後端驗證時段是否仍可預約 - 同一 Email 同一時段不能重複預約 - admin 端點檢查 admin session / token - 不要把 key 放在 URL - secret 放 GAS PropertiesService - 前端只送一次性或表單驗證資料
15 分鐘的規格 → 省下 3 小時的除錯和重做
這就是「先規劃再動手」的體感
## 功能
預約系統
AI 只知道「預約」兩個字
其餘全部自行決定
## 功能需求
- 顯示可預約時段
- 排除已過期+已預約
- 預約後寄確認信
每一條都可驗收
AI 不需要猜
寫在 spec.md 裡的 → AI 照著做
沒寫在 spec.md 裡的 → AI 自己決定
你不想讓 AI 決定的事,就寫進去
ROUND 4 · 1:10–1:35
同一個系統、同樣的時間 — 感受差距
清空專案 → spec.md 放進去 「按 spec.md 建這個預約系統」
把 R1 的成品全部清掉
只放 spec.md 進去,一句話啟動
25 分鐘,跟 R1 完全相同的時間
規格清楚 → 不需要反覆確認
spec 有寫 → AI 照做
spec 有寫 → AI 照做
spec 有寫 → AI 照做
在現有系統上加上「取消預約」功能 預約者收到確認信後,信裡有取消連結 點取消 → 時段恢復為可預約
架構亂 → 不知道改哪裡
改了一個 → 壞了三個
AI 重新生一版 → 跟原本矛盾
API 結構清楚 → 加一支端點
資料結構清楚 → 加一個狀態
AI 照架構加 → 不壞原有功能
有 spec.md 的版本 → 功能完整、架構乾淨、可擴展
講師下課後直接部署,省下自己開發的時間
差別不在時間、不在工具、不在 AI 的能力
差別在你有沒有先寫規格
spec.md 不是增加工作量
是把「後面會踩到的坑」提前在前面解決
ROUND 5 · 1:35–1:50
R1 和 R4 並排 — 用數據看差距
R1 的 35% 功能裡,還有一半是壞的
R4 的 95% 功能,全部通過手動測試
R4 加「取消預約」功能只花 3 分鐘
R1 試了 15 分鐘,加完反而壞了原有功能
R1:你說一句,AI 問三句,做出來不對,再改
R4:你給 spec,AI 直接做,一次到位
Product Requirements Document
產品經理寫的功能需求書
定義「做什麼」
Request for Comments
工程師寫的技術提案
定義「怎麼做」
我們的簡化版
PRD + RFC 的精華
一個檔案搞定
spec.md 是工程界數十年經驗的簡化版
不需要學 PRD 的完整格式,掌握核心就夠
| # | 常見問題 | 學到什麼 |
|---|---|---|
| 1 | 同時段被多人預約 | 業務邏輯驗證(後端防衝突) |
| 2 | 過期時段還能選 | 時間驗證要在後端做 |
| 3 | AI 每次給不同架構 | 沒有藍圖 = AI 亂蓋 |
| 4 | 加功能改壞原有功能 | API 規格 + 可擴展性 |
| 5 | spec.md 太簡略 | 關鍵決策要人類做 |
六個維度全面碾壓 — 因為規格清楚
AI 的能力一直都在,差的是你給它的指引
ROUND 6 · 1:50–2:00
帶走模板 + 理解三份文件的分工
# [專案名稱] spec.md ## 功能需求 - [ ] 功能 1:描述 + 驗收條件 - [ ] 功能 2:描述 + 驗收條件 - [ ] 功能 3:描述 + 驗收條件 ## 技術選型 - 前端:(框架 / 部署位置) - 後端:(語言 / 服務) - 儲存:(資料庫 / Sheet / JSON) - 通知:(Email / TG / Line) ## 資料結構 - 表/集合名稱 欄位 1 / 欄位 2 / 欄位 3 / 狀態
## API 端點 - GET /endpoint1 → 說明 - POST /endpoint2 → 說明 + 輸入 + 回傳 ## 安全規則 - 驗證邏輯(後端不信任前端) - 權限控制(誰能做什麼) - Key 管理(放哪裡、不放哪裡) ## 範圍定義 - 第一版做:功能 A / B / C - 第一版不做:功能 D / E - 未來考慮:功能 F
明確寫出「不做什麼」
防止 AI 自行加功能 → 系統膨脹失控
用模板,為你下一個想做的系統寫 spec.md 大綱
不用寫完 — 先把五大區塊的標題和重點列出來
AI 的個性和偏好
跨專案不變
「你是什麼樣的 AI」
這個專案的規格
每個專案獨立
「這次要做什麼」
AI 的技能方法
跨專案共用
「用什麼方法做」
# 開發偏好 - 使用繁體中文回應 - 程式碼加註解 - 優先使用 GAS + Google Sheet - 錯誤訊息要對使用者友善 - 不要用 emoji
放在 ~/.claude/CLAUDE.md
所有專案共用 — AI 在任何專案都會遵守這些偏好
你的專案/ ├── spec.md ← 這個專案的規格 ├── index.html ← 前端 ├── gas/ ← 後端 │ └── Code.gs └── README.md
spec.md 放在專案根目錄
AI 開始工作前會先讀這份文件
後續所有決策都以 spec.md 為準
# GAS API 部署 Skill 1. 建立 GAS 專案 2. 寫 doGet / doPost 處理函式 3. 部署為 Web App(設為所有人可存取) 4. 測試 API 端點回應 5. 把 URL 貼回前端設定
Skills 定義「怎麼做」— 標準化的工作流程
寫一次,所有專案都能用
不需要每次重新教 AI 同樣的步驟
CLAUDE.md = 員工的個性(他是什麼樣的人)
spec.md = 這次的工作單(今天要做什麼)
Skills = 公司的 SOP(用什麼方法做)
不只學了什麼,是想法怎麼變了
從「請 AI 幫我做事」→ 設計 AI 能執行的系統
下一堂課 — M3-4
下一堂課:GitHub Actions + Cloudflare Worker + 永遠有選擇
M3-3 完成