去年十二月,Boris Cherny 在一個月內發送了 259 個 Pull Request。每一個都由 Claude 撰寫。他說他整個月都沒有打開過編輯器。
他的工作不是寫程式碼,而是寫那個會寫程式碼的東西。Peter Steinberger 用兩句話總結了這個概念,這句話已被觀看超過 800 萬次:「你不應該再手動對 coding agent 下提示。你應該設計迴圈來對你的 agent 下提示。」
這就是「迴圈工程」。你建立一個小型系統,讓它自行尋找工作、將任務交給 agent、檢查結果、決定下一步行動,然後讓它在你睡覺時自行運作。
問題在同一個月出現了。某人的迴圈在無人看管的情況下跑了十一天,燒掉了 47,000 美元,才有人發現。所以這其實是兩種技能,而幾乎所有人都只教第一種:建立一個能交付工作的迴圈,以及建立煞車系統,防止它把你推下懸崖。
一個問題決定了你建立的是哪種迴圈:它是收斂於某個真實結果,還是只是一個昂貴的隨機漫步?
1. 一個迴圈由六個部分和一個問題組成
排除所有雜訊後,一個可運作的迴圈包含六個部分。第一次看到這個列表時,它看起來過於簡單。但每個部分的細節,才是決定這個迴圈是能夠穩定運作,還是在一夜之間流失資金的关键。
你不再需要手動建立這些東西。一年前,一個迴圈意味著一堆你必須自己維護、時時監控的 shell 腳本。現在,這些部分已經內建於產品中,同樣的六個部分也對應到 OpenAI Codex 應用程式和 Claude Code。一旦你看懂了,工具就不再是重點,迴圈設計才是核心。
1零件 在迴圈中的角色 CODEX CLAUDE CODE2------------- ------------------------ ------------------------- --------------------------3狀態 在每次執行之間記住資訊 Markdown / Linear (MCP) Markdown / Routines + MCP4自動化 按排程執行 Automations 標籤 + Triage /loop (技能), Routines, /goal5工作樹 隔離並行作業的 agent 每個執行緒一個 Worktree --worktree, isolation: worktree6技能 將你的意圖程式化 ~/.agents/skills/SKILL.md ~/.claude/skills/SKILL.md7連接器 連接你的真實工具 MCP 伺服器 (config.toml) MCP 伺服器 (.mcp.json)8子 agent 將製造者與檢查者分開 .codex/agents/ 中的 TOML .claude/agents/ + agent 團隊
2. 狀態是下一次執行唯一繼承的東西
從最底層開始,因為其他一切都建立在它之上。
當一次執行結束時,模型會遺忘。對話終止,上下文清除,下一次執行醒來時一無所知。聊天中的記憶隨著執行結束而消失。它必須存在於磁碟上。
在實務上,這是一個檔案。存在於儲存庫中的 STATUS.md,或透過連接器存取的 Linear 專案,記錄著已完成的事項、進行中的事項、接下來要做的事,以及迴圈絕對不能碰觸的事項。
1# STATUS.md (迴圈會先讀取這個檔案,最後才寫入它)2## 已完成3- [x] auth: 遷移至 tokens v2,測試通過4## 進行中5- [ ] billing: webhook 重構 (PR #214,CI 紅燈)6## 接下來7- [ ] dashboard: test/charts 中的不穩定測試8## 絕對不能碰9- 未經人工審核,不得修改 infra/
把這個迴圈想像成你從未監看的夜班。你被評斷的標準,不是它在凌晨三點做了什麼,而是早上九點留在你桌上的那張備忘錄。先設計好那張備忘錄,迴圈的大部分設計就會自動成形。
3. 自動化是區分「迴圈」和「只跑過一次的東西」的關鍵
一個迴圈只有在它能自動觸發時,才配得上這個名稱。
在 Codex 應用程式中,你可以在 Automations 標籤 中建立一個迴圈:指定儲存庫、提示詞和執行頻率。找到東西的執行會進入 Triage 收件匣;什麼都沒找到的執行會自行歸檔。OpenAI 將此用於程式碼庫中那些不起眼但至關重要的任務:每日問題分類、CI 失敗摘要、抓出上週偷偷混進來的錯誤。
Claude Code 則透過幾個基本功能來達成,而常見的文章常常搞錯細節,所以值得在此精確說明。/loop 是一個技能,不是內建指令,它會在你的工作階段開啟時,依照設定的頻率重複執行一個提示詞。週期性的雲端任務稱為 Routines,透過 /schedule 設定,最小間隔為一小時,即使關閉筆電也會持續執行。沒有本機的 crontab。
最值得學習的是 /goal。它會一直執行到你設定的條件成立為止,並且在每次執行後,由一個獨立的、較小的模型來檢查你是否真的完成了。撰寫程式碼的 agent 不能為自己的工作評分。
1# Claude Code:持續執行直到真正完成,而不是感覺完成2/goal test/auth 目錄下的所有測試都通過,且 lint 步驟乾淨無誤34# Claude Code:一個週期性的雲端任務(最小間隔一小時)5/schedule 每天早上 9 點進行 PR 分類67# Codex:一個自動化提示詞(在表單中設定頻率)8"工作日早上 9 點:掃描開啟的 PR,標記 CI 失敗或沒有審查者的項目,張貼到 Triage。"
將停止條件當作合約來撰寫。「test/auth 目錄下的所有測試都通過」是一份合約。「讓它變得更好」則是讓迴圈一路跑到發薪日的藉口。
4. 工作樹讓並行 agent 不會互相干擾
當你同時執行一個以上的 agent 時,失敗模式就改變了。問題不再出在模型本身,而是兩個 agent 同時寫入同一個檔案,就像兩個工程師在無人溝通的情況下,同時修改同一行程式碼。
Git 工作樹就是它們之間的圍牆:一個獨立的、位於自己分支上的工作目錄,但共用儲存庫的歷史記錄。這樣一來,一個 agent 的編輯就不會影響到另一個 agent 的檢出目錄。
1# Claude Code:每個 agent 都有獨立的檢出目錄2claude --worktree feature-auth34# 或在子 agent 的 .claude/agents/<名稱>.md 前置設定中:5# isolation: worktree67# Codex:開啟執行緒時選擇「Worktree」(每個執行緒都是一個分離的 HEAD)
有一個工具不會提到的注意事項。工作樹解決了衝突問題,但沒有解決瓶頸。你仍然是那個瓶頸。無論你啟動多少個 agent,你自己的審查頻寬決定了你能信任多少個。
5. 技能是你的意圖,一次性寫下,並存在外部
每次啟動時,agent 都是一片空白,並會用自信的猜測來填補你意圖中的任何空白。技能就是將這些意圖寫下來,讓模型每次都能讀取,從而停止猜測。
兩種工具的格式相同:一個包含 SKILL.md(內含指令和描述)以及任何所需腳本的資料夾。當你透過名稱呼叫它,或當你的任務與其描述相符時,它就會被觸發。這正是為什麼一個直接、字面上的描述,勝過一個花俏的描述。
1# .claude/skills/triage/SKILL.md (Codex: ~/.agents/skills/triage/SKILL.md)2---3name: triage4description: 讀取昨天的 CI 失敗、開啟的問題和最近的提交;5 將每個發現寫入 STATUS.md 作為一個任務。6---71. 提取失敗的 CI 並按根本原因分組。82. 將每個失敗與導致它的開啟問題或提交進行比對。93. 每個真正的發現寫入一個 STATUS.md 任務。忽略雜訊。
沒有技能,每個週期都要從頭學習你的專案。有了技能,迴圈每天早晨都會變得更精準一些。
6. 連接器讓迴圈能夠實際行動,而不只是空談
一個只能看到檔案系統的迴圈只是個玩具。連接器建立在共通的 MCP 標準之上,讓 agent 能夠讀取你的問題追蹤器、呼叫測試環境的 API、查詢資料庫、或張貼訊息到頻道。
1# Claude Code2claude mcp add --transport http linear https://mcp.linear.app/mcp34# Codex5codex mcp add linear --url https://mcp.linear.app/mcp
這就是「說『這是修正方法』的 agent」與「能夠自行開啟 Pull Request、關聯工單、並回報綠色狀態的迴圈」之間的差別。由於兩種工具都支援 MCP,你為一個工具設定的連接器通常也能直接用在另一個工具上。
7. 子 agent 讓製造者與檢查者分開
在任何迴圈中,最高價值的操作就是將負責撰寫的 agent 與負責檢查的 agent 分開。
一個模型審查自己的工作時,永遠會給自己通過。而第二個 agent,使用不同的指令,理想情況下使用不同的模型,就能抓到第一個 agent 說服自己接受的錯誤。
1# Codex: .codex/agents/reviewer.toml2name = "reviewer"3description = "對抗式 PR 審查者:檢查正確性、安全性、遺漏的測試。"4developer_instructions = "以擁有者的心態進行審查。假設作者是錯的,直到 diff 證明他沒錯。"5model_reasoning_effort = "high"67# Claude Code: .claude/agents/reviewer.md 前置設定8# name: reviewer9# description: 對抗式審查者。在任何程式碼變更後使用。10# model: opus
一個負責探索,一個負責實作,一個負責根據規格驗證。這正是 /goal 在底層做的事情:由一個全新的模型來判定工作是否完成。第二意見會消耗 tokens,因為每個 agent 都運行自己的模型和工具,所以在錯誤成本高昂的地方,才該使用第二意見。
8. 一個迴圈的實際樣貌
將這六個部分組合起來,一個單一的執行緒就變成了一台小型機器。
一個排程好的自動化腳本每天早上在儲存庫上執行。它會呼叫你的分類技能,讀取昨晚的 CI 失敗、開啟的問題和最近的提交,並將每個真實的發現寫入 STATUS.md。對於每個值得處理的發現,迴圈會開啟一個隔離的工作樹,將一個子 agent 派去草擬修正方案,再派第二個 agent 根據你的技能和測試來審查它。連接器會開啟 PR 並更新工單。任何它無法處理的事情會留在你的 Triage 收件匣中。STATUS.md 會記住哪些完成了、哪些還在進行中,因此明天可以從今天結束的地方開始。
你早上醒來看到的是一份簡短的交接報告,而不是一堵記錄牆:
1# 9:00am — 迴圈的夜間交接報告(你的 Triage 收件匣)2準備合併3 PR #218 修正 test/charts 中的不穩定測試 CI 通過4 PR #219 在收到 429 狀態碼時重試 webhook,加入退避測試 CI 通過5需要你處理6 auth/session.ts 有兩種安全的方法可以修正;我兩種都沒選,請你決定7安靜無事8 7 個排程執行什麼都沒找到,已自行歸檔
你只設計了一次。你完全沒有手動下提示。
9. 在你離開前,先裝好煞車
這是沒有人教的那一半,而它決定了你的迴圈是資產還是負債。
那筆 47,000 美元的帳單,並不是聰明的模型失控了。它是兩個 agent——一個分析者與一個驗證者——彼此有禮貌地要求更多工作,但沒有步驟限制、沒有預算上限、也沒有停止條件。它跑了十一天。任何一個限制就能在第一天終止它。
在增加馬力之前,先裝好煞車。 在裝好煞車踏板之前,不要讓引擎上路。
1# 在你離開之前,先把這些裝上去:2- 步驟上限: --max-turns 50 (強制停止,沒有例外)3- 預算上限: claude -p --max-budget-usd 10 (列印模式;每個階段)4- 事故範圍: 一個工作樹,一個分支,src/ 目錄外唯讀5- 斷路器: 連續三次執行相同的工具+相同的參數 = 停止6- 生死狀態檢查: 每次執行時將心跳寫入 STATUS.md;無回應則發送警報給你
根據一個迴圈能夠摧毀什麼來界定它的範圍,而不是根據你想讓它做什麼:哪些儲存庫、哪些分支、多少美元、在強制退出前允許多少步驟。先選擇事故範圍,再選擇任務。
並且要誠實地計算成本。Steinberger 那個一百個 agent 的艦隊是真實存在的,每月運行成本約 130 萬美元。它能運作,是因為 OpenAI 現在僱用了他並支付帳單。前沿案例是有贊助的。你的不是。 在每月 20 到 200 美元的方案下,能讓你獲益的迴圈是小型、有上限、且針對一個無聊任務的,而不是一個 swarm。
1成本分佈(全部真實,全部來自過去六個月)2-----------------------------------------------------------------330 天內 259 個 PR 一位工程師,100% 由 Claude 撰寫411 天內 47,000 美元 一個沒有上限、無人監看的失控迴圈5每月約 130 萬美元 一個 100 個 agent 的艦隊(帳單有贊助)6-----------------------------------------------------------------7相同的技術。差異在於煞車。
10. 迴圈如何死亡
每個失敗的迴圈都死於四種死因之一。現在就學會它們的名字,這樣你才能在凌晨三點發現它們。
失控的遞迴。 兩個 agent 無止盡地餵養彼此。解法就是上面提到的步驟上限和預算上限,沒有更聰明的方法。
無聲的死亡。 某個開發者的夜間執行遇到了完整的上下文視窗而停止,然後不斷嘗試從同一個障礙處恢復,同時表面上還顯示為活躍狀態。你的迴圈可能已經死了好幾個小時,卻仍在回報進度。 解法是使用心跳機制,並為每個階段建立新的上下文,而不是一個無止盡的執行。
隨機漫步。 如果沒有可驗證的停止條件,迴圈會偏離目標,而不是朝著目標前進。一個通過的測試套件是一個它可以達到的固定點。「看起來完成了」則不是。
理解債務。 迴圈越快交付不是你寫的程式碼,你的儲存庫在做什麼與你實際理解之間的鴻溝就越大。讓它在你未閱讀的情況下運行太久,你就會從工程師變成一個橡皮圖章。解法是一個人工審查的關卡,迴圈永遠不允許跳過它。
11. 建立迴圈。保持工程師的身份。
兩個人可以建立完全相同的迴圈,並得到相反的結果。一個人用它來加速處理自己瞭若指掌的工作。另一個人用它來完全停止理解工作。迴圈無法區分他們。但你可以。
Cherny 的重點從來不是工作變簡單了。而是槓桿點轉移了:從提示詞轉移到迴圈,從打字轉移到判斷。這是一個比下提示更難的工作,而不是更輕鬆。
所以,這就是接下來的行動,而且刻意很小,因為現在還很早,而且成本波動劇烈。明天早上,找出你仍然手動處理的最無聊工作——分類 CI、關閉過期的問題、追查一個不穩定的測試——然後用一個有上限的迴圈把它包起來。煞車優先。迴圈要夠小,讓你仍然能閱讀它交付的每一個 diff。
那些每個月交付 200 個 Pull Request 的人,沒有一個是從一百個 agent 開始的。他們從一個自己信任的迴圈開始,並且在整個過程中始終保持工程師的身份。建立那一個迴圈吧。





