# 用 LLM 製作工具：作業方法

本文件規範以 LLM CLI 協作開發課堂工具的作業流程，適用對象為無程式背景的修課學生。內容限於工作方法與已知的平台行為，不涉及作品的形式、外觀與技術選型。標示為「作業約定」者為本課程的規定，非技術限制。

將本檔置於專案資料夾根目錄，依兩種情況啟動：

- **首次**：專案內只有本檔。第一則指令要求 CLI 讀取本檔，並依 §Specification 建立 `spec.md`、依 §Version Control 建立版本控制、依 §Session Handoff 建立 `HANDOFF.md`。
- **續作**：第一則指令要求讀取本檔、`spec.md` 與 `HANDOFF.md`。

全新 session 不帶前次對話的脈絡。部分 CLI 可恢復既有 session（例如 `codex resume`、`claude --resume`），恢復與否取決於 session 資料是否留存及是否在同一台機器；交接因此一律以檔案為準。

§Browser Constraints 與 §Publishing 僅適用於 browser 平台。§Problem Reports 第 4 項的 Console 要求同樣如此，其他平台以該環境的訊息輸出（Max 的 console、Pd 的 Pd window、序列埠輸出）替代，其餘規則不變。

## AI Use

本課程允許以 AI 協助程式撰寫與技術實踐：產出與修改程式碼、除錯、設定執行環境、說明某個功能有哪些做法。

不允許把概念工作交給 AI。作品要處理什麼問題、為何如此設計、實際聽到了什麼、如何詮釋，由學生自行完成。判準為：**需要說明理由的決定，理由必須出自學生本人。** CLI 可以列出可行做法與彼此的差異，選擇與理由不外包。

§Specification 規定由 CLI 提問、學生回答，用意即在此。提問是要學生把想法說清楚，不是由 CLI 代為構思。

書面文字依課綱辦理：送審版課綱明定禁止 AI 直接寫期末報告主文段落，創作自述同此。

## Platform

實作平台不限。Max/MSP、Pure Data、Python、microcontroller 或 DAW script 均可作為期末作品的實作環境，依作品需要選擇。

建議自 browser 起步，理由為三項條件：不需安裝執行環境、可發布為公開網址供他人開啟與試聽（見 §Publishing）、同一份檔案不綁定特定作業系統。

## Specification

實作前建立 `spec.md`，記錄五項：

1. **工具的功能**：一句陳述。
2. **輸入來源**：microphone、既有音檔、滑鼠或鍵盤動作，或無輸入。
3. **操作者的動作**：明確到單一動作。
4. **完成判準**：可聽見或可看見的結果。
5. **不支援的情境**：刻意不處理的狀況，例如未授權 microphone、未選擇檔案、操作中途取消。未記錄者無法在驗收時區分「尚未完成」與「刻意不做」。

第四項決定其餘各項能否驗收。「製作一個好用的聲音工具」不構成判準，因為沒有任何觀察能判定其成立。「按下按鈕後，錄製的 20 秒環境音以 0.5 倍速播放，畫面同時顯示波形」構成判準。

第五項不得用於規避驗收：驗收失敗的情境不直接移入第五項。確有必要改列時，於 `HANDOFF.md` 第 4 欄記錄該決定與理由，並重新確認第四項是否仍成立。

規格由 CLI 主動問出，不由學生獨自寫成。開工第一則指令：

> 目標是製作一個工具。先不要寫程式。依序提問，把 spec.md 的五個欄位問到可驗收為止，其中完成判準必須是可聽見或可看見的句子。問完出示整份規格，經確認後才開始實作。

CLI 若略過提問直接產出程式碼，中止並重述上述指令。

使用 Claude Code 者，安裝 superpowers plugin 可取得結構化的需求釐清流程（brainstorming skill）。安裝方式：於 Claude Code 內執行 `/plugin`，在 `claude-plugins-official` marketplace 安裝 `superpowers`（plugin id：`superpowers@claude-plugins-official`）。安裝介面依 Claude Code 現行版本，以其官方文件為準；其他 CLI 的安裝方式見 superpowers 專案的說明文件。未安裝時以上述指令替代，流程不變。

規格會隨製作過程修改，修改一律寫回 `spec.md`。

## Version Control

寫入第一行程式前先建立版本控制，並要求 CLI 說明其規劃：

> 將這個資料夾建成 git repository，並說明預計在哪些節點 commit。

LLM 修改既有程式時可能連帶影響其他功能，且不一定回報。版本控制的作用是讓任一先前狀態可被指名取回。

五項作業約定：

1. main 的歷史只保留經實際執行確認可運作的版本。未通過驗收的程式碼提交於實驗 branch。
2. commit message 描述行為變化，不使用 `update`、`fix` 這類無資訊的字樣。「加入錄音按鈕，可錄可播」在回溯特定聲音版本時可用，`fix` 不可用。
3. 實驗 branch 通過驗收後，以 squash 方式併入 main，使過程中未通過的提交不進入 main 的歷史。一般 merge 會把那些提交一併帶進 main，牴觸第 1 項。squash 後，實驗過程中 `HANDOFF.md` 的中間狀態不會留在 main；需要保存的是失敗原因與 `ai-log.md` 段落（第 5 項），交接現況本身不需要歷史。
4. 在 main 上直接修改而驗收失敗時，要求 CLI 由目前的修改另開實驗 branch 再提交，不在 main 上提交失敗狀態。未提交的修改不隨 branch 隔離，切換時會跟著移動，Git 也可能因為會覆寫而拒絕切換。
5. `HANDOFF.md`、`spec.md`、`ai-log.md` 的提交不受第 1 項限制。捨棄實驗 branch 前，先把失敗原因寫進 main 上的 `HANDOFF.md`，並將該 branch 上的 `ai-log.md` 段落併回 main：只留在被捨棄 branch 上的紀錄，續作時讀不到，期末也無法用於揭露。

復原時指名目標版本，例如「回到 commit 4a2f，那一版的錄音可以播放」；「上一個」在文件提交混入紀錄後不足以定位，commit message 因此須能辨識版本（第 2 項）。操作者不需記憶指令，但需知道此操作存在。

未納入版本追蹤的音檔、相依套件與執行環境不會隨版本回退還原，需另行備份。

## Session Handoff

交接文件的作用是讓新 session 取得現況、既有決定與已排除的方案，避免重走已證實失敗的路徑。

在專案根目錄維持一份 `HANDOFF.md`，五個欄位：

1. **目前狀態**：可運作的功能，並標出對應的 commit。
2. **進行中**：正在處理的項目與未解決的問題。
3. **已排除的做法**：嘗試過而失敗的方案、失敗原因，以及當時的環境。環境改變後可重新評估，此欄不構成永久禁令。
4. **已定案的設計決定**：目前不重新討論的選擇。出現新證據時可重啟，重啟時記錄理由。
5. **下一步**：一至三項具體工作。

作業約定：

- 欄位無內容時填「尚無」或「不適用」，不留空白。開場時核對所載 commit 是否存在於本專案、內容與實際狀態是否相符；空白、矛盾或屬於其他專案時，只就該部分與 CLI 重建，其餘內容照常沿用。
- 下列時點即更新並提交，不只在 session 結束前更新：通過一項驗收、驗收失敗、排除一個方案、切換 branch。session 中斷且其紀錄未留存時，未記錄的除錯過程無法復原。
- `HANDOFF.md` 為覆寫式文件，只記現況，不累積歷史。歷史由版本紀錄承擔。
- 單次 session 過長而 CLI 開始遺忘先前內容時，先更新 `HANDOFF.md` 與 `ai-log.md`，再開新 session。

## Iteration and Verification

單次指令只要求一項變更，變更完成後實際執行確認，通過後提交，再進行下一項。此為作業約定，用意是讓異常可歸因到單一變更。

CLI 不一定能播放或聆聽音訊輸出，其回報的「完成」不構成聲音正確的證據，也不表示它實際執行過該程式。因此要求 CLI 在每次變更後停止，列出操作者應執行的步驟與預期結果，待實際結果回報後再繼續：

> 每次變更完成後停止，列出操作者應執行的步驟與預期結果，待回報後再繼續，不要自行判定完成。

驗收由操作者執行，每一輪確認四項：

1. 工具若應產生聲音，是否產生。
2. 若有聲音，是否為預期內容，而非雜訊、削峰或極短片段。
3. `spec.md` 的完成判準是否成立。
4. 前一輪已可運作的功能是否仍可運作（回歸檢查）。

未經實際執行確認的狀態不併入 main。純文件變更不適用本節。

## Problem Reports

「不能動」不構成可處理的回報。有效回報包含四項資訊：

1. 執行的操作。
2. 預期的結果。
3. 實際的結果。
4. 錯誤訊息原文，以及執行環境（browser 名稱與版本、開啟網頁的方式，或其他平台的對應資訊）。browser 上按右鍵選「檢查」開啟 Console，複製訊息全文，不改寫、不摘要、不只取單行。

沒有訊息時照樣回報，於第 4 項註明「無訊息」。無訊息不等於無錯誤：錯誤可能發生在程式未讀取的地方，也可能是不會拋出例外的邏輯問題（例如音量被設為零）。此時要求 CLI 加入檢查點，並指明該檢查點顯示在哪裡、由哪個操作觸發、應觀察什麼數值。

同一問題連續兩次修改未解決時停止要求重試，改下達：

> 先不要修改程式。說明推測的原因，列出兩種可能，逐一排除。

## Browser Constraints

以下為已知的 browser 行為，實際規則依 browser 與版本而異。症狀相同不代表原因相同：無聲或時間偏移同樣可能來自程式缺陷。確認原因後再修改，修改後重跑原案例並確認既有功能未退化。

1. **頁面載入時的自動發聲受 autoplay 政策限制。** 多數 browser 預設要求使用者先與頁面互動，AudioContext 才會啟動；實際行為依 browser 設定與既有授權而異。提供一個使用者會觸發的控制項可避開此限制。
2. **microphone 需 secure context 並經使用者授權。** https 與 localhost 屬 secure context。滿足此條件仍可能被 iframe 的權限政策、sandbox 設定或作業系統的麥克風權限阻擋，須逐項確認。
3. **以 `file://` 開啟時，`fetch` 與 XMLHttpRequest 讀取本地音檔會被安全規則阻擋**，經由這條路徑取得資料再交給 `decodeAudioData` 因此失敗。另外兩條路徑不受此限：`<audio>` 元素直接播放通常可行；使用者以檔案選擇器選取的檔案可經 `arrayBuffer()` 取得資料後解碼。改以 local server 或公開網址（見 §Publishing）開啟可解除被阻擋的那條路徑，但不會改變遠端伺服器的 CORS 設定，跨來源的音檔仍需該伺服器授權。
4. **音訊格式支援依 container 與 codec 分別認定。** 以 MDN 的 Audio codecs 對照表確認目標 browser 是否支援所選格式；WAV（PCM）與 MP3 為常見的低風險選項，本文件未做版本比較。載入失敗有錯誤可讀：`decodeAudioData` 會回傳失敗，media element 具 `error` 事件與 `MediaError`。未見錯誤訊息不能推論沒有錯誤，須逐一確認這些錯誤介面是否被程式讀取並顯示。
5. **分頁移至背景時 timer 可能被節流**，規則依 browser 與頁面狀態而異，音訊播放中等情況列有例外。切換視窗後節奏偏移不得直接歸因於節流，須分別觀察頁面可見性、timer 延遲與音訊狀態。作品涉及時間精度時，要求 CLI 列出可用的排程方式與差異，再行選擇。

查證關鍵字（MDN）：`Autoplay guide`、`getUserMedia`、`CORS`、`Audio codecs`、`decodeAudioData`、`Timeouts in inactive tabs`。

## Publishing

作品須能在他人機器上開啟，僅本機可執行者不構成交件（見 §Submission）。Cloudflare Pages 提供免費的靜態網頁託管，可將網頁發布為公開網址。發布後網址為 https，§Browser Constraints 第 2 條的 secure context 條件因此滿足；網頁由伺服器提供而非 `file://`，第 3 條被阻擋的載入路徑隨之解除。

本節只涵蓋靜態部署。Cloudflare Pages 另有 Functions 可執行伺服器端程式，不在本文件範圍。

**兩種模式在建立專案時就要決定，之後不可互換。** Cloudflare 文件明載：選擇 Direct Upload 後無法改為 Git 連動，需另建專案。

| 模式 | 前置條件 | 更新方式 |
|---|---|---|
| Direct Upload | Cloudflare 帳號 | 於 Cloudflare 網頁介面上傳，或以 `npx wrangler pages deploy <輸出目錄>` 上傳，需先安裝 Node.js |
| Git 連動 | Cloudflare 帳號、GitHub repository | 將 repository 連上 Pages 專案，其後每次 push 觸發建置與發布 |

Wrangler 不限於 Direct Upload：Git 連動的專案亦可停用自動部署，改以 Wrangler 手動上傳。

**上傳的是要公開的檔案，不是整個專案資料夾。** Direct Upload 接收已建置完成的資產；使用需編譯的 framework 時上傳其輸出目錄。`ai-log.md`、`HANDOFF.md`、`spec.md` 與未交付的素材不得包含在內，上傳即公開。

**push 成功不等於發布完成。** 建置可能失敗，而舊版仍在線上可以開啟，因此不能以「網址打得開」判定本次發布成功。Git 連動模式下，每次發布後於 Cloudflare 的部署紀錄核對狀態與 commit 代號是否為本次提交。Direct Upload 的上傳不帶 commit 資訊，須於 `HANDOFF.md` 記錄本次上傳對應哪一個 commit 的輸出，否則事後無法辨識線上版本的來源。

**preview deployment 預設公開。** Git 連動模式下，非正式 branch 的 push 也會產生可公開存取的 preview 網址。素材授權與當事人同意須在第一次 push 之前確認，不能留到正式發布時才處理。需要限制存取時，於專案設定啟用 Cloudflare Access。

發布後在乾淨環境確認：使用全新的 browser 設定檔，或清除該網站的站點資料與權限後開啟，逐項重跑 §Iteration and Verification 的驗收，並記錄裝置、browser 與版本、受測的部署代號。僅登出帳號不構成乾淨環境，快取、localStorage 與既有權限都可能仍在。

限制（依 Cloudflare 現行文件）：

- 單一檔案上限 25 MiB。長音檔需壓縮，或改以外部串流來源。
- 免費方案單一站台上限 20,000 個檔案，每月 500 次建置。
- **發布即公開。** 取得網址者皆可存取上傳的音檔，正式網址並可能被搜尋引擎索引。內容含他人聲音、未授權素材或私人錄音時，發布前須確認授權與當事人同意。此為課程的倫理要求，非技術限制。

## Submission

送審版課綱的《AI 使用規則》採「有條件開放」，明定必須揭露三項：哪些段落使用 AI、給 AI 的 prompt 內容、引用 AI 輸出時加註「AI-generated, edited by author」；違規處置為第一次扣 20%、第二次零分。書面文字（期末報告主文、創作自述）的撰寫規則依課綱辦理，本節規範的是程式碼協作過程的紀錄。

`spec.md` 與版本紀錄留下的是結果，不含提問過程，因此另建 `ai-log.md`，每次 session 追加一段：

- 該次的關鍵 prompt 原文。
- AI 產出的部分與操作者決定或改寫的部分，分別標示。
- 未採用的建議及其理由。

`ai-log.md` 於每次 session 結束前與 `HANDOFF.md` 一併更新提交，並於發布前再次確認本次 session 已有對應段落。此為手動紀錄；CLI 的 session 紀錄未留存時，未當場寫下的 prompt 無法重建。

另需保留：

- 素材來源，他人素材標註出處。
- 可執行的版本及其開啟方式。僅能在製作者本機執行者不構成交件。

每次提交前於 `spec.md` 末尾追加一行：本次變更與可觀察到的差異。期末創作自述以 `ai-log.md` 與該紀錄為材料。

## Out of Scope

以下屬作品的設計決定，本文件不提供答案：

- **視覺形式**：版面、色彩、字體、動態。
- **程式組織**：單一檔案或多檔案、是否使用 framework。
- **效能**：何時需處理效能，以及取捨對象。
- **功能邊界**：完成度，以及刻意不處理的狀況。決定本身不受本文件規範，但須記入 `spec.md` 第 5 項，否則無法驗收。

向 CLI 詢問「哪一種比較好」會得到一個預設答案，該答案未經本作品的條件檢驗。有效的問法為「有哪些做法，差異在哪」，選擇由製作者作出並記入 `spec.md`。
