工程實作 11 min read

12-Factor Agents vs 我的遊戲專案:3 條原則,同一個坑

HumanLayer 的 12-Factor Agents 有 24.2k star,我對照自己寫 Splendor 網頁版時踩出的工程紀律,發現其中 3 條原則我半年前就已經做對,這是實測後的對照筆記。

12-Factor Agents vs 我的遊戲專案:3 條原則,同一個坑
本文目錄 · 7

半年前我用 Claude Code 從零做了一款 Splendor 網頁版,規則引擎、React UI、單元測試、E2E 全部自己盯過一輪。那時候沒讀過任何「AI agent 工程原則」的清單,純粹是被 bug 逼出來的紀律:規則引擎跟 UI 分開、用 fuzzing 抓 AI 寫的暗 bug、E2E 一定走完整 round-trip 不繞過引擎。

最近翻到 HumanLayer 的 12-Factor Agents,這個 repo 在 GitHub 上有 24.2k star、1.8k fork(2026-07-12 查證)。讀完 12 條原則,發現裡面至少 3 條,我半年前寫遊戲時就已經在做,只是沒人跟我說這是「原則」,我以為只是踩過坑之後的直覺反應。

這篇不是逐條翻譯 12-Factor Agents 的清單,坊間已經有夠多這種文章。我想做的是反過來:把我自己那個遊戲專案的真實程式碼、真實測試策略,拿去對照這份清單,看看「沒讀過原則但踩對了」跟「讀過原則」之間差在哪裡。

12-Factor Agents 是什麼

作者 Dexter Horthy 任職於 HumanLayer,他在 README 裡寫的起手式很直接:「什麼樣的原則,能讓 LLM 驅動的軟體真正好到可以交給生產環境的客戶用?」這個提問本身帶著一點不耐煩——他測過市面上大多數 agent framework,也訪談過 100 多位 SaaS 創辦人,觀察到的現象是多數團隊最後放棄框架,自己重寫控制流程。

這句話要小心讀。「多數團隊放棄框架自建」是作者自己訪談得出的觀察,不是我能獨立驗證的統計數字,但值得記住,因為它解釋了整份清單的口氣——不是「用這個框架」,是「這些是你自己動手時該守的紀律」。

12 條原則的標題列出來是這樣:

#原則
1Natural Language to Tool Calls
2Own your prompts
3Own your context window
4Tools are just structured outputs
5Unify execution state and business state
6Launch/Pause/Resume with simple APIs
7Contact humans with tool calls
8Own your control flow
9Compact Errors into Context Window
10Small, Focused Agents
11Trigger from anywhere, meet users where they are
12Make your agent a stateless reducer
License 方面,程式碼是 Apache 2.0,文字與圖片內容是 CC BY-SA 4.0(2026-07-12 查證)。

我沒有把 12 條全部走一遍的資格——遊戲專案本來就不是 agent 系統,硬要湊 12 條對照只會變成穿鑿附會。老實比對之後,真正站得住腳、有真實程式碼可以佐證的只有 3 條:Factor 8(Own your control flow)、Factor 9(Compact Errors into Context Window)、Factor 10(Small, Focused Agents)。剩下 9 條要嘛跟這個專案的形態不相關(比如 Factor 6 的 Pause/Resume,我的遊戲是同步回合制,沒有長時間掛起的需求),要嘛我沒有實測證據,寫了就是硬拗。

Factor 8:Own your control flow —— 對照我的 E2E round-trip 紀律

12-Factor Agents 裡這條講的是:別把控制流程整個丟給框架的 DAG 或 orchestrator 黑箱,自己掌握「下一步做什麼」的判斷邏輯。作者原文提到一個具體教訓:「把控制流程整個丟給框架,結果發現這行不通」(throw the DAG away... it turns out this doesn't quite work)。

我踩到的版本不是 orchestrator,是測試策略上的同一種誘惑。寫 Splendor 網頁版時,規則引擎(誰能買哪張卡、寶石夠不夠、貴族該不該來)跟 React UI 徹底分離——UI 只負責顯示狀態、送出使用者操作,規則引擎是一組純函式,吃狀態吐結果。

測試的誘惑是:規則引擎測過了,UI 元件測過了,兩邊都綠燈,應該就沒事了吧?我一開始也想抄捷徑,直接對規則引擎的輸出斷言就當作 E2E 過了。後來發現這樣測不出「UI 傳給引擎的資料格式錯了」「畫面沒有正確反映引擎回傳的新狀態」這類整合層的 bug——這正是「繞過控制流程本身」的陷阱,跟 12-Factor Agents 講的「別把流程判斷外包給看不見內部的黑箱」是同一種道理,只是我的黑箱是「假設兩邊分開測就等於整合測過了」。

改法是:E2E 測試一律用 Playwright 走完整使用者操作——點卡牌、選寶石、送出回合,一路走到畫面真的更新,不允許中途繞過引擎直接呼叫規則函式再斷言。控制流程的「真相」只能從使用者實際操作的那條路徑驗證,不能相信中間任何一層自己回報「我這邊沒問題」。

Factor 9:Compact Errors into Context Window —— 對照我的不變量測試 + fuzzing

這條原則講的是:錯誤發生時,把足夠的上下文壓縮進 agent 能處理的範圍內,讓它有機會自己修正,而不是讓例外直接往外炸、淹沒在一堆無關資訊裡。

我的對照版本發生在測試層,不是 runtime 錯誤處理層,但邏輯結構很像。AI 寫的規則引擎程式碼有個特性:看起來對,單元測試也過,但某個沒測到的邊界組合下會默默算錯——比如寶石數量在某種特殊回合順序下沒有正確歸零。這種 bug 靠人工寫測試案例很難撞到,因為你得先猜到那個特殊組合才會寫測試。

解法是不變量測試加 fuzzing:用固定 seed 的隨機數讓兩個 bot 自動對打幾百局,每一步結束都檢查遊戲的不變量(寶石總數守恆、卡牌不會重複發放)。一旦某個不變量在第 137 步被打破,fuzzing 框架會把那個 seed、那一步的完整遊戲狀態記下來,變成一個可重現的最小案例。

這跟 Factor 9 的精神重疊在「別讓錯誤資訊四散、要壓縮成可處理的東西」。fuzzing 抓到的不是「哪裡錯了」的模糊警報,是一組完整、可重播、可定位到具體那一步的狀態快照——跟原文說的「把錯誤壓縮進上下文視窗」是同一種工程直覺:錯誤要被馴服成可操作的訊號,不能放任它變成一堆雜訊。

Factor 10:Small, Focused Agents —— 對照規則引擎與 UI 的邊界

這條原則主張:agent 不該無限擴張職責範圍,保持小而專注的邊界,比一個什麼都做的大 agent 更容易掌控。

我的規則引擎從一開始就只做一件事:吃遊戲狀態和一個操作,回傳新狀態或拒絕原因。它不知道畫面長怎樣,不知道使用者用滑鼠還是鍵盤操作,不處理動畫、不處理音效。這個邊界帶來的直接好處是測試速度——純函式餵狀態、檢查結果,毫秒級跑完幾百個測試案例,不用啟動瀏覽器、不用等渲染。

反過來想,如果讓規則引擎順手處理一點 UI 邏輯(比如「這張卡目前是否高亮」),職責邊界就開始模糊,AI 改動 UI 的時候就有機會手滑動到規則判斷,而且測試規則邏輯會被迫拖著 UI 一起跑,速度變慢、案例變少。Small, Focused Agents 這條原則講的雖然是 agent 系統裡的分工,但「職責邊界清楚才好測、好維護」這件事,不限於 agent,寫遊戲規則引擎一樣適用。

三條對照關係整理成一張圖:

12-Factor Agents 對應原則

Splendor 網頁版踩過的紀律

對照

對照

對照

E2E 一律走完整 round-trip
不繞過規則引擎

不變量測試 + fuzzing
抓 AI 寫的暗 bug

規則引擎與 UI 徹底分離

Factor 8
Own your control flow

Factor 9
Compact Errors into
Context Window

Factor 10
Small, Focused Agents

剩下 9 條,我沒有資格對照

我不打算硬把其餘 9 條也套進這個專案。Factor 1(Natural Language to Tool Calls)、Factor 4(Tools are just structured outputs)這類講的是 LLM 跟外部工具互動的介面設計,我的遊戲專案裡沒有 LLM 在 runtime 做決策,套上去就是牽強附會。Factor 6 的 Launch/Pause/Resume 假設的是長時間執行、可能被打斷的任務,我的遊戲是同步回合制,沒有這個問題要解。

這也是我覺得這份清單值得認真看待的原因——它不是「把 12 條都做到才算及格」的檢查清單,是從真實生產踩坑裡萃取出來的一組獨立原則,不同專案會踩中不同的子集。硬要湊滿反而是灌水。

這份清單對正在做 agent 的人有什麼用

如果你正在自己動手做 AI agent,不管是遊戲裡的 bot、內部工具還是客服系統,12-Factor Agents 這份清單最大的價值不是照抄,是拿來對照自己已經做的決定,看看有沒有踩中共通的坑。我自己的經驗是:先有真實專案跌過的痛,再讀這種原則清單,會比先讀清單再套用有感得多——因為你已經知道「為什麼」,清單只是把直覺變成可以講給別人聽的語言。

原文作者也提到一個現實判斷:80% 的品質對大多數面向客戶的功能來說不夠用(80% quality isn't good enough for most customer-facing features)。這句話跟我自己的經驗吻合——AI 寫的規則引擎第一版能跑,但「能跑」跟「賽局規則在所有邊界組合下都對」中間那段差距,只能靠測試策略去補,靠人盯著看是補不完的。

如果你想看這 3 條原則在真實程式碼裡長什麼樣子,可以參考我之前寫的《用 Claude Code 從零做一款遊戲》,裡面有完整的架構拆解跟測試策略細節。

常見問題

Q:12-Factor Agents 是一個框架嗎?需要安裝什麼套件?
不是。它是一份原則清單(GitHub repo,MD 文件為主),沒有對應的 npm 套件或 SDK 要安裝。原則本身是框架無關的,你可以在任何語言、任何 agent 實作方式裡套用。

Q:這份清單只適用於「AI agent」專案嗎?
不完全是。這篇文章的重點正是:即使你的專案裡沒有 LLM 在 runtime 做決策(像我的規則引擎遊戲),裡面關於控制流程、錯誤處理、職責邊界的原則,依然是通用的軟體工程紀律。

Q:要把 12 條原則全部做到才算合格嗎?
不用,也不該勉強湊滿。這份清單是從不同生產案例萃取出的獨立原則,不同專案的架構會踩中不同子集。硬套用不相關的原則(例如把 Pause/Resume 套進一個同步系統)只會讓設計變得奇怪。

author
陳彥彤

AI 工程師 · AI 顧問。Java 後端 8 年、AI 工程師 2 年。AI 內訓 · AI 導入顧問 · 前後端與雲端培訓。

support

覺得文章有用可以到 GitHub 給個 star,或是透過信箱聊聊 AI 內訓、AI 導入顧問或前後端 / 雲端培訓。

related

相關文章

[工程實作] · 15min
用 Claude Code 從零做一款遊戲:不是會 prompt,是會這三件工程紀律
我用 Claude Code 從零做了一款 Splendor(璀璨寶石)網頁版 —— 規則引擎、React UI、單元測試、E2E、連 100 張卡牌插圖都生好,全程沒手寫幾行 code。但能跑得順的關鍵不是 prompt 寫得好,而是三件工程紀律:規則引擎跟 UI 徹底分離、用「不變量測試 + fuzzing」逼出 AI 看不到的暗 bug、E2E 走完整 round-trip 而不是繞過引擎。這篇拆解這套協作方法,附這個專案的真實程式碼。
[AI 工具] · 14min
good night, have fun:讓 AI Agent 過夜自己跑迴圈的 orchestrator(實測 0.1.41)
gnhf(good night, have fun)是把 coding agent 包成自動迴圈的 orchestrator,GitHub 3.2k star。實測安裝、7 種 agent 支援、小步 commit + 失敗回滾 + 連續失敗中止機制,以及它跟 ralph-loop / 手寫 while 迴圈差在哪。
[AI 工具] · 20min
CodeGraph vs grep:AI 讀 codebase 少 81% 工具呼叫的知識圖譜
CodeGraph 把整個 codebase 預先建成一張「程式碼知識圖譜」(symbol 節點 + call 邊),讓 Claude Code、Codex、Cursor 這類 AI agent 不用一個一個檔案爬,一次 codegraph_explore 就拿到相關 source、call path 跟改動波及範圍。官方在 7 個真實開源專案實測:VS Code 少 81% tool call、少 64% token,Alamofire 便宜 40%、快 33%。這篇把它是什麼、三層架構(tree-sitter + SQLite + file watcher)、安裝三件套、跟 grep / LSP 的差別、以及我接的時候要注意的點寫一遍。100% 本機跑、MIT、支援 23 種語言、8 個 agent。