為 AI Agent 實施測試驅動開發 (TDD)
AI agent 經常產生模糊、過於複雜或同義反覆的測試,因為它們是在通常缺乏品質的人類撰寫範例上進行訓練的。為了克服這一點,開發者可以為 agent 提供特定的「技能」——基於永恆的軟體工程原則的結構化指導——以強制執行理性的測試驅動開發 (TDD) 流程。
Specify-Encode-Fulfill (SEF) 迴圈
有效 AI TDD 工作流的核心是 Specify-Encode-Fulfill (SEF) 迴圈,它作為傳統 red-green-refactor 循環的高層次替代方案。這個過程確保 AI 在嘗試編寫代碼之前理解需求。
- Specify: 定義功能或修復的清晰規格。
- Encode: 將這些規格轉換為自動化、可執行的測試。
- Fulfill: 編寫滿足規格所需的最小量代碼。
將 Canon TDD 應用於 AI Agent
整合 Kent Beck 的 Canon TDD 可以提供 agent 所需的戰術指導,以避免「投機性編碼」(speculative coding)——編寫比需要更多的代碼,這會增加引入未經測試邏輯的風險。
其操作流程遵循以下步驟:
- List Specifications: 在當前會話的範圍內建立一份完整的規格清單。
- Encode Tests: 將清單中的每個項目轉換為自動化測試。
- Incremental Implementation: 僅進行足夠的代碼變更以使當前的測試失敗消失。
- Isolated Refactoring: 僅在提交行為變更後進行重構;絕不要將行為變更與重構混在一起。
- Iteration: 重複此過程直到規格清單清空。
多 Agent 審查與設計驗證
為了減少偏見並提高代碼品質,建議使用多 agent 架構。使用不同的 agent 擔任不同角色可以防止主要 agent 忽略自身的錯誤。
Test Design Review
專門的 Test Design Review agent 會分析測試是否違反設計原則,特別是檢查測試是否關注於「手段」(how it is done) 而非「目的」(what the result is)。
Software Design Review
通用的軟體設計原則,例如準確命名 (「稱呼事物其應有的名稱」),是透過 Software Design Review 技能來強制執行的。這確保了 TDD 流程不僅產生通過的測試,還能產生可維護的代碼。
「清理廚房」啟發式方法
在 agent 指令中加入直觀的比喻可以產生意想不到的效果。例如,指示 agent 如果測試難以編寫,它可能需要「在做晚餐前先清理廚房」(重構現有代碼以使新功能更容易實現),這會鼓勵 agent 暫停並建議必要的準備性重構。
社群觀點與反對意見
雖然 SEF 迴圈提供了一條通往品質的結構化路徑,但開發者社群對於 LLM 時代下 TDD 的效用仍有分歧。
支持在 AI 工作流中使用 TDD 的論點
有些開發者認為,測試是將 AI 維持在護欄內的關鍵槓桿。一位用戶指出,生成用於審查的獨立 agent 可以顯著提高代碼品質並減少 bug,並認為額外的 token 成本低於稍後修復 bug 的成本:
"Spawning separate agents to review the original agent's implementation results in a very noticeable increase in code quality and decrease in bugs."
反對在 AI 工作流中使用 TDD 的論點
批評者認為,在 agentic 開發中,由於 token 成本以及 AI 傾向於「幻覺」測試或僅僅更新測試以匹配有 bug 的代碼而非修復代碼本身,因此 TDD 是低效的。
- Token Overhead: 一些用戶聲稱 TDD 會「使 token 成本膨脹」並與「瀑布式」方法相比,使開發速度變得很慢。
- Fragility: 有人擔心 AI 可能在測試失敗時直接修正測試,有效地將規格變更為以匹配實現。
- Redundancy: 有些人認為現代 LLM 可以編寫出很大程度上無 bug 的專家級代碼,使得 TDD 的開銷銷償成本過高。
驗證策略
為了確保測試不僅僅是表面功夫,有些人建議進行驗證測試,即故意將 bug 注入代碼中,以驗證測試是否真的會失敗,從而確認測試具備檢測回歸的能力。