昨天我把 Issue、修改、測試到 Code Review 串成一個比較完整的流程,單獨看一個 Issue 的時候其實已經很順了,Codex 可以先理解需求、找相關檔案、修改程式、跑測試,再把結果整理成 Pull Request,整個過程開始有一點真的把任務交給另一個工程師處理的感覺。
但真實專案很少會只有一張 Issue 安靜地排在那裡等你做完,通常是三、四個需求同時存在,而且它們還可能剛好改到同一個地方,所以今天我想把難度再往上拉一點,看看 Codex 面對多個 Issue 時會發生什麼。
我先準備三個彼此有一點關聯的需求,例如第一個 Issue 要修改使用者資料頁,第二個要增加欄位驗證,第三個則要調整 API 回傳格式。
如果分開交給 Codex,其實都不算困難,它可以找到 Controller、Service、Model 以及前端畫面,再依照需求完成修改,但當三個任務一起進入同一個專案後,事情就開始變得有趣。
因為第二個 Issue 可能會修改 Model,第三個 Issue 也會碰到同一個 Model,第一個 Issue 又剛好依賴這兩個改動,這時候即使每一張 Issue 都寫得很清楚,實際執行順序還是會影響最後結果。
我原本習慣把 Issue 當成一張一張獨立的工作單,但今天測試之後才比較明顯感覺到,很多任務表面上分開,底下其實共用同一批程式。
例如:
Issue #31
新增使用者電話欄位
Issue #32
新增電話格式驗證
Issue #33
API 回傳電話資料
如果先做 #33,當下的資料模型可能還沒有電話欄位,Codex 就可能自己先補一個欄位,接著 #31 又重新定義一次;另一種狀況則是 #31 修改完 Model 後,#32 根據新的結構加入 Validation,但 #33 還停留在舊版本,最後三個修改各自看都合理,合在一起卻開始出現重複或衝突。
所以多 Issue 的難度並沒有單純變成「一次做三倍的事情」,真正麻煩的是 Codex 要知道哪些工作應該先做,以及前一個任務完成後,後面的任務需不需要重新閱讀目前程式碼。
這次我沒有一開始就叫 Codex直接修改,而是先請它讀三張 Issue,再整理可能受到影響的檔案與依賴順序。
整理出來大概會像:
#31 User Model
↓
#32 Validation
↓
#33 API Response
看起來只是一個很小的步驟,但對後面的修改差很多,因為 Codex 開始知道 #32 應該建立在 #31 完成之後,#33 又需要確認前兩個 Issue 最後留下的資料結構。
這也讓我開始覺得,Coding Agent 真正要處理的其實不只有程式碼,Issue 之間的關係也是專案 Context 的一部分。
另外一個很容易遇到的問題是 Branch。
假設三個 Issue 都直接從原本的 main 建立:
main
├── issue-31
├── issue-32
└── issue-33
那麼 issue-32 根本看不到 issue-31 新增的欄位,issue-33 也不知道前面兩個 Branch 做了什麼,最後 merge 時自然很容易發生衝突。
如果任務真的存在依賴,就可能要改成:
main
└── issue-31
└── issue-32
└── issue-33
或者先完成一個 Issue、Merge 回主要開發分支,再讓 Codex重新取得最新版本繼續下一張。
以前自己寫程式的時候,這些順序很多都是很自然地在腦中處理掉,交給 Agent 之後才發現,如果沒有明確讓它知道 Branch 狀態與任務依賴,它其實很容易在一個過期的 Context 裡做出看起來完全合理的修改。
我也故意讓兩個 Issue 同時修改同一個檔案,看看 Codex 遇到 Merge Conflict 會怎麼處理。
簡單的衝突它確實可以理解,例如兩邊只是新增不同欄位,通常很容易合併,但如果兩個 Issue 都改了同一段商業邏輯,事情就沒有那麼單純。
像這種:
Issue A:
登入失敗三次後鎖定帳號
Issue B:
登入失敗五次後要求驗證碼
這時候已經不是單純選左邊或右邊的程式碼,兩張 Issue 的需求本身可能就需要重新確認。
所以我現在會希望 Codex 在這種情況停下來,把衝突位置、兩個需求以及它目前看到的差異整理出來,而不是自己猜哪一邊才是正確答案。
前幾天測試 Codex,我主要都在看它能不能理解 Repository、修改程式、跑測試以及做 Review,到了今天開始同時處理多張 Issue 後,測試的東西已經慢慢從「它會不會寫程式」變成「它能不能維持整個專案的狀態」。
因為專案一旦開始並行開發,就會出現 Branch、Dependency、Conflict、舊 Context、修改順序這些東西,任何一個地方沒有處理好,最後產生的程式都可能單獨正確、整合後卻失敗。
所以今天我沒有特別追求一次把三張 Issue 全部做完,反而比較在意 Codex 能不能先看懂它們之間的關係,再決定執行順序。
明天我想繼續往這個方向測,當 Repository 裡開始累積很多 Branch、Pull Request 與修改紀錄之後,Codex 到底應該讀多少歷史 Context,又要怎麼避免被早就過期的資訊影響。