Day 08 把一份 Plan 往下拆成 Task,讓 AI 知道接下來有哪些工作要做。
不過只要其中一項工作會讀資料、送出申請,或改變畫面狀態,事情又會回到另一個很實際的問題
資料從哪裡來?要送什麼出去?後端回來之後,畫面又該怎麼走?
如果這些沒有先講清楚,AI 就算把表單畫得很完整,還是可能把資料流接錯。按鈕能點,不代表功能真的接起來。

一份 Task 可以寫得很清楚:調整表單、送出申請、確認結果。但只要碰到資料,AI 還是得回答不少問題。使用者選了一個項目,應該查哪一份資料?送出時要帶哪些內容?後端回傳成功後,是顯示訊息、留在原頁,還是帶使用者到下一步?
只有功能描述時,這些細節很容易被 AI 補成它覺得合理的樣子。對畫面來說,那常常已經太晚了。
我在第二代把 Notebook 功能移到 Web 時,就很早遇到這個分工問題。當時前端使用 Vue 與 Element Plus,後端是 FastAPI;因此 API 規格很重要,這是我們服務在溝通的方式,這張表單會使用哪些 API?每支 API 收什麼、回什麼?
我共同參照就是 Swagger。
| 只有功能描述 | 有 API 規格 |
|---|---|
| AI 得猜資料來源、輸入內容與回傳後處理 | 呼叫時機、input、output 與後續畫面行為都能先確認 |
Task 寫出要做什麼;API 規格則讓 AI 知道資料要怎麼進出。
第二代沒有使用 TypeScript。前端和後端的 API 規格以 Swagger 提供;有變更時,我會和後端同仁口頭討論,也會在每週專案會議中確認。這不是一套很複雜的協作制度,但對當時的我很有用。
只要我能清楚說明「這張表單要用哪些 API」,並理解它們的 input/output,前端就能往下開發。AI 可以協助我把資料帶入、按鈕事件和送出流程串起來;我不用每次從頭描述資料大概會長什麼樣子。
用一個匿名化的流程來說,使用者先在表單選擇專案或申請項目,前端依 Swagger 查詢可選資料;填完申請內容後,再依規格送到後端。後端處理完成後,前端根據回傳結果,決定接下來要顯示什麼。
使用者選擇專案/申請項目
↓
前端依 Swagger 查詢資料
↓
表單顯示可選資訊
↓
使用者完成填寫並送出
↓
前端依 API 規格處理回傳結果
後來我才更有意識到,Swagger 背後對應的是 OpenAPI 這類 API 描述規格。它讓不讀後端原始碼的人,仍能理解 HTTP API 接受什麼、回傳什麼;對我而言,這份說明也成了 AI 實作前端資料流時很高訊號的 context。OpenAPI Specification
我不需要把整份 Swagger 都塞進 prompt。這次的畫面會用到哪些 API、哪幾個 input/output 和成功或失敗後的行為,才是 AI 真正需要讀的部分。
第二代也不是單純把既有 API 接到前端。後端 API 本身同樣用 Vibe Coding 開發,只是有一部分既有的資料庫 function 被沿用。例如使用者在表單選擇一個專案後,後端可以透過既有 function 取得這個專案相關的人員或資料;前端不必直接碰資料庫,也不需要讓 LLM 自己拼 SQL。
這是當時 SQL/JSON 錯誤相對少的一個原因。主要規則已經放在後端 function,LLM 比較像協助把 function、API 和畫面流程串起來,而不是自己猜查詢規則。
但這不表示業務邏輯消失了。API 規格只處理資料怎麼交換,不能替我決定使用者怎麼操作。
Day 02 談到的個資資料表抄寫功能就是一個例子。API 可以提供資料和欄位資訊,卻不會替我決定全選按鈕該怎麼運作、個資欄位要選 Hash 還是留空白、畫面要怎麼讓同仁理解這些差異。那些問題仍要由需求和 UI 設計說清楚。
| API 規格/後端 function 能先界定 | 還需要人與前端決定 |
|---|---|
| input、output、既有資料取得,以及部分規則封裝 | 何時呼叫、畫面流程、操作限制與使用者理解 |
所以我不會說「有 Swagger 之後 AI 就不會做錯」。它只是少掉了一大塊不必要的猜測,讓我把時間放回真正還需要判斷的地方。
第二代沒有 mock。當時我主要依 Swagger 與後端 API 往下開發。到了第三代,整個流程拆到獨立環境做開發,這個環境不能直接連到後端 API,前端開發卡在一個很現實的地方:連資料都拿不到,就很難確認畫面載入、送出、空資料或錯誤處理到底長什麼樣子。
所以這階段加入 mock 。在本機開啟 mock 設定時,前端會取得擬真情境資料,讓我可以先把流程操作一遍,確認畫面和流程是否正確。

它能幫我確認的事情很具體:畫面是否拿得到正確資料、送出後會不會進到下一步、空資料與失敗狀態有沒有被處理。這讓我能先確認本機流程正確;但正式環境能不能順利串接,仍要用真實後端再驗證一次。
| mock 可以先幫我確認 | 正式串接仍要再驗證 |
|---|---|
| 以擬真情境資料操作載入、送出、空資料與錯誤狀態 | 真實後端、實際權限與正式環境整合 |
回頭看目前的開發紀錄,好幾次資料形態看起來正確,流程跑完後最終欄位值卻還是空的。
第三代的編審放流程裡,有一段可匿名化的例子很適合說明這件事:使用者在確認頁選擇主管,接著送出申請並開立單據。
畫面上看起來只是一個下拉選單和送出按鈕,實際上前端得先讀取登入者的組織資訊,再取得可選主管;使用者確認後,才把申請人、主管與申請內容送出。後端回傳單據識別結果後,畫面顯示成功,個人單據中心也要刷新。
選主管
↓
讀登入者組織資訊 → 讀主管候選清單
↓
送出申請內容
↓
取得單據識別結果
↓
顯示成功並刷新單據中心
這個案例不是要展開所有單據流程,而是要讓我自己記得:一個看起來可以送出的按鈕,背後通常有多段資料交換。如果 API 規格沒有先把每一段講清楚,AI 很可能完成下拉選單、dialog 和成功提示,流程卻沒有真正接起來。
第三代新增流程時,我會先和 LLM 討論資料庫架構與資料該怎麼存,再寫 Spec、開發前端。後端仍會提供 API 規格。LLM 可以協助我把想法整理成可以討論的內容,但資料模型和接口規則不能讓它自己決定。
Anthropic 在談 context engineering 時也提醒,Agent 的輸入應該清楚而且高訊號。對這類 UI 任務來說,這次真正會用到的 API input/output,比一段很長的模糊描述更有用。Effective context engineering for AI agents
今天不用先寫完整 OpenAPI,也不是每一個小修改都需要 mock。選一個會讀取或送出資料的真實變更,先把資料交換寫清楚;本機真的連不到後端,或需要固定資料情境時,再列出 mock 需求。
# API contract note|功能名稱
## 這次要用的 API
- 目的:
- 何時呼叫:
- Input:
- Output:
## UI 怎麼使用回傳結果
- 載入成功時:
- 無資料時:
- 失敗時:
## 本機 mock(若需要)
- 要模擬的成功回應:
- 至少一種失敗/空資料情境:
- 與真實後端待確認的差異:
如果你已經使用 Claude Code,可以先請它盤點,不要急著叫它改程式:
請讀取這次的 Plan、相關頁面與既有 API 定義。
列出本次 UI 真正需要的 API:呼叫時機、input、預期 output,
以及成功、空資料與失敗時畫面要怎麼處理。
若本機無法連後端,再提出最小 mock 需求;不要自行發明業務規則或 endpoint。
寫完後,逐一確認 AI 列出的 input/output 能不能回到 Swagger、既有 API、後端同事,或一個明確待確認問題。只要 AI 自己補了一個欄位,卻找不到來源,我會先停在這裡,不讓它直接往下實作。
第二代的 Swagger,讓我、後端同仁與 AI 對 API input/output 有共同參照;第三代的 mock,處理的是本機連不到內部後端時,前端還能不能繼續開發與檢查流程。
Swagger 不會替我定義使用者流程;mock 也不會省掉正式串接驗證。不過它們都把 AI 原本得猜的資料交換,放到可以討論、可以 review 的位置。
下一篇要接著處理另一個問題:資料流邊界清楚後,AI 實作頁面時,怎麼讓它只改這次界定的範圍,不順手把其他功能一起改掉?