AI 工作流程
這個專案是用 Claude Code 打造的。大多數「用 AI 打造」的聲明到標籤就止步了。以下是完整的面貌:AI 知道什麼、工作階段如何運作、實際的提示詞撰寫是什麼樣子,以及人類在哪裡劃下界線。無論你自己正在用 AI 開發,或只是好奇它實際上長什麼樣子,這篇文章就是為你而寫的。
AI 知道什麼
Section titled “AI 知道什麼”Claude Code 有一個持久記憶檔案,能在不同工作階段之間延續上下文。它不會每次對話都重新探索整個程式碼庫,而是從我們上次結束的地方接續。以下是其中的內容(已脫敏):
- 應用程式名稱、原始碼位置、授權條款、應用程式識別碼
- 分支關係:上游是 Francisco Salgueiro 的 En Croissant,我們獨立維護自己的分支
- 分支存在的原因:上游維護者婉拒了 TTS 功能,這完全合理——同一個專案有不同的願景
- 僅限 pnpm——npm 會破壞 vanillaExtract(執行時白屏,沒有錯誤訊息,什麼都沒有)
- 需要 Node.js 22+(Vite 7 需要
crypto.hash) - 提交前務必執行
pnpm format && pnpm lint:fix - 覆寫二進位檔前先關閉應用程式(「Text file busy」)
- 搬移原始碼目錄後,執行
cargo clean以清除過期的路徑參照
- 哪些檔案擁有哪些功能(atoms 在
atoms.ts、棋譜樹導覽在tree.ts、TTS 引擎在tts.ts) - 為什麼所有 TTS atoms 都需要
getOnInit: true(在 React 訂閱之前透過store.get()進行命令式讀取) - 音訊快取如何運作(
provider:voiceId:lang:text鍵值) - chessground 座標修正是在 CSS 端,而非分支該函式庫
- 資料佈局:什麼放在哪裡、什麼是符號連結、什麼在應用程式重啟後仍然保留
AI 不知道什麼
Section titled “AI 不知道什麼”記憶檔案不包含 API 金鑰、密碼或憑證。它會參照這些資料的儲存位置(localStorage atom 名稱),但絕不包含其值。AI 生成的程式碼會從設定中讀取金鑰——它永遠不會看到或處理實際的機密資訊。
AI 被告知什麼
Section titled “AI 被告知什麼”除了記憶檔案之外,Claude Code 還遵循內建於其系統中的規則:
- 不要過度工程化。 只做直接被要求的變更。修一個 bug 不需要順便整理周圍的程式碼。三行相似的程式碼勝過一個過早的抽象。
- 不要猜測 URL。 絕不捏造連結或端點。
- 編輯前先閱讀。 絕不對未讀過的程式碼提出修改建議。
- 偏好編輯而非新建。 除非絕對必要,不要建立新檔案。
- 禁止安全漏洞。 注意注入攻擊、XSS 和 OWASP 前十大問題。
- 不確定時就問。 如果指令含糊不清,寧可詢問而非猜測。
- 三思而後行。 破壞性操作(force push、reset —hard、刪除檔案)需要人類明確批准。
撰寫好的提示詞
Section titled “撰寫好的提示詞”一次有用的 AI 互動和一次令人沮喪的互動之間的差異,幾乎總是取決於提示詞。
明確說明你想要什麼。 不是「修那個 bug」,而是「TTS 快取鍵沒有包含供應商名稱,所以從 ElevenLabs 切換到 Google 時會播放快取的 ElevenLabs 音訊,而不是產生新的音訊。」
提供 AI 沒有的上下文。 AI 可以讀你的程式碼,但讀不了你的心。「使用者回報棋盤上的座標是反的」不如「chessgroundBaseOverride.css 中的 CSS 把行列搞反了——Francisco 的原始版本就是反的」來得有用。
說明你的限制條件。「不要建立新檔案」、「使用現有的 atom 模式」或「這必須在沒有 API 金鑰的情況下運作」,能告訴 AI 護欄在哪裡。
說明你不想要什麼。「不要為不可能發生的情況加上錯誤處理」或「不要重構周圍的程式碼」可以防止過度工程化——這是 AI 最常見的失敗模式。
模式是:意圖 + 上下文 + 限制條件。掌握這個模式,AI 就會變得顯著更好用。
計畫模式:用一個 Claude 來提示另一個 Claude
Section titled “計畫模式:用一個 Claude 來提示另一個 Claude”Claude Code 有一個「計畫模式」,將思考與執行分開。在計畫模式中,AI 讀取檔案、探索程式碼庫,並產出一份計畫——但不寫任何程式碼。你審閱計畫、調整它,然後切換到實作模式,讓 AI 執行。
為什麼這樣做有效?因為任何程式設計任務中最困難的部分不是寫程式碼。而是搞清楚該寫什麼程式碼——該改哪些檔案、該遵循什麼模式、存在哪些邊界情況。計畫模式在寫下任何一行程式碼之前,就把全部注意力集中在這個問題上。
來自這個專案的例子:當我們重新調整「說明」選單以加入語言選擇器時,計畫模式的對話探索了 Tauri 選單的運作方式、已存在哪些 atoms、文件檢視器如何解析資源路徑,以及確認對話框的 API 長什麼樣子。等到我們切換到實作模式時,AI 已經有了一張完整的變更地圖。沒有任何錯誤起步。
你本質上是讓 AI 的一個實例擔任資深架構師,另一個擔任開發者。同一個模型,不同的角色。
工作階段如何運作
Section titled “工作階段如何運作”一個典型的工作階段看起來像這樣:
-
人類陳述意圖。「在 KittenTTS 段落加上快取注意事項。」「移除 PostHog 遙測。」「品質評分是錯的,這是正確的內容。」
-
AI 讀取相關檔案。 它不會猜測檔案裡有什麼。它會讀取它、理解當前狀態,然後提出修改建議。當多個檔案相互獨立時,會平行讀取。
-
AI 進行修改。 對現有檔案進行針對性的編輯。不是重寫——而是保留周圍一切的精準修改。
-
人類審閱。 每一次編輯在寫入磁碟前都會展示。人類批准、拒絕或重新引導。「不,那太委婉了——直說它真的很爛。」「把那個段落往上移。」「那不是我的意思。」
-
被告知時才提交。 AI 絕不會主動提交。人類說「commit」或「commit and push」。提交訊息包含
Co-Authored-By: Claude Opus 4.6——永遠標明歸屬,絕不隱藏。
上下文視窗與存檔點
Section titled “上下文視窗與存檔點”每一次 AI 對話都有一個上下文視窗——它一次能在記憶中保存的文字總量。當對話變得夠長時,較舊的訊息會被壓縮以騰出空間。
兩個策略:保持對話聚焦(每次對話一個任務),以及使用存檔點(Claude Code 會將對話記錄儲存為 JSONL 檔案,你可以從中恢復並還原完整上下文)。記憶檔案有不同的用途——它是一個跨所有對話持續存在的知識庫。
AI 提議的 vs. 實際發布的
Section titled “AI 提議的 vs. 實際發布的”AI 的第一個建議很少是最終版本。一個典型的交流過程:
- AI 草擬一個合理的版本
- 人類說「太官腔了」、「更直接一點」或「那是錯的,原因如下」
- AI 調整
- 人類批准
品味、語調和最終決定權永遠在人類手上。AI 負責速度——讀取檔案、理解上下文、在它能保持在記憶中的程式碼庫裡進行精準編輯。人類負責判斷——要建什麼、感覺應該如何、何時該停下來。
技能與斜線指令
Section titled “技能與斜線指令”Claude Code 支援「技能」——儲存在 .claude/commands/ 目錄中作為 markdown 檔案的可重複使用提示詞。你可以用斜線指令來調用它們,例如 /translate-docs。
這個專案使用 /translate-docs 技能來自動化將文件翻譯成多種語言。技能檔案包含完整的指示:要翻譯哪些檔案、使用什麼格式、如何處理程式碼區塊和連結、維持什麼語調。不需要每次都解釋這些,你只要輸入 /translate-docs,AI 就確切知道該做什麼。
技能編碼的是流程,而不只是資訊。你可以為任何重複性的工作流程建立技能:執行測試、部署、審閱 PR、更新變更日誌。
完整的原則文件位於儲存庫中的 .claude/01_UNIVERSAL_PRINCIPLES.md。它最初以 Robert C. Martin 的 Clean Code(2008)為基礎,再加上 AI 時代的補充。然後我們進行了一場坦誠的對話,討論哪些仍然適用、哪些已經不合時宜。
永恆不變的原則
Section titled “永恆不變的原則”- 揭示意圖的命名。 永遠如此。始終如此。
- 函式只做一件事。 真正的原則是連貫性,而非大小。
- 無副作用。 仍然是大多數 bug 的根源。
- 註解解釋為什麼,而非是什麼。
- 單一職責。 一個模組應該只有一個改變的理由。
- 對介面程式設計,而非對實作。
- 不要吞掉錯誤。 每一個錯誤都是資訊。
- 浮現式設計: 通過所有測試、無重複、表達意圖、最小化複雜度。按照這個順序。
視情境而定的原則
Section titled “視情境而定的原則”這些原則是正確的,但具體的規則反映了 AI 之前或特定語言的世界。我們遵循精神,而非字面:
- DRY。 逐漸分歧的重複是危險的。但把每一個重複的模式都抽取成抽象會產生間接層,可能更糟。有時候就在這裡寫三行可讀的程式碼,比在另一個檔案裡做一個過早的抽象要好。
- 嚴格的 TDD 儀式。 原則——交付經過測試的程式碼、知道它能運作——是不可妥協的。儀式——測試必須先於程式碼存在——是為人類打字速度慢的工作流程設計的。寫測試。確保它們通過。測試先寫還是程式碼先寫,不如兩者都存在來得重要。
- 童軍規則。「離開時比來時更乾淨」——是的。但童軍是打掃營地,不是整座森林。修復你觸碰到的部分。不要因為改了一行程式碼就重構整個檔案的結構。
AI 時代的補充
Section titled “AI 時代的補充”- 基於原則的指引比規則更具擴展性。 原則允許判斷;規則則脆弱。
- 如果代理人建造了它,代理人就能維護它。 保留對話上下文和產出物。記錄建造過程,而不只是結果。
- 清晰勝過巧妙。 建造這個系統的工具需要能重建推理過程並正確修改。明確的結構勝過微小巧妙的抽象。
- 這能成為基礎設施嗎? 工具為你解決問題。基礎設施讓其他人能在上面建構。相應地進行設計。
人類在哪裡劃下界線
Section titled “人類在哪裡劃下界線”AI 是一個工具。一個非常出色的工具。但有些事情它不做:
- 產品決策。 要建什麼功能、要砍什麼、應用程式應該有什麼感覺。「系統 TTS 品質評分應該寫『勉強堪用』因為它真的很爛」——這是基於實際聆聽後做出的人類判斷。
- 品味。 AI 可以寫出乾淨的文字,但專案的聲音、直言不諱談論品質的決定、選擇prominently 標注 Francisco 的功勞——這些都是人類的選擇。
- 倫理。 移除 PostHog 不是一個重構任務。而是「設定頁面說我們不收集遙測資料,但程式碼裡有一個活躍的 PostHog API 金鑰。那是謊言。修掉它。」AI 執行了。人類發現了問題並在乎這件事。
- 西洋棋。 棋盤不在乎你的工具鏈。
為什麼分享這些
Section titled “為什麼分享這些”因為「用 AI 打造」已經變得毫無意義。每個人都這麼說。沒有人展示出來。有趣的問題不是 AI 是否參與了——而是它如何參與的,以及人類實際貢獻了什麼。
這就是答案。人類帶來願景、品味、判斷和責任。AI 帶來速度、記憶,以及在凌晨兩點不知疲倦地閱讀 Rust 錯誤訊息的意願。
兩者都無法獨自完成這件事。兩者都被標注功勞。這就是約定。
En Parlant~ 是 Francisco Salgueiro 的 En Croissant 的分支,使用 Anthropic 的 Claude Code 打造。