Skip to content

AI 改 Code 一直改 A 壞 B?Brownfield 專案的五步工作流

影片核心論點:「問題從來不是 AI 不夠強,而是你用它的方法錯了。」 在 Brownfield(既有)專案中,AI 必須先當「幫你讀專案的資深同事」,再當「照規矩施工的師傅」。順序不能反——先看懂,再動手

目錄


1. 根因:Greenfield vs Brownfield

兩種專案類型對比

維度 Greenfield(綠地) Brownfield(棕地)
比喻 一塊什麼都沒有的空地 別人蓋好、已經有人住的房子
歷史包袱 既有 code、pattern、未解 bug、隱性相依性
架構決策權 完全自主 必須遵守既有規範
AI 發揮空間 極高(「你叫它怎麼蓋,它就怎麼蓋」) 受限(須遵守既有 pattern)
典型場景 「用 AI 30 分鐘做一個 App」 進公司接手別人的 codebase

為什麼教學派 vs 實戰派差這麼多

「用 AI 30 分鐘做一個 App」的教學影片全部都是 Greenfield 場景——沒有歷史包袱,AI 自由發揮。但日常工作中面對的是 Brownfield:在別人住的房子裡拆牆改管,還不能停水停電。

關鍵轉變:Greenfield 不會永遠是 Greenfield。Vibe Coding 狂寫一個月後,如果過程中沒有意識地維持架構乾淨,專案就已經變成 Brownfield 了——因為裡面大部分的 code 你根本沒讀過。

「改 A 壞 B」的標準翻車現場

場景:商品頁要加「庫存狀態篩選」功能
  │
  ├─ 需求:"幫我加庫存狀態的篩選跟編輯功能"
  │
  ├─ AI 不知道專案有 React Query pattern → 自己發明新寫法
  ├─ AI 不知道有共用 Table 元件       → 自己重刻一個
  ├─ AI 改了 useProducts hook 取資料   → 訂單頁也在用這個 hook
  │
  └─ 結果:商品頁修好了,訂單頁卻爆了

根因:把一個從沒進過你家的裝潢師傅一個人丟進廚房,叫他直接搞個流理台出來,完全沒先說設計風格與裝潢理念。AI 手藝再好,不認識這棟房子的管線,一鎚子下去就可能出事。


2. 兩種開發模式

在進入五步驟前,根據「對 AI 的信任度」與「使用的工具」選擇走法:

模式 主導權 適合人群 工具 特點
模式 A:AI 輔助開發 在人手上 網頁版 AI 使用者、對 AI 仍觀望者 ChatGPT / Claude 網頁版 人親自走進每個房間,AI 是放大鏡
模式 B:純指揮 Agent 在 AI 手上 Claude Code / Cursor 用戶 Coding Agent 只出一張嘴,Agent 自己探勘、回報
           對 AI 的信任度 / 工具能力
    低 ◄──────────────────────────► 高
    │                                │
 模式 A                          模式 B
 AI 輔助開發                     純指揮 Agent
 (人主動搜尋、貼 code)          (Agent 全域讀取)
    │                                │
    └──────── 第一、二步分岔 ────────┘
                 │
            第三步起合流
        (決策活沒有外包版)
                 │
            第五步再分岔
        (勞力活可以外包)

選擇原則:沒有標準答案,取決於你對 AI 的熟練度跟信任度、以及你使用的工具能力。隨著 AI 越強,所有步驟會越來越往「純指揮」收斂。


3. 五步工作流總覽

整套流程拆成兩大階段,核心區別是「勞力活 vs 決策活」:

┌─────────────────────────────────────────────────┐
│           Brownfield AI 開發五步工作流            │
├─────────────────────────────────────────────────┤
│                                                  │
│  第一階段:看懂它(探索 / 勞力活 / 可外包)        │
│  ┌──────────────────────┐ ┌──────────────────┐  │
│  │ 步驟 1               │ │ 步驟 2           │  │
│  │ 定位 UI → 元件檔案   │ │ 梳理 Dataflow    │  │
│  │ DevTools + 全域搜尋  │ │ 狀態管理 + 邊界   │  │
│  └──────────────────────┘ └──────────────────┘  │
│                        ▼                         │
│  第二階段:安全的動它(決策 / 必須人為把關)        │
│  ┌──────────────────────┐ ┌──────────────────┐  │
│  │ 步驟 3               │ │ 步驟 4           │  │
│  │ Guardrails 規範需求   │ │ 拆解任務 + Review │  │
│  │ 帶邊界的指令          │ │ 小步迭代          │  │
│  └──────────────────────┘ └──────────────────┘  │
│                        ▼                         │
│  ┌──────────────────────────────────────────┐   │
│  │ 步驟 5:測試驗證 + 回歸檢查               │   │
│  │ 跑既有測試 / 看懂 Error Log / Regression  │   │
│  └──────────────────────────────────────────┘   │
└─────────────────────────────────────────────────┘

勞力活 vs 決策活:外包界線

活的類型 本質 可否外包 對應步驟
勞力活 讀 code、找檔案、追資料流 可外包(信任度決定外包程度) 步驟 1、2、5
決策活 決定什麼不能動、判定 code 夠不夠格 不可外包,AI 只能起草 步驟 3、4

「改壞了之後,被 QA 找麻煩的是你,隔天踩到地雷的也是你,不是它。」


4. 第一階段:看懂它(探索)

步驟 1:定位 UI 畫面對應的元件檔案 [05:19]

目標:搞清楚畫面上這一塊到底長在哪個檔案裡,建立「地圖」,辨識哪些是全站共用資產。

做法:AI 輔助模式

1. 瀏覽器 DevTools → 對目標區塊右鍵「檢查」
2. 找出一個獨特特徵:
   - 特殊 class name
   - 按鈕文字
   - 測試標籤(data-testid)
3. 回編輯器「全域搜尋」這個特徵
4. 定位渲染該畫面的檔案
5. 把檔案丟給 AI 分析

Prompt(AI 輔助)

這是負責商品頁的檔案。幫我分析這個畫面的結構:
- 它引入了哪些子元件,各自負責渲染什麼?
- 有沒有哪些看起來是全站共用,而不是這頁專屬的元件?

⚠️ 只分析,不要修改任何 code

做法:純指揮 Agent 模式

畫面上商品列表這一塊,是哪個檔案在渲染的?幫我找出來。
分析它的元件結構,標出哪些子元件是全站共用的。

⚠️ 這個階段只做分析就好,不要改任何 code

共通原則:嚴禁此階段修改 code

兩條路的 Prompt 結尾都是「只分析,不要改」。這一步的價值是把「我怕改壞」的恐懼,變成一張看得見的地圖——你會清楚知道: - 自己現在站在這棟房子的哪個房間 - 哪些元件是全站共用資產(可以重用,絕對不能亂改) - 同步讓你和 AI 都認識這個專案

步驟 2:梳理資料流(Dataflow)與相依性 [06:42]

目標:搞清楚資料從哪裡來、存在哪裡、怎麼被改動。前端最容易出事的地方從來不是畫面,而是資料。

做法:AI 輔助模式

1. 打開 package.json → 確認狀態管理工具(Redux / Zustand / React Query)
2. 找對應的 store 或 hooks 資料夾
3. 回到畫面元件,找出觸發資料變動的動作(dispatch / mutate / setState)
4. 把畫面元件 + 狀態檔案一起丟給 AI

Prompt(AI 輔助)

我會給你商品頁的檔案,還有這個 hook 檔案。
請用白話文解釋這條 data flow:
- 商品列表的資料是從哪個 API 來的?用哪套工具在管?
- 當管理員編輯庫存時,資料是怎麼從畫面流回 server 的?
  把中間經過的 function 依序列出來。

📌 請特別標出:這個 hook 有沒有被商品頁以外的地方用到?

網頁版 AI 的限制:看不到整個專案,所以要先在編輯器「全域搜尋」這個 hook,把搜到的檔案一起貼給它,它才答得出「誰還在用」。

做法:純指揮 Agent 模式

幫我梳理商品頁的 data flow:
- 商品列表的資料是從哪個 API 來的?用哪一套工具在管理?
- 當管理員編輯庫存時,資料是怎麼從畫面流回 server 的?
  把中間經過的 function 依序列出來。
- 另外,商品資料那個 hook,有沒有被商品頁以外的地方用到?

Agent 讀得到整個 codebase,「還有誰在用」這一題直接就能答。

進階技巧:架構導覽圖 [08:18]

探勘做完後,補一句 Prompt:

把你剛剛探勘到的結果做成一頁 HTML:
- 這個專案的頁面結構
- 共用元件
- data flow
畫成一張架構導覽圖,我要直接用瀏覽器打開來看。

幾分鐘後就會拿到一張「建築藍圖」——哪些元件是共用的、資料從哪裡流到哪裡、哪一根水管後面接著別的頁面,一目了然。


5. 第二階段:安全的動它(決策)

從第三步開始,AI 輔助跟純指揮 Agent 兩條路合流。因為前面兩步是勞力活(可以外包),但接下來是決策活——決定什麼東西絕對不准動、判定一段改動夠不夠格進這個 codebase。決策活沒有外包版。

步驟 3:帶有邊界與規範的需求指令(Guardrails) [09:18]

這是 Brownfield 跟 Greenfield 差最多的地方。 你給 AI 的不能是一個空需求,必須是一個帶著既有規則的需求

❌ 錯誤做法(空需求)

幫我加一個庫存篩選

✅ 正確做法(帶 Guardrails)

請在既有的商品頁新增庫存狀態篩選,並讓管理員可以編輯庫存。

動手前,先讀:
- 負責商品資料的 hook
- 共用元件資料夾
- 型別定義檔

要求:
- 沿用專案既有的 React Query pattern
- 重用現成的 Table、Modal、Select 元件
- 只准用 Tailwind

🚫 絕對不要動到:
- 全域的 routing
- 權限控管
- 任何被商品頁以外用到的共用 hook

「絕對不要動」那句話,就是把前半場看懂的東西變成 AI 的 guardrail。

Brownfield 的 Clean Code 觀念 [10:08]

很多人搞錯 Clean Code 的定義:

觀念 Greenfield Brownfield
Clean Code 自己覺得漂亮的寫法 跟前人一致的寫法

在 Brownfield 裡,所謂的 Clean Code 不是你自己覺得很漂亮的寫法,而是跟前人一致的寫法。所以 Guardrails 第一條永遠是:照著這個專案原本的樣子寫。沿用前人的 coding style,本身就是最高優先的 Clean Code。

步驟 4:拆解任務、小步迭代與 Code Review [10:28]

不要讓 AI 一次生出整個功能,拆成小步,每一步都親自 Review。

拆解順序

1. 先叫它只提出「元件結構跟資料流的規劃」
   └─ 先不要寫 code,等你確認方向對了

2. 再讓它只去改那個商品資料的 hook
   └─ 加上庫存篩選的參數,改完你 Review

3. 再讓它做篩選的畫面
   └─ Review

4. 最後才做編輯庫存的彈出視窗
   └─ Review

Brownfield Review 的專屬重點

跟 Greenfield 不一樣,你不是只看有沒有 bug:

Review 項目 問題
一致性 命名習慣、資料夾結構、抓資料放的位置跟前人一不一致?
共用檔案 有沒有偷偷改到共用的檔案?
重複造輪子 有沒有自己又刻了一個其實早就存在的元件?

讓 AI 當第一道防線

用資深前端工程師的角度,幫我 Review 這段改動:
- 它有沒有偏離專案既有的 React Query 寫法?
- 有沒有動到共用元件?
- 有沒有漏掉 loading 跟 error 的狀態處理?

但記住:AI 的 Review 是初審,終審永遠是你。 在 production 環境下,除非你已經很熟悉這套 codebase,或者這套 codebase 已經有很好的 harness 跟 context 管理,否則重要決策建議都先不要外包給 agent。

步驟 5:測試驗證與回歸檢查(Regression Check) [11:41]

回答影片一開始纏著你的恐懼:我改的東西,到底有沒有弄壞別人的功能? 到了這一步,勞力活回來了,所以兩條路又分岔。拆成三個部分:

5-1. 跑專案本來就有的測試 [11:52]

很多人完全忘記專案裡其實早就有一整套的測試——這是最快、最省力確認有沒有壞到既有功能的方法。

模式 做法
AI 輔助 動手前自己跑一次(確認綠燈)→ 動完手再跑一次
純指揮 動手前先跑一次專案既有的測試,跟我回報結果,之後每完成一小塊改動就再跑一次

如果你的專案根本沒有測試,那現在就是叫 AI 幫你補幾條關鍵測試的最好時機。

5-2. 看懂別人的 Error Log(部落知識)[12:28]

Brownfield 有一個經典的坑:很多專案有自己一套包裝過的錯誤紀錄機制(custom error logging)——可能是包裝過的 logger、一組統一的 error code、或固定要送去某個後台的格式。在公司裡這叫做部落知識(老鳥都懂,但沒有寫在任何文件裡)。

錯誤機制可能是:
├─ 包裝過的 Logger
├─ 統一的 error code
└─ 固定要送去某個後台的格式

Prompt

這個專案有自己的錯誤紀錄機制。讀一下負責這件事的 logger 檔案,
然後告訴我三件事:
1. 錯誤最後被送到哪裡?
2. 一筆 log 長什麼樣子?
3. 有沒有規定一定要帶哪些欄位?

然後示範一次:如果我這次的庫存編輯功能要沿用同一套 logging,
我該怎麼寫?

後果對比

❌ 隨手 console.error
   → 上線後根本不會被任何人看到
   → Debug 時找不到線索

✅ 照專案既有格式 + errorCode + metadata
   → 乖乖出現在該出現的地方
   → Debug 才找得到線索

注意:AI 幫你生 side project 時也常順手建了一套 error handling,你根本不知道它存在。結果你後來隨手寫的 console.error,根本沒有進到那個系統裡。

5-3. 回歸檢查(Regression Check)[13:36]

直接對付「訂單頁掛掉」事件的一招。

模式 做法
AI 輔助 拿著前半場 AI 標出的「hook 還被誰用到」清單,一個一個回頭驗
純指揮 見下方 Prompt

Prompt(純指揮)

我動了商品資料的 hook。
列出專案裡所有用到它的地方,逐一確認我的改動有沒有改變它原本的行為:
- 回傳的型別
- 參數
- 預設值
有沒有變?

如果既有的測試有覆蓋到這些地方,告訴我該跑哪幾個。

這一句話,就是你跟「改 A 壞 B」這件事的正式和解。


6. 完整走一次 [14:15]

把整條線套回開頭那個商品頁的任務:

❌ 之前的做法
   └─ "幫我加個庫存篩選跟編輯"(空需求)
      → 改 A 壞 B

✅ 五步工作流
   1. 分清楚這是 Brownfield
      └─ 知道自己是在別人的房子裡改廚房

   2. 選好你的路
      ├─ 自己拿著放大鏡逐間看房(AI 輔助)
      └─ 指揮 agent 幫你畫出建築藍圖(純指揮)
      → 都拿到了那張地圖,標出那根危險的共用水管

   3. 把既有的規矩(包含 coding style)
      寫成規格跟 guardrail

   4. 讓 AI 一小塊一小塊的寫
      → 每一塊都用資深的眼光親自 Review

   5. 用既有的測試、看懂的 log、回歸檢查
      客觀證明你這次沒有弄壞任何人的東西

同一個需求,同一個 AI,差別只在於你這次是先看懂,再動手,而不是閉著眼睛把整包 code 直接丟給它。


7. 核心觀念與進階路線

三條核心行動建議

原則 說明
嚴格執行 Prompt 限制 修改前務必加上「只分析不修改」或「絕對不可以修改 shared components」等 Guardrail 邊界指令
注重專案 Consistency 在舊專案中,最好的 Clean Code 就是「與前人寫法保持一致的程式碼」
逐步建立 Harness 與 Context 管理 從初階 Vibe Coder 晉升為具備系統化掌控力的 Agentic Engineer 的關鍵里程碑

AI 越強,流程越往純指揮收斂

現在
├─ 步驟 1-2:AI 輔助 ◄──┐
│   vs 純指揮           │ 兩條路
└─ 步驟 5:AI 輔助 ◄──┘

未來(AI 更強)
└─ 全部往純指揮收斂
   └─ 總有一天不會再有人手動貼檔案給 AI

身為 AI 原生工作者,很重要的能力之一就是:在被丟進一棟完全陌生的專案裡時,你要知道自己現在需要 agent 幫你探索,並帶著你理解,而不是直接擼起袖子幹活。

進階路線:Harness 與 Context 管理

如果你在開啟一個新專案時就已經有很好的 harness 跟 context 管理,那這些問題都不存在——真的只需要出一張嘴就好了。有能力搭建專案的架構、做好 context 管理,是 Vibe Coder 晉升 Agentic Engineer 的關鍵里程碑之一。


8. Prompt 模板

以下模板可直接複用,以「商品頁加庫存篩選」為例。

步驟 1:定位元件

[AI 輔助]
這是負責 {頁面} 的檔案。幫我分析這個畫面的結構:
- 它引入了哪些子元件,各自負責渲染什麼?
- 有沒有哪些看起來是全站共用,而不是這頁專屬的元件?
只分析,不要修改任何 code。

[純指揮]
畫面上 {區塊描述} 是哪個檔案在渲染的?幫我找出來。
分析它的元件結構,標出哪些子元件是全站共用的。
這個階段只做分析就好,不要改任何 code。

步驟 2:梳理 Dataflow

[純指揮]
幫我梳理 {頁面} 的 data flow:
- {資料} 是從哪個 API 來的?用哪一套工具在管理?
- 當 {角色} {動作} 時,資料是怎麼從畫面流回 server 的?
  把中間經過的 function 依序列出來。
- {資料 hook} 有沒有被 {頁面} 以外的地方用到?

步驟 3:Guardrails 需求

請在既有的 {頁面} 新增 {功能描述}。

動手前,先讀:
- {負責資料的 hook}
- 共用元件資料夾
- 型別定義檔

要求:
- 沿用專案既有的 {pattern}
- 重用現成的 {元件清單}
- {其他規範,如 styling 工具}

🚫 絕對不要動到:
- 全域的 routing
- 權限控管
- 任何被 {頁面} 以外用到的共用 hook

步驟 4:Review

用資深前端工程師的角度,幫我 Review 這段改動:
- 它有沒有偏離專案既有的 {pattern} 寫法?
- 有沒有動到共用元件?
- 有沒有漏掉 loading 跟 error 的狀態處理?

步驟 5-3:回歸檢查

我動了 {hook 名稱}。
列出專案裡所有用到它的地方,逐一確認我的改動有沒有改變它原本的行為:
- 回傳的型別
- 參數
- 預設值
有沒有變?

如果既有的測試有覆蓋到這些地方,告訴我該跑哪幾個。

參考資料

相關筆記

  • [[AI Coding 工作流]]
  • [[Vibe Coding 實踐筆記]]
  • [[Guardrails 設計原則]]
  • [[Code Review Checklist]]