AI-First Software Engineering:從 AI Coding 到 Agent Coding 的工程方法
前言:AI Coding 已經不是「幫我寫一段 Code」
過去談 AI Coding,通常是在討論:
AI 能不能幫我產生一段程式碼?
但現在的開發工具已經逐漸從「Code Completion」走向「Agent」。
Agent 不只是產生 Code,而是可以自行:
- 搜尋專案
- 閱讀檔案
- 分析依賴
- 修改程式
- 執行測試
- 查看錯誤
- 再次修改
- 重複驗證
因此,軟體工程面對的問題也發生了變化。
以前我們關心:
「這段 Code 寫得好不好?」
現在還必須增加一個問題:
「Agent 能不能在有限的 Context 與 Tool Call 下,找到正確的位置,完成正確的修改,而且不要擴大影響範圍?」
這就是我認為 AI-First Software Engineering 真正值得討論的地方。
它不是「讓 AI 多寫 Code」。
而是:
讓系統更容易被 Agent 定位、理解、修改與驗證。
一、從 AI Coding 進入 Agent Coding
傳統 AI Coding 的流程很簡單:
Developer
↓
Prompt
↓
AI
↓
Code
Agent Coding 則更接近:
Developer
↓
Goal
↓
Agent
├── Search
├── Read
├── Analyze
├── Modify
├── Test
├── Inspect Error
└── Retry
最大的差異在於:
Agent 開始自己決定「下一步要看什麼、改什麼、測什麼」。
因此,工程師控制的已經不只是 Prompt。
還包括:
- Agent 可以搜尋什麼
- Agent 可以讀多少
- Agent 可以修改什麼
- Agent 可以呼叫哪些工具
- Agent 什麼時候應該停止
- Agent 發現問題後能不能自行擴大 Scope
這也是為什麼單純討論 Prompt Engineering 已經不夠。
二、Agent 時代,Token 問題不只是 Prompt 長度
很多人談 Token Optimization 時,第一個想到的是:
Prompt 寫短一點。
這確實有幫助,但在 Agent 模式下,通常不是主要問題。
因為真正進入 Context 的內容可能包括:
Initial Prompt
+
Repository Search Results
+
File Contents
+
Tool Outputs
+
Test Results
+
Error Logs
+
Previous Reasoning Context
+
Repeated Context
因此可以用一個簡化模型理解:
Agent Cost
≈
Context Size
×
Tool Calls
×
Iteration Count
這不是嚴格的計費公式,而是一個工程上的思考模型。
例如一個原本只需要修改 10 行的需求:
修改 B12 標題長度
理想流程可能是:
Search B12
↓
Locate b12Steps()
↓
Read relevant code
↓
Modify
↓
Test
但如果 Agent 開始:
Search B12
↓
Read Schema
↓
Read Registry
↓
Read SharedFields
↓
Read Block Service
↓
Read Permission
↓
Read API Resource
↓
Read Model
↓
Run full test suite
↓
Test failure
↓
Read more code
↓
Modify unrelated code
真正浪費的就不是「Code 多少」。
而是:
Agent 為了一個局部需求建立了過大的 Context。
所以 AI-First 的第一個核心原則不是:
Write Less Code
而是:
Understand Only What Is Necessary.
三、Context 是 Agent 的工程資源
在人類工程師的世界裡,我們會管理:
- CPU
- Memory
- Database Connection
- Network
- Build Time
Agent 時代,我認為還應該把:
Context
視為一種工程資源。
因為 Context 越大,不代表 Agent 一定越聰明。
反而可能增加:
- 無關資訊干擾
- 推理成本
- 工具輸出成本
- 錯誤判斷
- 修改範圍
- Token 消耗
所以好的 Agent Workflow 應該遵循:
Search
→ Locate
→ Read Relevant Context
→ Decide
→ Modify
而不是:
Read Everything
→ Understand Everything
→ Modify
這個差異非常重要。
四、不要追求「最少檔案」,要追求「可定位性」
這是 AI-First 架構很容易被誤解的地方。
有人會說:
「既然 Agent 不喜歡跨檔案,那是不是所有東西都放在同一個檔案?」
不是。
大型系統如果過度集中,同樣會造成:
- 高耦合
- 高認知負擔
- 修改風險
- Merge Conflict
- 測試困難
所以真正值得優化的不是:
File Count
而是:
Navigation Cost
例如:
protected static function b12Steps(): Block
{
// ...
}
這種明確的方法命名,本身就是一個 Navigation Point。
當需求是:
修改 B12 的步驟標題限制
Agent 可以透過:
B12
→ b12Steps()
→ title
→ maxLength()
快速定位。
相反地,如果整個 CMS 都依賴:
buildBlock($type, $config)
再由多層 Registry、Factory、Resolver、Provider 動態組裝,
雖然架構可能很抽象,但 Agent 必須追蹤更多執行路徑。
因此:
AI-Friendly Architecture 並不代表少抽象,而是抽象必須具有可追蹤性。
五、命名在 Agent 時代變得更加重要
人類工程師可以透過 IDE、經驗與上下文理解:
handle()
process()
build()
resolve()
transform()
到底在做什麼。
Agent 也能理解,但需要更多 Context。
相比之下:
buildInvestorBlocks()
resolvePageBlockPermission()
exportAgeFriendlyTranslations()
syncProjectProgressItems()
這些名稱本身就提供了更多語意。
所以在 Agent Coding 裡:
Good Naming 不只是可讀性問題,也是 Context Compression。
一個好的名稱可以減少 Agent 為了理解「這個方法到底在做什麼」而需要讀取的 Code。
六、真正要避免的是 Hidden Convention
大型 Laravel 專案通常存在大量 Convention:
Permission Naming
Resource Naming
Translation Handling
File Storage
API Response
Model Traits
Shared Fields
Import / Export
Cache
對熟悉專案的人來說,這些規則可能是「常識」。
但對 Agent 來說,如果規則只存在於:
- 某個資深工程師的腦中
- 過去 PR
- 某個不明顯的 Trait
- 一個歷史遺留的寫法
Agent 就很容易自行推測。
而 AI 最危險的地方之一就是:
它通常可以提出一個看起來合理、但不符合你專案既有規則的答案。
例如專案已經有:
SharedFields
FeaturePermissionService
HasTranslatable
BaseTranslationService
BlockRegistry
Agent 卻另外建立:
NewHelper
NewService
NewTrait
NewRepository
從單一檔案來看可能沒有問題。
但從整個系統來看,這是在增加第二套 Convention。
因此:
Reuse Before Create
應該成為 Agent Coding 的基本規則。
七、Agent 不應該自行發明 Architecture
Agent 很容易出現一種行為:
需求:
修正一個欄位驗證。
Agent:
「為了提高可維護性,我建議建立 ValidationService。」
這就是典型的:
Speculative Architecture
它不是一定錯。
問題是:
目前需求真的需要嗎?
如果現有程式碼已經可以:
->maxLength(12)
完成需求,那麼建立:
ValidationService
ValidationInterface
ValidationResolver
ValidationFactory
就可能只是增加系統複雜度。
所以 Agent 應該遵循:
Existing Pattern
↓
Can it solve the problem?
↓
Yes → Reuse
↓
No
↓
Consider New Abstraction
而不是:
New Requirement
↓
New Class
↓
New Service
↓
New Abstraction
八、Minimal Diff 比「漂亮重構」更重要
Agent 最容易做的一件事就是:
順便幫你整理。
例如:
需求:
修改 B12 標題長度
理想 Diff:
- ->maxLength(10)
+ ->maxLength(12)
但 Agent 可能變成:
- 重構 B12
- 抽 Helper
- 調整命名
- 整理 imports
- 修改其他 Block
- 調整 Registry
- 修改測試
最後得到:
+80
-120
這時候即使 Code 本身沒有明顯問題,Review 成本也大幅增加。
更重要的是:
你已經很難快速確認「真正的需求修改」在哪裡。
所以:
Minimal Diff Principle
不是追求 Diff 數字越小越好。
而是:
Diff 應該與需求的必要變更高度相關。
九、Small Diff 的真正價值是縮小 Regression Scope
假設:
修改 A
只影響:
A
那測試範圍可能就是:
Test A
但如果 Agent 順便修改:
A
B
C
Shared Helper
Base Service
測試範圍就可能變成:
A
B
C
所有使用 Shared Helper 的功能
所有使用 Base Service 的功能
因此:
Small Diff
↓
Small Dependency Change
↓
Small Regression Scope
↓
Faster Verification
這是 Agent Coding 很重要的工程價值。
十、Agent 最大的風險之一:Scope Creep
Agent 很容易從:
Fix A
變成:
Fix A
→ 發現 B 不漂亮
→ 修 B
→ 發現 C 可以重構
→ 修 C
→ 發現 D 架構問題
→ 修 D
最後:
原本一個 Bug Fix 變成 Architecture Refactoring。
因此我認為 Agent 必須明確區分:
Observation
Agent 發現了一個問題。
與:
Authorization
Agent 被允許修改這個問題。
兩者完全不同。
例如:
Agent 發現:
SharedFields 有歷史技術債。
正確行為:
報告:
發現 SharedFields 存在另一個問題,
但此問題不在本次 Scope。
而不是:
順手重構 SharedFields。
這是一個非常重要的 Agent Governance 概念:
發現問題 ≠ 獲得修改問題的授權。
十一、Agent 必須有 Stop Condition
傳統程式:
while (...)
如果沒有終止條件,就是 Bug。
Agent Workflow 其實也是一樣。
如果只告訴 Agent:
「直到問題解決為止。」
Agent 理論上可以:
Search
→ Modify
→ Test
→ Error
→ Modify
→ Test
→ Error
→ Search
→ Modify
→ Test
一直循環。
所以 Agent Task 應該有明確的 Stop Condition。
例如:
1. 已找到 Entry Point
2. 已確認 Root Cause
3. 已確認既有 Convention
4. 已完成最小修改
5. Diff 沒有無關變更
6. 相關測試通過
如果無法達成:
停止並報告,而不是無限嘗試。
這其實比「讓 Agent 更自主」更重要。
十二、Agent 的探索也應該是 Bounded Exploration
我不認為 Agent 應該完全禁止探索。
因為大型系統裡,真正的問題可能跨越:
Controller
→ Service
→ Model
→ Trait
所以正確方式不是:
不准讀其他檔案。
而是:
允許擴大 Context,但必須有理由。
例如:
Level 0
需求直接相關檔案
Level 1
直接 Dependency
Level 2
必要 Convention
Level 3
測試或錯誤相關程式碼
只有當目前 Context 無法做出正確決策時,才進入下一層。
這可以稱為:
Bounded Exploration
不是限制 Agent 的能力。
而是限制 Agent 的無目的探索。
十三、Tool Output 也是 Context
這是實際使用 Agent 時很容易忽略的問題。
很多人會控制:
「不要讀太多 Code。」
但忽略:
Search Result
Test Output
Log
Stack Trace
CLI Output
Git Diff
全部也可能進入 Agent Context。
例如:
grep "Project" .
可能得到數百筆結果。
如果 Agent 全部讀取,這些搜尋結果本身就成為 Context。
所以 Agent Tool 使用也需要控制:
Search → Narrow
Read → Relevant Range
Test → Targeted
Logs → Relevant Error
Diff → Current Change
換句話說:
Tool 不只是能力,也是 Context Generator。
十四、測試策略也必須 Agent-Friendly
AI 很容易被教成:
修改完 → 跑全部測試。
但大型專案這未必是最有效率的方法。
例如:
修改單一 Filament Block
第一階段可以:
Static Check
↓
Targeted Test
↓
Relevant Feature Test
如果涉及:
Shared Service
再擴大:
Related Test Suite
最後才考慮:
Full Test Suite
這不是說永遠不要跑完整測試。
而是:
驗證範圍應該與變更風險一起成長。
十五、Error Recovery 是 Agent Token 成本的大來源
Agent 真正容易浪費 Token 的地方,往往不是第一次修改。
而是:
第一次修改錯了之後怎麼辦?
例如:
Modify
↓
Test
↓
Error
↓
Read more
↓
Guess
↓
Modify
↓
Test
↓
Error
如果沒有控制,Agent 很容易進入:
Error → Guess → Modify → Error
的循環。
比較好的流程應該是:
Test Failure
↓
Identify Root Cause
↓
Locate Relevant Code
↓
Minimal Fix
↓
Retest
如果 Root Cause 無法確認:
Stop
↓
Report
而不是:
Guess another fix
這會同時降低:
- Token
- Diff
- Regression
- Debugging Cost
十六、因此 AI Coding Prompt 應該從「命令」變成「Contract」
好的 Agent Prompt 不只是:
幫我修這個 Bug。
而應該包含:
Goal
Scope
Constraints
Reuse Rules
Exploration Rules
Verification Rules
Stop Conditions
Output Format
例如:
AI Coding Task
Goal
[描述需求]
Scope
只允許修改:
- [File]
- [Class]
- [Method]
Before Modify
1. 先確認 Root Cause。
2. 找出 Entry Point。
3. 搜尋現有可重用實作。
4. 確認專案既有 Convention。
Constraints
- 不修改 Scope 以外的 Code
- 不新增檔案,除非確實必要
- 不新增 Service / Helper / Trait / Repository
- 不修改 DB / API / Architecture
- 不進行額外重構
- 不重新命名無關程式碼
Context Rules
- 優先 Search → Locate → Read
- 只讀取完成需求所必要的 Dependency
- 不要讀取無關檔案
- Tool Output 避免大量無關內容
Modification
- 使用最小必要 Diff
- 保留既有 Code Style
- 優先修改現有實作
Verification
- 檢查 Diff
- 執行最小必要測試
- 測試失敗時先確認 Root Cause
- 不因測試失敗而任意擴大 Scope
Stop Conditions
- 找不到 Root Cause
- 需要修改 Scope 外架構
- 需要新增重大抽象
- 無法確認需求
→ 停止並報告,不要猜測。
Output
- Root Cause
- Modified Files
- Modified Methods
- What Changed
- Impact
- Test Scope
這已經不是單純 Prompt。
比較接近:
Agent Coding Contract。
十七、專案本身也需要提供 Agent Context
不能所有事情都丟給 Prompt。
一個成熟的 AI-First 專案,應該把重要規則顯式化。
例如:
AI-CODING-RULES.md
ARCHITECTURE.md
CONTRIBUTING.md
或者更實際一點:
docs/
├── architecture/
├── conventions/
├── api/
└── development/
內容不需要寫成一本書。
重點是讓 Agent 可以快速知道:
這個專案怎麼做?
例如:
Authentication
→ 使用既有 Permission Convention
Translation
→ 使用 HasTranslatable
API Response
→ 使用既有 Response Wrapper
File Storage
→ 使用既有 FileUrlCast
CMS Blocks
→ 使用既有 Block Registry
這些規則如果被明確記錄:
Agent 就不需要從 Code 猜 Convention。
十八、但 Documentation 也不能無限制增加
這裡又有另一個陷阱。
為了讓 Agent 理解專案,開始建立:
50 個 Markdown
300 頁 Architecture Documentation
結果 Agent 每次又要讀大量文件。
這同樣會造成 Context 問題。
所以 Documentation 本身也應該遵循:
High Signal / Low Noise
好的文件應該回答:
這個專案有哪些不可違反的規則?
這個功能應該從哪裡開始找?
有哪些既有實作可以重用?
哪些事情禁止自行修改?
而不是把整個 Repository 再用 Markdown 描述一次。
十九、AI-First 不代表拋棄傳統 Software Engineering
這一點非常重要。
AI-First 不是:
AI > Architecture
也不是:
AI > Tests
更不是:
AI > Human Review
真正的關係應該是:
Software Engineering Principles
+
Agent-aware Workflow
↓
AI-First Engineering
依然需要:
- Cohesion
- Coupling Control
- Encapsulation
- Testing
- Security
- Observability
- Code Review
- Domain Boundaries
只是現在又多了一個使用者:
Agent
所以架構除了服務 Runtime 與 Developer,也開始需要考慮:
Agent 如何理解這個系統。
二十、Human-readable 與 AI-navigable 並不是二選一
真正成熟的架構不是:
Human-readable
vs
AI-readable
而是:
Human-readable
+
Machine-readable
+
Agent-navigable
好的程式碼依然需要讓人理解。
只是現在又增加一個要求:
Agent 能不能透過搜尋、命名、結構與 Convention 快速找到它?
因此我比較傾向使用:
AI-Navigable Architecture
而不是:
AI-Optimized Architecture
因為後者很容易讓人誤解成:
為了 AI 而犧牲正常的軟體工程。
真正的目標應該是:
讓人與 Agent 都能有效率地導航系統。
二十一、AI-First 的核心不是「少寫 Code」
如果把前面的概念全部整理起來,可以得到一個比較完整的模型:
Requirement
↓
Scope
↓
Search
↓
Locate
↓
Minimal Context
↓
Existing Convention
↓
Minimal Change
↓
Minimal Diff
↓
Targeted Verification
↓
Stop
其中任何一個環節失控,都可能增加成本。
例如:
Context 太大
→ Token 增加
Search 太廣
→ Tool Output 增加
Dependency 太深
→ 理解成本增加
Scope 太大
→ Diff 增加
Diff 太大
→ Regression 增加
Test 太廣
→ Verification 成本增加
Error Recovery 沒有控制
→ Agent Loop 增加
所以真正需要優化的是:
Change Path
而不只是:
Code Generation
二十二、我認為 AI-First 可以濃縮成六個原則
1. Locate Before Modify
先找到真正負責需求的 Entry Point。
不要沒有定位就開始寫 Code。
2. Reuse Before Create
先搜尋既有:
- Helper
- Service
- Trait
- Component
- Convention
- Enum
- Transformer
確認真的沒有,再考慮新增。
3. Context Before Complexity
不要讓 Agent 為了完成一個小需求理解整個系統。
必要時才擴大 Context。
4. Change Before Refactor
先完成需求。
不要把每一次 Bug Fix 都變成 Architecture Refactoring。
5. Verify Before Expand
先驗證目前修改。
測試失敗時先找 Root Cause。
不要因為錯誤就無限制擴大修改範圍。
6. Stop Before Guess
當需求、架構或 Root Cause 無法確認時:
停止。
比猜一個看起來合理的答案更專業。
二十三、最後重新定義「AI 開發效率」
如果只是:
AI 每分鐘產生多少行 Code?
這個指標其實沒有太大意義。
更有價值的應該是:
從 Requirement
到 Verified Change
中間需要多少:
- Context
- Tool Calls
- Agent Iterations
- Diff
- Regression Tests
因此可以用一個工程上的簡化模型:
Agent Efficiency
=
Correctness
×
Navigation Efficiency
×
Context Efficiency
×
Change Precision
×
Verification Efficiency
而不是:
Agent Efficiency
=
Lines of Code / Minute
因為:
寫出 1000 行錯誤 Code,比寫出 10 行正確 Code 沒有價值。
結語:AI-First 真正改變的是「變更成本」
我認為 AI Coding 真正帶來的變化,不是:
「以後工程師不用寫 Code 了。」
而是:
Code Generation 的成本下降之後,Context Management、Change Control 與 Verification 反而變得更加重要。
Agent 可以幫我們:
Search
Read
Write
Test
Fix
但 Agent 越自主,工程師越需要控制:
Scope
Context
Dependencies
Tool Calls
Diff
Regression
Stop Conditions
所以真正成熟的 AI-First Development,不是讓 Agent 擁有最大的自由度。
而是:
給 Agent 足夠的自由完成工作,同時給它清楚的邊界,避免它為了完成一個小需求而理解整個系統、修改整個架構、跑完整個測試套件。
最終可以把這套方法濃縮成一句話:
Don't optimize how much code the Agent can write. Optimize how little context the Agent needs to make one correct change.
而這也會逐漸改變我們對「好架構」的定義。
過去我們主要問:
人類工程師能不能理解這個系統?
現在還需要問:
Agent 能不能快速找到正確的位置、理解必要的 Context、做出最小變更,並且知道什麼時候應該停止?
這不是把 Software Engineering 交給 AI。
而是:
把 Agent 納入 Software Engineering 的設計範圍。
這才是我認為從 AI Coding 走向 Agent Coding 之後,真正值得討論的 AI-First Software Engineering。