前一天我們談 Loop Engineering。
核心是把:
Agent Loop
Verification Loop
Event Loop
Improvement Loop
疊成一個可以自己執行、驗證與收斂的系統。
但 Loop Engineering 之後,很快會碰到另一個問題:
每一步都需要問或讓模型決定「下一步要做什麼」嗎?
例如一個 Coding Workflow:
先分類 Issue
↓
進入對應 Specialist
↓
完成修改
↓
一定要 Review
↓
Review Fail
↓
回去修改
↓
Review Pass
↓
結束
這裡有很多 Control Flow,在第一次 Model Call 前其實就已經知道。
如果全部交給 Agent 決定:
完成修改後要不要 Review?
Review Fail 後要做什麼?
Approval 前可以 Send 嗎?
系統會多出三種成本:
Model 每次都在重新推理一個我們本來就知道答案的問題。
這就是 Graph Engineering 要處理的邊界。
今天的核心原則:
Code 負責已知結構,Model 負責真正需要 Judgment 的部分。
很多系統為了保持 Agentic,會刻意避免寫固定 Workflow。
例如:
你現在可以:
research
implement
review
deploy
請自己決定下一步。
看起來很靈活。
但如果業務規則本來就是:
Deploy 前一定要 Review。
那讓 Model 決定:
要不要 Review?
並沒有增加有價值的 Autonomy。
只是把 Deterministic Rule 變成 Probabilistic Routing。
Graph Engineering 真正要問的是:
哪些 Decision 根本不是 Judgment,而是 Control Flow?
一個最小 Graph 可以拆成:
Node 可以是三種完全不同的東西。
完全 deterministic。
例如:
parse input
validate schema
check permission
read cache
不需要 Model。
只做一次 LLM Call。
例如:
classify ticket
extract intent
score risk
需要 Judgment,但範圍很小。
完整 Agent Loop。
例如:
Research Agent
Coding Agent
Debugging Agent
Node 內部可以:
Graph 只決定:
什麼時候讓這個 Agent Run。
可以把 Node 看成一條 Spectrum:
Code
↓
Model Call
↓
Agent Loop
越往下:
所以不是所有 Node 都應該做成 Agent。
例如:
檔案存在嗎?
用 Code。
這個 Issue 是 bug 還是 feature?
可能用 Model。
找出 Root Cause 並修正。
適合 Agent Node。
原則是:
把最便宜、最 deterministic 的 Mechanism 放在能解決問題的最外層。
Node 做工作。
Edge 決定下一個 Node。
例如:
classify
↓
route == "math"
→ math_agent
route == "prose"
→ prose_agent
重點是:
Edge 由 Harness 在 Code 中判斷。
不是再呼叫一次 LLM:
請問下一步應該走 math_agent 還是 prose_agent?
如果 route 已經存在 State 中,Code 可以直接判斷。
Routing 不需要額外 Token。
最簡單:
implement
→ review
沒有選擇。
永遠 Review。
例如:
review
↓
passed?
├── Yes → END
└── No → implement
仍然由 Code 看 State 決定。
Checker 可以是 Model。
但:
PASS 要去哪裡,FAIL 要去哪裡
是固定規則。
不需要再問 Model。
很多人聽到 Graph,會先想到:
DAG。
但 Agent Workflow 很常需要 Cycle。
例如:
Implement
↓
Review
↓
Fail
↓
Implement
或者:
Draft
↓
Evaluate
↓
Revise
↓
Evaluate
Loop Engineering 裡的 Verification Loop,其實就是一個最小 Graph:
Worker
↓
Checker
↑ ↓
└ Fail
所以 Loop 可以看成 Graph 的一種特殊形狀。
Graph 有 Cycle 之後,又回到 Day 23 的原則。
例如:
review fail
→ implement
如果永遠 Fail,就會:
implement
review
implement
review
implement
review
...
所以 Graph Runner 仍需要:
step_budget
Budget 用完:
Escalate
而不是讓 Model 決定:
我覺得差不多該停了。
Node 之間不能只靠 Prompt 傳遞資訊。
最好有一個結構化 State。
例如:
task
route
draft
review
attempt
artifacts
approval
每個 Node:
Read State
↓
Do Work
↓
Return Updates
例如:
classify
returns:
route = "math"
接著 Edge 讀:
state["route"]
決定:
math_agent
錯誤做法:
每個 Node 都重新輸出整份 State。
這會增加:
比較好的 Contract 是:
Node reads:
需要的 State
Node returns:
它真正改變的 keys
例如:
review_node
returns:
verdict
review_notes
這讓 State Change 可追蹤。
假設 Shared State 很大:
50K logs
20 files
4 subagent results
full conversation
math_agent 不一定全部需要。
Graph Node 可以自己有 Prompt Builder:
Graph State
↓
Select Node-relevant State
↓
Fresh messages[]
↓
Agent Node
這和 Day 9 Context Management 是同一個問題。
這裡有兩種常見設計。
每個 Agent Node 都重新建立 Context。
適合:
例如:
Security Review
Performance Review
Documentation Review
各自只看到必要資料。
不同 Phase 共用同一段 messages[]。
例如:
Explore
↓
Implement
↓
Review
Explore 發現的細節直接留給 Implement。
Review 也看到前面的決策。
優點:
Handoff Loss 小。
缺點:
Context 一直變大。
這是一個 Context Engineering Decision。
不是哪個永遠比較好。
如果一個 Job 有固定階段,也可以把每個 Phase 視為 Node。
例如:
Explore
↓
Implement
↓
Review
每個 Phase 可以有不同 Prompt 與 Tool Set。
Prompt:
先理解,不要修改。
Tools:
read
search
Prompt:
根據 Evidence 做最小修改。
Tools:
read
write
shell
Prompt:
尋找問題,不要再修改。
Tools:
read
review
也就是:
Graph 不只控制下一個 Prompt,也可以控制每個 Phase 的 Capability Surface。
一個實用設計是:
Model 決定自己什麼時候完成 Phase,但 Harness 決定完成後去哪裡。
例如 Explore Agent 有一個 Tool:
finish_exploring()
模型覺得已經找到足夠資訊時呼叫它。
Harness 收到後:
Explore
→ Implement
所以:
Model
決定:
我準備好了
Harness
決定:
準備好之後只能去哪
這是一個很好的 Judgment / Control 分工。
很多所謂「Agent Pattern」,其實只是不同 Graph Shape。
A
↓
B
↓
C
每個 Node 做一小段工作。
適合固定 Pipeline。
Classifier
├── Finance
├── Coding
└── Support
先判斷類型,再送 Specialist。
┌→ Agent A ─┐
Task ──┼→ Agent B ─┼→ Merge
└→ Agent C ─┘
可以是:
每個 Agent 處理不同部分。
多個 Agent 處理同一問題,再做 Voting。
Orchestrator 根據 Runtime Task 動態產生 Worker。
例如:
Research Topic
↓
Orchestrator
├── Source A
├── Source B
├── Source C
└── Source D
↓
Merge
Worker 數量不固定。
但整體仍然是一個 Dynamic Graph。
Worker
↓
Evaluator
├── Pass → END
└── Fail → Worker
這就是 Day 23 的 Verification Loop。
Graph Engineering 把它正式變成一個 Subgraph。
這是今天最重要的反面問題。
不是流程越複雜,就越應該 Graph 化。
有些 Task 本質非常 Open-ended:
你根本不知道:
正確路徑會經過哪些 Step。
如果硬畫 Graph:
Step 1
Step 2
Step 3
反而會阻止 Agent 找到新的路。
所以重要原則是:
只 Encode 你本來就一定會 Enforce 的結構。
例如:
一定先 classify
一定 review before merge
一定 approval before external side effect
這些很適合 Graph。
但:
Debug 一定先看 file A
再看 file B
再跑 command C
可能太 rigid。
Day 6 我們談 Planning。
可以用一句話區分:
不知道路徑。
讓 Model 根據 Observation 動態決定。
知道結構。
直接把它寫進 Code。
例如:
Root Cause 怎麼找?
→ Planning
找到 Fix 後一定要跑 Test
→ Graph
這也是整個系列很重要的設計原則:
不要把 Deterministic Workflow 偽裝成 Agent Reasoning。
真正的 Production System 通常不是:
100% Graph
也不是:
100% Agent
而是:
Graph
├── Code Node
├── Model Node
├── Agent Node
├── Approval Node
└── Verification Node
Graph 保證:
Agent Node 處理:
這樣可以把 Model Token 花在真正有價值的地方。
Long-running Graph 也會遇到:
跑到 Node 7 時 Process 掛掉。
如果 Resume 從 Node 1 開始:
所以每個 Node 完成後可以寫 Journal:
node
input_state_version
output
status
timestamp
Resume 時:
Replay finished nodes
↓
Continue from first unfinished node
這和 Day 13 Task System 的 Checkpoint 是同一個概念。
Graph 天然適合 Observability。
因為每次執行可以留下:
classify
↓
math
↓
check
↓
math
↓
check
↓
END
這讓你可以直接分析:
甚至可以發現 Dead Branch:
某個 Edge
過去 30 天從未被觸發
這可能代表:
Graph Structure 本身也變成 Observability Surface。
每個重要 Checker Node 都應該回答:
Fail 後去哪?
錯誤設計:
Implement
↓
Check
↓
Deliver
即使 Check Fail,還是往下。
正確應該是:
Check
├── Pass → Deliver
└── Fail → Implement
Verification 沒有 Failure Edge,就只是 Decoration。
假設已經有:
state["approved"] = False
卻還呼叫 Model:
現在可以 Deploy 嗎?
這就是把 State Machine 重新外包給 LLM。
如果答案可以由:
if approved:
決定,就用 Code。
優點:
Graph Engineering 很容易讓人上癮。
最後變成:
100 nodes
300 edges
47 conditions
所有 Model 行為都被微管理。
結果:
所以和 Day 1 Harness Thesis 一樣:
更多 Harness 不一定更好。
Graph 只應該 Encode 已經確定的 Control Structure。
即使答案已經在 State。
問題:
Token、Latency、Variance。
Open-ended Task 被固定流程限制。
問題:
Agent 找不到預期外的正確路徑。
Fail 後仍往下。
問題:
Verification 沒有控制力。
Review / Revise 無限循環。
問題:
Cost Explosion。
每個 Node 都 Dump 全部 Output。
問題:
後面的 Agent Node 被 Context 淹沒。
跑到第七個 Node 掛掉,從頭重跑。
問題:
重複工作與 Side Effect。
失去 Context Isolation。
問題:
Token 增加、注意力下降。
模型永遠不呼叫 Gate。
問題:
只能靠 Budget 強制終止。
先從四個東西開始:
nodes
edges
state
budget
例如:
nodes = {
"classify": classify,
"math": math_agent,
"prose": prose_agent,
"check": check,
}
edges = {
"classify": route,
"math": "check",
"prose": "check",
"check": after_check,
}
Graph Runner 只做:
Run Node
↓
Merge State Update
↓
Record Trace
↓
Evaluate Edge
↓
Next Node
直到:
END
或:
Budget Exhausted
最值得先 Encode 的通常不是所有 Agent 行為。
而是:
Review before merge
Approval before send
Verification before complete
Task Type → Specialist
Check fail → Retry
Collect → Process → Verify
先把真正 deterministic 的部分拉出模型。
效果通常最明顯。
可以這樣理解:
Loop Engineering
問:
怎麼讓整個系統持續執行並收斂?
Graph Engineering
問:
這個持續執行的系統中,哪些路徑其實已經知道?
Loop 是最小 Graph。
Graph 則把:
一個 Loop
擴展成:
多個 Node
+
明確 Edge
+
Cycle
+
Shared State
兩者不是競爭關係。
Graph 是對 Loop 的 Generalization。
Day 23 我們建立外層 Loop。
今天加入:
這時 Harness 不只是:
讓 Agent 一直做下一步。
而開始明確決定:
哪些 Step 可以自由 Reason,哪些 Transition 不需要 Reason。
Graph Engineering 最重要的問題不是:
要不要使用某個 Graph Framework?
而是:
下一個 Step 真的是一個需要 LLM Judgment 的問題嗎?
如果答案本來就知道:
Review Fail
→ 回去修改
那就寫進 Code。
如果答案需要理解新 Evidence:
Root Cause 是什麼?
再交給 Model。
最重要的原則:
Encode the route you already know. Spend the model where judgment is needed.
這也代表我們走到了整個 Agent Harness Architecture 最後一層。
從 Day 1 的:
Model
+
Harness
到現在:
Graph
↓
Loops
↓
Agents
↓
Models
↓
Tools
Model 仍然負責 Judgment。
但整個系統的:
都已經成為 Harness 可以明確控制的工程問題。
完整系列與程式碼範例收錄於 https://github.com/hardness1020/awesome-agent-architecture