【EP-26】AI 總是產出糞 Code 給我,還說想取代程式設計師?到底該怎麼解決?
Vibe Coding 就像是跟工程師合作,你必須詳細地描述你要做的專案,沒辦法說,「幫我做出屌打Facebook的社群媒體」。你的第一步是先寫出專案說明書。
你開始用 AI 寫程式了嗎?
在網路上常可以看到兩種不同聲音,一個是說他完全不會寫程式,但是靠 AI 設計了 App;
也有人說, AI 總是產一些糞 Code 給他,叫它改個程式,很容易改壞。
到底哪一個才是對的?
我認為都是對的。
其實用 AI 寫程式,跟我們用 AI 生圖,體感上一模一樣。
當我使用 ChatGPT 4o 生圖時,覺得這傢伙超厲害的,一下子就產出很漂亮的圖畫。
但是有時候產出的圖並不是我們要的,如下圖左側,原本的提示詞是希望產出中華民國國軍迷彩帽,但是帽子上差了國徽。
沒關係嘛,那就跟它說明要產出國徽啊。
結果下了提示詞之後,連女孩的胸口都有國徽了。
寫程式也像是這樣,如果我們放手上 AI 自由發揮,有時候的確會產出很棒的作品。
但是假設產出的結果不如預期,而當我們要微調時,就會開始頻頻出錯。
幸運的是,我們可以藉由設計給 AI 的基本規則來改善結果。
我曾經在EP-4 與 AI 共同協作寫程式的準則,分享國外網友如何設計AI 程式編輯器的規則。
不過自己親自測試過好幾次,有了一些小心得,我發現除了設定規則,寫程式的過程還必須遵循結構化的步驟。
為 AI 設計可精確遵循的規則
目前兩款主流的 Cursor、Windsurf AI 程式編輯器,都有全域規則與專案規則的設計。
以 Windsurf 為例,按下齒輪,搜尋 Rules ,就可以找到 Global Rules 與 Local Rules 。
我目前已經把之前 EP-4 國外網友分享的規則全都修改了,因為我覺得那個版本沒什麼用,例如裡頭說:
程式碼品質:優先考慮乾淨、易讀和可維護的程式碼。 演算法效率:使用最有效率的演算法和資料結構
類似這樣的規格是沒有用的,不夠精確。
你一定要明確地跟 AI 說你要做什麼!
我較為擅長的語言是 Python ,最多加一個 JavaScript,所以我依據我的個人需求,做了以下的設計:
全域規則,就像是給 AI 的憲法
# Windsurf AI 程式開發規範
## 語言
- **回應方式**:所有回應皆使用繁體中文,並採用台灣地區常用用語。
---
## 作業系統
- **作業系統**:預設使用者為 Windows 系統,並使用 PowerShell 指令。
---
## 專案初始化
- **初始化結構**:在開始新專案或空目錄作業時,若不存在則自動建立以下標準檔案與目錄:
- `LICENSE`:預設使用 MIT 授權,除非另有指定。
- `.gitignore`:根據 Python 與 JavaScript 技術棧自動生成,忽略如 `__pycache__/`、`*.pyc`、`node_modules/`、`.env`
等檔案或資料夾。
- `requirements.txt`:列出 Python 相依套件。
- `modules/`:可重複使用的 Python 模組資料夾,內含 `__init__.py`。
- `src/`:後端 Python 主程式碼目錄。
- `frontend/`:前端 JavaScript 程式碼目錄,包含 `package.json` 等檔案。
- `logs/`:用於儲存執行時期日誌檔案的資料夾(如 `project.log`)。
- `CHANGELOG.md`:專案變更記錄檔案,內容使用繁體中文並採用以下格式:
```markdown
# Changelog
## [Unreleased]
### Added
- 新增「使用者登入後台」頁面
- 撰寫 `auth.py` 模組驗證 JWT
### Fixed
- 修正環境變數未載入的問題
## [1.0.0] – 2025-04-28
### Added
- 初始版本:包含基本的 REST API 路由
- `requirements.txt`、`src/`、`frontend/` 資料夾結構
```
---
## 專案管理
- **文件管理**:閱讀 `CHANGELOG.md` 內容以了解目前進度,再依照 `README.md` 指示進行。
- **目錄檢查**:在開始任何新任務前,必須先檢查目前目錄結構。
- **更新目錄結構**:新增或移除檔案、目錄後,必須同步更新 `README.md` 中的目錄結構。
- **變更紀錄更新**:每次新增或刪除功能後,必須以標準格式在 `CHANGELOG.md` 中新增清楚的紀錄。
- **錯誤處理**:每個函式需加入錯誤記錄功能,所有錯誤統一寫入專案根目錄下的 `.log` 檔案。
- **模組化設計**:程式設計需遵循高內聚、低耦合原則,相關功能統一整理至 `modules/` 目錄下。
- **註解撰寫**:程式中需加入清楚簡潔的繁體中文註解,說明程式邏輯。
- **行長限制**:每行程式碼長度限制在 100 字元以內。
專案規則,就像是專門針對某件項目的法律條文
在設計專案規則之前,必須先將「專案說明」寫出來。
所謂的專案說明,通常會記錄在 README.md
,一起放在專案的根目錄內,會記錄專案目標、專案功能、專案目錄、採用的技術等等。
以最近在開發的台海戰爭風險地圖為例,我首先花了許多時間與 AI 詳細討論專案,到最後再讓 AI 生成專案說明。
至於專案規則,則是針對專案採用的技術,要求 AI 特別遵守的規則。
我同樣也是先花了許多時間跟 AI 討論,利用 ChatGPT 的深入研究(Deep Research),調查目前網路上建議的規則。
最後再依據建議的規則,搭配先前的專案說明,產出以下的專案規則。
# Workspace Rules — 台海戰爭風險地圖 v2
## 通用
- **架構**:後端 Python,前端 Streamlit + MapLibre GL JS,詳見 README。
- **格式**:Python 遵循 PEP 8,使用 Black + Ruff;JS 遵循 ESLint + Prettier。
- **命名**
- snake_case:函式、變數
- PascalCase:類別
- UPPER_SNAKE_CASE:常數
- kebab-case:檔案與目錄(`.py` 模組除外)
- **文件**:公開函式 / 類別必備簡潔 docstring;複雜邏輯加行內註解。
- **版控**:將 `.env`、`.windsurfrules`、快取與編譯產物加入 `.gitignore`。
---
## 前端 (Streamlit + MapLibre)
1. **MapLibre 注入**:僅在 `modules/map/renderer.py` 透過 `st.components.v1.html()`
引入 `<link>` 與 `<script>`;其他檔案不得重複載入。
2. **靜態資產**:GeoJSON、CSS、圖片等放於 `modules/map/assets` 或 `static/`。
3. **圖層規範**:來源與 ID 依 README 既有定義;新增圖層用語意明確的 kebab-case。
4. **UI 一致性**
- 圖表:`st.plotly_chart(fig, use_container_width=True)`
- 表格:`st.dataframe(df, use_container_width=True)`
- 篩選與設定元件置於 `st.sidebar`。
---
## 後端 (資料抓取・排程・通知)
1. **設定管理**:所有金鑰與參數集中於 `config.py`,用 `os.getenv()` 讀取 `.env`,禁止硬編碼。
2. **資料快取**:I/O 函式置於 `modules/*_loader.py`;重度操作加 `@st.cache_data(ttl=300)`。
3. **排程**:使用 APScheduler `BackgroundScheduler`;Job 名稱語意清晰且不衝突。
4. **通知**:
- `modules/notify/notifier.py` 負責傳送訊息
- `modules/notify/scheduler.py` 只負責排程
5. **例外與日誌**:關鍵區塊包覆 try/except,使用 `logging`(模組同名 logger,預設 INFO)。
6. **測試**:Pytest 測試檔置於 `tests/`;以 `pytest -q` 驗證核心函式。
---
以上規則維持專案結構清晰、一致且易於維護;如遇未涵蓋情況,以 README 為最終依據,必要時先詢問人類開發者再實作。
結構化的 Vibe Coding 方式
有了全域規則與專案規則,還不夠,自己還是得遵循一定的規範。
這個規範沒有一定,隨時會動態調整,我也不敢說自己已經摸索出最佳解了。
不過目前我是這麼做的,以下是開發步驟,提供給各位參考:
全域規則:依據習慣開發的軟體來設計,例如我最擅長的是網站設計,程式語言僅使用 Python 與 JavaScript。我認為依據開發的項目不同,全域規則也應該長得不一樣。
初始化目錄:打開 WindSurf 選擇空目錄,使用全域規則初始化,建立需要的目錄與空白檔案。
專案說明:我會另外在 ChatGPT 網頁上,建立專案,如下圖。然後花許多時間與 o3 與 o4-mini-high 討論專案內容,最後產出
README.md
,記載專案目標、專案功能、專案目錄、專案技術。專案規則:在根目錄底下建立
.windsurfrules
,以README.md
為基礎,讓 AI 設計專案規則。開發步驟:專案說明(README.md)寫的都只是大概的功能,詳細開發步驟,必須針對每一個功能,與 AI 詳細溝通,列出每一個功能應該有的開發步驟,記錄在
INSTRUCTION.md
。寫程式:到了第6步驟才要寫程式,有些小訣竅要記住,
隨時記錄:依據
INSTRUCTION.md
要求 AI 寫程式,另外之前在全域規則已有設定,每次修改、新增功能,必須記錄在CHANGELOG.md
。所以也得檢查是否有照實記錄。記得存檔:如果滿意了這次修改,我就會馬上存檔到 git 。因為 LLM 改錯程式的機率不小。
回到上一動:程式如果出錯了,先別叫它修正。先復原目前的版本,再繼續叫它寫一次。不要讓它嘗試修正,很容易出錯。
程式要短:還記得之前我們有提到要模組化,把這件事記在心裡。隨時檢查程式碼是否太長。
滾動修正:理論上來說,AI 每次寫程式都會閱讀
CHANGELOG.md ,依據提示詞與專案說明來開發。我們必須
反覆依據開發狀況,修正README.md
、INSTRUCTION.md
,甚至是專案規則。
湊巧的是,在我整理這篇文章時,我剛好看到有篇網路翻譯影片剛剛發佈在YouTube:YC合夥人談氛圍開發的技巧, 不只直覺更是精準導引的新開發哲學,裡面討論的內容與我目前的作法有些重疊。
從事 Vibe Coding 開發,最重要的工作不是讓 AI 開始寫程式,那反而是最後的工作。
我們應該花更多的時間整理專案內容,思考自己開發的目的,每一個功能的細節,需要使用什麼套件來達到我們的目標。
這些我們都不用自己空想,善用 AI ,多跟它討論。
即便是專案說明寫好了,我都可能隨時會再修改,就必須回頭再跟 AI 繼續討論。
你是怎麼利用 AI 開發專案呢?讓我知道吧!