快轉到主要內容

Loop Engineering:我一開始把它想得太簡單了

作者
GuanLin’s Latent Space
記錄每一個學習的瞬間,分享技術心得與成長歷程

這陣子第一次看到 Loop Engineering 這個詞。

一開始看到的時候,我直覺把它理解成:讓 Agent 自己一直跑。

但看完 Addy Osmani、Boris Cherny、Andrej Karpathy、Geoffrey Huntley 等人的相關文章內容,再加上幾篇中文整理後,我發現並不是一個很單純的概念。同一個「Loop」字,Karpathy 用來講 Agent 自己做研究,Boris Cherny 用來講「不再一輪一輪 prompt Agent,而是寫一個持續驅動它的系統」,也有人是拿它講整個軟體工程流程怎麼交給一組能持續工作的 Agent——大家講的不是同一件事,只是剛好用了同一個詞。

讀到後面,我比較在意另一個問題:如果真的讓 Agent 一直工作,究竟要靠什麼確定它是在往正確的方向前進?

這篇不是實作心得。我目前也還沒有真的把一套 Loop 放著跑一整晚,算是把幾篇文章讀完之後,整理一下自己目前如何理解這件事情。

我一開始把 Loop 想得太簡單了
#

如果把平常使用 AI Coding Agent 的方式畫出來,大概是:人給 Prompt,Agent 執行,人看結果、判斷,再給下一個 Prompt,Agent 再執行。人就是那個 Loop——看到結果之後決定下一步要做什麼,再交給 Agent。

Loop Engineering 要做的事情,是把其中一部分決策和執行流程交給系統自己處理:給一個 Task,Agent 執行,檢查結果,根據結果決定下一步,繼續執行。

Loop 的四步循環:觀察、執行、檢查、調整,加上撐起這個循環的六個工程組件
我後來把它拆成觀察、執行、檢查、調整四步,比較好對照文章裡講的東西。

這裡我覺得有一個很重要的區分:Loop 不是單純重跑。 如果只是每天晚上固定跑一次 script,比較像 scheduler;失敗之後再跑一次,是 retry;批量處理一百份文件,是 batch processing。Loop 比較有意思的地方,是上一輪發生的事情會影響下一輪要做什麼——例如 Agent 修改程式後測試失敗,它不是單純再執行一次相同指令,而是讀取錯誤、判斷原因、修改策略,再試一次。簡單講,我會把 Loop 理解成:結果要經過檢驗,檢驗完的東西要能回頭改變下一輪的決定,這個「結果回到下一輪決策」的部分,是我現在比較想理解的 Loop。

從 Prompt 到 Loop,其實是一路疊上去的
#

這也是我看完 Addy Osmani 的文章後比較有感的一點——雖然 Loop Engineering 這個詞是 Addy Osmani 提出的,但把整件事拆成 Prompt、Context、Harness、Loop 四層疊起來的講法,其實是後來不少文章沿用的框架,不是他自己文章裡的說法。我們可以把這件事情粗略想成幾層:Prompt、Context、Harness、Loop,一層疊一層。Prompt 解決「要模型做什麼」,Context 解決「模型知道什麼」,Harness 把模型放進一個可以真正工作的環境裡——工具、檔案、權限、測試、執行環境,Loop 則是在這個基礎上,讓工作可以持續進行。

從 Prompt 到 Loop 的四層演進
Prompt、Context、Harness、Loop 可以看成逐步增加工程控制能力的幾個層次——Loop Engineering 這個詞是 Addy Osmani 提出的,但四層框架是後來的文章延伸出來的整理。

所以我現在比較不會把 Loop 看成另一個取代 Prompt Engineering 的東西。如果 Harness 本身沒有測試、沒有隔離環境,也沒有權限和停止條件,那麼把它做成 Loop,反而只是讓原本的問題更快出現。這個地方其實很像一般軟體工程——自動化不會自動讓流程變可靠,它只會讓流程更快。

我後來發現,大家講的 Loop 其實不太一樣
#

這是我讀這幾篇文章時最容易混在一起的地方。我後來比較傾向不要把它們看成一層比一層高階,而是不同文章在講 Loop 的不同作用範圍。

Karpathy 分享的 AutoResearch 案例比較像研究型迴圈:Agent 可以自己閱讀研究資料、提出假設、修改程式、跑實驗,再把實驗結果帶回下一輪。這種方式有一個很重要的條件——結果要能量測,像 accuracy、loss、training speed、benchmark score 這些數字可以直接拿來判斷上一輪到底有沒有變好。但如果今天換成「這篇文章寫得好不好?」,問題就完全不一樣了。不是不能做,而是你很難找到一個同樣穩定的客觀指標。所以我現在看研究型迴圈,第一個想到的不是 Agent 有多自主,而是:它到底靠什麼知道自己做得比較好了?

另一種比較常見的是 Agent 自己的行動迴圈。其實很多 Agent 系統裡面本來就有這種東西:理解目標、決定 action、呼叫 tool、取得結果、再決定 action。比如讀 log、找相關程式碼、定位問題、修改、跑測試、測試失敗、分析錯誤、再次修改。這已經不是單純的 Prompt → Response,Agent 開始根據環境回饋決定下一步。但我覺得這還比較像「Agent 裡面的 Loop」。

真正讓我覺得 Loop Engineering 有意思的,是再往外走一層,把整個工程流程接起來:任務、Agent、Git、測試、Evaluation、State、CI、人工審核,全部接在一起。這時候問題已經不只是「Agent 下一步要呼叫哪個 tool」,而變成這個工作現在到底做到哪裡、上一輪為什麼失敗、這次可以直接重試嗎、什麼時候應該停止、什麼情況需要人介入。這也是我現在比較傾向把它稱為工程型迴圈的原因。

Ralph Wiggum:我覺得真正有意思的是「重新開始」
#

談 Loop 很容易講到 Geoffrey Huntley 的 Ralph Wiggum。根據我目前所理解核心做法,是讓 Agent 一輪一輪地工作——完成一輪後結束目前 session,再開新的 session,重新讀取專案現在的狀態。

我一開始覺得這好像只是很簡單的 Bash 迴圈,但後來想了一下,反而覺得「重新開始」這件事情蠻有意思——重點是要給新的 session 一個機會,看得到過去累積下來的東西,而不是每次都從零開始猜。因為它沒有試圖把所有事情都塞在同一個 context 裡。上一輪真正留下來的東西,是程式碼、任務狀態、文件、測試結果,以及其他能被下一輪重新讀取的外部 state——下一輪重新看這些東西,再決定接下來怎麼做。換句話說,真正持續存在的不是上一輪的對話,而是外部 state:Agent 可以失去 context,但不能失去 state。

這讓我開始重新想一件事情:如果 Agent 每次都開新的 context,那 memory 到底應該記什麼?可能不是把所有過去發生的事情都保存下來,而是只留下下一輪真正需要知道的狀態。

那一個 Loop 到底需要什麼
#

下面這些比較像是支撐 Loop 運作的工程組件,不是 Loop 本身的必要元素。Loop 的核心仍然是執行、檢查、回饋,再決定下一步;這些組件則是讓這個循環能在真實環境裡持續運作。看完不同文章後,我沒有找到一個大家完全一致的「Loop architecture」,但幾個東西一直反覆出現。

首先是 automation,也就是怎麼啟動下一輪——可能是手動、scheduler、CI、git event、queue,不一定要全自動,重點是要先定義什麼情況下可以開始下一輪。

再來是 isolation。如果同時跑多個 Agent,就會碰到一個很普通的軟體工程問題:Agent A 修改程式,Agent B 也修改同一個檔案,Agent C 正在跑測試。Git worktree、container、sandbox 這些東西就開始有用了。這部分其實沒什麼神秘的,就是在解決多個執行單元如何安全共存,只是現在執行單元從人變成了 Agent。

然後是 skills / project knowledge。如果每一輪 Agent 都重新摸索 build 怎麼跑、test 怎麼跑、哪些檔案不能碰、專案有哪些奇怪的歷史包袱,效率會很差。像 SKILL.md 這類東西,我覺得有價值的地方不是「再寫一份 Prompt」,而是把原本藏在工程師腦袋裡的規則留下來——以前可能只存在「老工程師都知道不要這樣改」,現在可以變成專案規則、build 流程、coding convention、known issues,下一輪 Agent 重新讀。

再來是 tools / connectors。Agent 如果只能改本機檔案,能做的事情其實有限。真的進到工程環境後,它可能還需要碰 GitHub、Jira、Database、CI/CD、Monitoring、Internal API,MCP 或其他 connector 的價值在這裡就比較容易理解——它讓 Agent 從「幫我寫 code」變成「去查這個 issue,修改程式,跑 CI,再把結果更新回去」,這時候 Agent 才真正開始碰到工程流程。

最後是 memory / state。我覺得這可能是 Ralph 類型 workflow 裡很重要、但很容易被忽略的一部分。下一輪 Agent 至少要知道現在做到哪裡、上一輪做了什麼、哪裡失敗、接下來還剩什麼。這些可以存在 markdown、issue、database 或其他 state store,形式其實不是重點,重要的是 Agent 結束之後,工作不能跟著 context 一起消失。

但我覺得真正重要的是驗證
#

前面那些東西都有了,還是會遇到一個問題:怎麼知道 Agent 沒有越做越偏?

一個簡單的 Loop 可以想成:Agent 執行、取得結果、驗證——過了就繼續,沒過就修正、再試一次。如果沒有中間這個「驗證」,那其實只是 Agent 一直做事情而已。所以我會把品質檢查與風險控制拉得很前面,而且不太傾向第一時間就找另一個 LLM 來評估。如果問題是「code 能不能 build」,直接讓 compiler 告訴你;如果是「test 過不過」,直接跑 test;如果 API response 必須符合 schema,直接做 schema validation——這些都可以確定回答,就不要多繞一層。真的需要判斷比較模糊的品質問題,再考慮 LLM-as-judge;如果再涉及 production、權限、資料刪除這類高風險操作,我還是會把人放進來。

我後來把這個想法畫成一張圖,算是幫自己整理清楚順序——這不是 Loop Engineering 的正式架構,只是讀完這些資料後,把 deterministic checks、LLM evaluation、human approval 拼成的一個品質與風險閘門:

Loop Engineering 三層式品質與風險閘門:確定性檢查、LLM-as-Judge、人工核准
三層品質與風險閘門——前兩層沒過帶著 feedback 回去重修,人工核准沒過則可能是要求修改或直接停止。

Agent 產出變更之後,先經過第一層確定性驗證——compiler / linter 檢查語法和型態、automated tests 跑單元和整合測試、schema validation 檢查格式和結構,這一層通常比 LLM-based 的評估更快、更可預期,也更容易自動化;如果這些檢查已經足以回答問題,就不需要再額外驚動 LLM。過了第一層,才進到第二層比較模糊的語義和品質評估,例如讓另一個 code review agent 看可讀性和潛在漏洞、或檢查是否符合業務邏輯規範,這一層是模糊判斷,成本也比較高。最後一層是人,只留給 production 部署、資料庫變更、高額 API 授權這類真正高風險、一旦出錯就很難收回的操作。三層裡前兩層如果沒通過,可以帶著 feedback 回到 Agent,讓它根據失敗原因重新修正;但到了人工核准,結果就不只是「通過或重試」——可能是核准、要求修改、縮小範圍,甚至直接判斷這個方向本身就不該繼續、直接停止。

這裡有一個區分要拉出來講:驗證跟回饋其實是兩個步驟,不是同一件事。驗證只回答一個問題:這次的結果過不過。它可以是 boolean,也可以是一個分數,但它本身不負責告訴 Agent 該怎麼改。回饋才是下一輪能不能修對方向的關鍵——同樣是「沒過」,回饋只回一句「失敗」,跟回饋附上具體是哪裡失敗、錯誤訊息長什麼樣、上一輪的 state 是什麼、下一步有哪些限制,Agent 能做的事情差很多。驗證決定要不要繼續,回饋決定繼續的時候往哪個方向修——這個區分沒做出來,很容易誤以為只要有驗證關卡,Loop 就會越跑越好,但其實驗證只是擋住爛結果,真正讓下一輪變好的是回饋的品質。

所以我現在會比較傾向這個順序:先用確定性的檢查,不夠再讓 LLM 評估,真正高風險的最後交給人核准。不是每個 Loop 都需要三層,而是能用簡單方法確認的事情,就不要讓系統變複雜。

到底哪些工作值得 Loop
#

這件事情會一直發生嗎? 如果只做一次,花時間建 Loop 可能不划算;如果每天、每週都在做,就開始值得考慮。

有辦法驗證嗎? 這是目前覺得最重要的一點——程式可以測,資料可以驗證,benchmark 可以比較,但如果是「這個策略夠不夠好」,就沒那麼容易。

做錯的代價大嗎? 如果失敗只是多花一點時間,很適合自動重試;如果失敗會刪資料、改權限、部署 production、產生大量成本,那就不能只想著讓 Agent 自己跑。

現在的工程基礎夠嗎? 如果連測試、CI、rollback、permission、isolation 都還沒有,那我不太會急著建 Loop,因為 Loop 不會幫忙做這些事。

Loopmaxxing:一直跑真的會比較好嗎
#

Jason Chuang 提到一個我覺得蠻有意思的詞:loopmaxxing,大概就是讓 Agent 一直跑、跑久一點,總會得到比較好的答案。但如果驗證本身有問題,事情可能剛好相反——錯誤結果帶來錯誤回饋,錯誤回饋導致錯誤決策,決策又產生新的錯誤,然後繼續循環。這時候 Loop 放大的不是能力,而是錯誤,而且同時增加的還有 token、compute、時間,以及可能越來越大的程式碼變更。所以我現在比較在意的不是 Agent 能跑多久,而是什麼時候不准它繼續跑——這也是為什麼停止條件很重要。

還有一個問題:人會不會開始不懂自己的系統
#

Loopmaxxing 講的是機器可能跑過頭,這其實是同一個問題的另一半:機器跑太多之外,還有人理解太少。這可能是 Loop 最容易被忽略的地方。假設 Agent 一晚上修改了幾十個檔案,測試也全部通過,第二天人打開 repository,程式確實能跑,但你真的知道它為什麼這樣寫嗎?這就是我看到 Jason Chuang、bnext 等文章談到「理解債」時比較有感的地方。AI 可以很快地把系統往前推,但人的理解速度沒有一起變快,最後可能變成 Agent 產生的程式碼越來越多、人的理解越來越少,兩者越來越遠。

所以我不太認為 Loop 的價值只是「幫工程師省時間」。比較理想的情況應該是:把自己已經理解、也已經建立好驗證機制的流程交給 Agent 放大,而不是「這東西我也不太懂,讓 Agent 幫我一直跑看看」。這兩種用法,結果可能差很多。

Loop Engineering 跟 Agentic AI,我目前會分開看
#

我現在會把兩者看成不同層次的問題。Agentic AI 比較在問「Agent 能不能自己決定下一步」,重點會落在 reasoning、planning、tool use、autonomy。而 Loop Engineering 讓我想到的是另一組問題:它做完之後呢?結果怎麼驗證?狀態怎麼留下來?失敗怎麼處理?可以重試幾次?什麼時候停止?哪些事情需要人?

所以目前我不太會把 Loop Engineering 當成另一個 Agent framework。Framework 可以換,model 可以換,tool 也可以換,但這些邊界還是要自己決定。

我目前的理解:真正要設計的是「邊界」
#

這篇看到最後,我目前留下來的其實不是某一個 framework,也不是 Ralph Wiggum 的 Bash script,而是一個很簡單的問題:到底哪些事情可以讓 Agent 自己決定?

如果把這件事情拆開,大概就是:Agent 可以自己做什麼、什麼結果需要驗證、什麼失敗可以重試、什麼狀況必須停止、什麼事情需要人核准、哪些狀態必須留下來。這幾個問題如果沒有想清楚,Loop 做得再漂亮也只是把一個不確定的流程自動化。反過來,如果這些邊界先定義好,底下到底用哪個 Agent、哪個 model、哪個 runtime,反而沒有那麼重要。

這也是我目前對 Loop Engineering 最簡單的理解:它不是在研究怎麼讓 Agent 一直工作,而是在設計 Agent 可以自主工作的範圍。

我還沒有把這套東西建起來,所以先彙整相關文獻當作學習。真正有意思的應該是下一步:等 Loop 真的開始改 code、跑 test、碰到 production 那條線的時候,前面講的這些邊界要怎麼落成一套真的能運作的系統。到時候再回來看,理論上的 Loop,跟真的讓 Agent 跑一整晚,是不是同一回事。


參考文獻
#


📬 Newsletter 訂閱功能即將上線