我決定把這篇文章獻給如何打造一個可程式化的 Agent,讓它為你完成工作,這樣你就不必每天早上打開電腦,反覆對它下達指令。
它會自己醒來,自己尋找任務,自己發現問題,並將結果儲存並呈現在你的桌上,供你審閱。
前言
Loop 的想法並非憑空出現——在 2026 年 6 月的同一週內,三位業界專家幾乎同時表達了同樣的想法:是時候開始開發這個層級了。
一週後,吳恩達(Andrew Ng)將這個對話置於「從 0 到 1 打造產品」的更廣泛脈絡中,提供了更全面的圖景。
這篇文章從那個故事開始,然後引導你從頭開始建立一個最小但完整的 Loop:5 個動作、6 個部分、一扇說「不」的門,以及一扇人類的門——全部在你自己的機器上運行,並且可以在任何軟體專案中重複使用。

來源:華數橙書,Loop 工程:別再問我它是什麼(v260615,2026 年 6 月)
那一週,3 個人點燃了引信
2026 年 6 月: 三個人,彼此之間沒有任何協調,卻在幾天內說了幾乎相同的話。
Peter Steinberger,OpenClaw 的創作者,在 X 上發了兩句話,獲得了 890 萬次觀看:
https://x.com/steipete/status/2063697162748260627
那篇貼文才是這場討論真正的起點。它不是一篇宣言或長文,只是兩行字,為人們已經在默默做的事情命名。
Boris Cherny:我已經不再對 Claude 下提示了,我有正在運行的 Loop。是它們在對 Claude 下提示並決定要做什麼。
Addy Osmani:Loop 工程就是用來取代你作為對 Agent 下提示的那個人。你設計的是執行這個動作的系統。
實務操作比這個名稱早了好幾個月,每個人都在寫 Loop,只是還沒有人給它一個名字。
所以,Loop 現在是我們讓 AI Agent 能夠長期迭代工作以創建軟體的關鍵部分。

吳恩達(Andrew Ng) 根據時間尺度,從最內層到最外層排列了三個 Loop:最內層的 Loop 最快,最外層的 Loop 最慢。此外,最外層 Loop 的輸入來自最內層 Loop 的輸出:
Loop
誰在運行它
週期長度
它輸出到外層的內容
Agent 編碼 Loop
Agent 本身
秒 - 分鐘
一個可運行的版本
開發者回饋 Loop
人類 + Agent
數十分鐘 - 數小時
更清晰的產品願景和規格
外部回饋 Loop
使用者 + 團隊
數小時 - 數週
驅動願景演進的真實數據
吳恩達按時間給了我們地圖:三個以不同速度運行的 Loop。Addy Osmani 則按抽象層級繪製了第二張地圖:提示 -> 上下文 -> 工具框架 -> Loop。

Loop 工程位於頂層,並增加了工具框架所沒有的三個動詞。它按計時器運行、產生輔助程式,並且自我餵養——今天的輸出成為明天的輸入。最後這一點使它成為一個 Loop,而不是將同一個任務執行 N 次。
最重要的直覺: 同一個錯誤在每個層級的成本都不同:
層級
它關心什麼
核心問題
提示工程
撰寫提示
要對模型說什麼
上下文工程
視窗中載入了什麼
要提取、總結、清除什麼
工具框架工程
裝備一次運行
哪些工具、哪些動作、怎樣才算完成
Loop 工程
在工具框架之上進行排程
如何讓它自己運行,一輪接一輪
Loop 的設計本質上就是一台讓「輪次數量」變大的機器。從這裡開始的每一個決定——評估器、人類關卡、Token 上限、狀態檔案——都是為了縮短從「錯誤發生」到「有人看到它」之間的距離。
一輪內部發生了什麼:
「Loop」常被誤解為「原地打轉」。它不是,每一輪都有 5 個具體的動作。刪掉任何一個,Loop 要嘛無法運行——要嘛運行了卻毫無進展。

- 驗證是那個說 「不」 的動作。
- 排程是將這一輪餵養到下一輪的動作。
這正是讓它成為一個 Loop 的部分。
對應到我們即將建立的專案: 一個針對小團隊的晨間分類 Loop:
動作
它的作用
在分類 LOOP 中
發現
弄清楚這一輪該做什麼
一個技能讀取 CI / 議題 / 最近的提交
交接
分派任務,並將其隔離
每個發現都獲得自己的工作目錄
驗證
換另一個 Agent 來說不
第二個子 Agent 作為審查者,檢查測試和技能
持久化
將狀態寫入對話之外
PR + Linear 工單 + ./state/triage.md
排程
讓它一輪接一輪地運行
GitHub Actions 的 cron 在 06:00 觸發
下面 5 堂課,每一堂都專注於一個動作。
五堂課 = 一個完整的 Loop。
我們從第一個開始:發現,因為如果 Loop 無法決定今天什麼值得做,之後的一切都無關緊要。
第 1 課 發現:撰寫一個晨間分類 SKILL.md
技能,而不是一堵提示牆。
想像一下,週一早上 6 點,你的筆記型電腦是闔上的,GitHub Action 醒來並啟動 claude --skill morning-triage:它讀取什麼、它判斷什麼是可操作的、它把結果寫在哪裡——所有這些都存在於你即將撰寫的 SKILL.md 中。
Osmani 的關鍵一句話: 自動化應該觸發一個技能——寫下來的、可更新的專案知識,而不是貼到 cron 任務裡的一堵提示牆。貼上去的提示只會在那裡腐爛,因為沒有人會回去更新埋在排程裡面的東西。
你這堂課的任務: 在 .claude/skills/morning-triage/SKILL.md 撰寫一個技能,讓它自己讀取三個來源(CI / 議題 / 提交),自己決定什麼值得做,將結果寫入 ./state/triage.md——並且有一個明確的「停止」部分,說明 Loop 不允許做什麼。
這是起手式——改三樣東西就是你的了:
1# .claude/skills/morning-triage/SKILL.md2---3name: morning-triage4trigger: invoked by daily automation5---67## 讀取(發現的輸入——換成你的儲存庫實際擁有的來源)8- 自上次運行以來失敗的 CI 運行 # gh run list --status failure9- 過去 24 小時內開啟的議題 # gh issue list --search "created:>=…"10- 自昨天以來合併的提交 # git log --since=yesterday11- 上一次的 ./state/triage.md # 「昨天 → 今天」的交接1213## 判斷(天花板——讓 Loop 自己選,不要給它清單)14對於每個候選項目,決定:15- 它現在是可操作的,還是雜訊?16- 它是否阻礙了發布?→ 優先級 = P017- 它是否已經被追蹤?→ 跳過18只保留今天值得建立工作目錄的項目。1920## 寫入(持久化——落地到 Markdown,而不是對話)21附加到 ./state/triage.md:22| 發現 | 來源 | 優先級 | 狀態 |23提交檔案,以便明天可以讀取。2425## 交接(為第 2 課做準備)26對於每個保留的發現,輸出一行任務:27 worktree=fix/<slug>28 goal=<停止條件>2930## 停止(唯一非模板的部分——這裡要仔細思考)31絕不合併。絕不刪除。32任何你不太確定的東西 → 放到 ./inbox/ 給人類處理。33不是 PR。
這裡有三個部分真正發揮作用:
讀取: 這是發現的輸入——列出具體的來源,精確到實際的指令。記住,「讀取上下文」不是一個來源,但 gh run list --status failure 是一個來源。
判斷: 這是整個 Loop 的天花板。Loop 自己決定「可操作 vs 雜訊」——它不會從你那裡收到清單,因為如果你每天早上還在給它清單,那你只是自動化了「執行」,而不是「選擇」。而選擇通常才是成本更高的步驟。無論你的來源有多好,如果這個部分選了垃圾,其他四個動作就是在無價值的工作上空轉。
停止: 這個檔案中唯一不是模板的部分。Loop 會做技能說的一切,而且只會做技能說的事。如果你不寫「絕不合併」——總有一天它會為你合併。
明確畫出紅線:絕不合併,絕不刪除,絕不推送到主分支,任何不確定的東西都放到 ./inbox/ 給人類處理,而不是放進 PR。
還有一件事值得知道: 同樣的技能結構也適用於晨間分類之外:將「讀取」部分換成「昨天的存取日誌 + 新議題 + 當前部署版本」,它就變成了一個夜間網站健康檢查 Loop。在「判斷」部分加一行——「這是否相較於昨天出現了回歸?」——它就增加了跨日比較的能力。
這堂課要預防的疾病——盲目 Loop:
最常見的「看起來像 Loop,但其實不是」的情況:Loop 在運行,但你每天早上仍然在指派工作(「嘿,看看這三個錯誤」)。那是執行的自動化,而不是發現的自動化。
症狀: Loop 從不讓你感到驚訝,因為它只會做你已經知道需要做的事情。
修復: 把「判斷」放進技能裡,讓它自己選擇今天的工作。
在繼續之前,回答這三個問題:
1/ 你的「停止」部分有幾行?
如果只是「絕不合併」——再加一行:這個 Loop 還不應該為你做什麼?(絕不關閉議題 / 絕不推送到主分支 / 絕不同時處理超過 3 個發現……)
2/ 將「讀取」的第一行改寫成一個在你的專案中實際運行的指令
3/ 如果這個技能一年不變——會發生什麼事?
**現在比較一下:貼在 cron 任務裡的一堵提示牆放一年會發生什麼事?
第 2 課 交接:分配工作,並將其隔離
第 1 課的技能剛剛執行完畢。./state/triage.md 現在包含了 5 個可操作的發現。最自然的下一步想法——同時啟動 5 個 Agent,加快速度。而這正是你養出一個糾結 Loop 的步驟:好幾個 Agent 在同一個目錄下編輯同一個檔案,合併日變成了考古日。
解藥只有一行: 每個發現都獲得自己的工作目錄。
git worktree 是 git 內建的機制:一個儲存庫,多個獨立的工作目錄,每個都簽出到自己的分支。git worktree add ../fix-auth fix/auth 在 ../fix-auth 開啟一個完全隔離的工作空間。建置、編輯、測試——都不會影響到其他人。一個發現一個工作目錄 = Agent 之間物理隔離。
你這堂課的任務: 撰寫一個腳本,讀取 ./state/triage.md 中的每個發現,為每個發現開啟一個隔離的工作目錄(命名為 fix/<slug>),發送一個 Agent 在裡面起草修復方案——並設定一個並行上限,以免它無限產生。
1# 讀取 state/triage.md,每個發現一個工作目錄2# 修改:MAX_PARALLEL 為你的機器 / 帳單可以處理的數量3MAX_PARALLEL=345# 修改:解析方式以符合你實際的 triage.md 欄位6findings=$(awk -F'|' 'NR>2 && $5 ~ /open/ {print $2}' \7 state/triage.md | head -n $MAX_PARALLEL)89for finding in $findings; do10 slug=$(echo "$finding" | tr ' ' '-' | tr -cd '[:alnum:]-')1112 # 關鍵行:每個 Agent 的物理隔離13 git worktree add ../wt-$slug -b fix/$slug1415 # 修改:goal 是停止條件,第 3 課的評估器會讀取它16 claude --worktree ../wt-$slug \17 --goal "tests in tests/$slug pass and lint is clean" \18 "draft a fix for: $finding" &19done2021wait # 等待所有並行 Agent 完成2223# 關閉規則:Agent 絕不自動合併——工作目錄等待24# 第 5 課的人類關卡25echo "所有工作目錄已準備好審查:"26git worktree list
這裡重要的規則: 絕不在主分支上工作。
主分支是人類審查的著陸跑道——不是 Agent 的工作桌。所有 Agent 都活在 fix/* 的工作目錄上。
限制並行度: 無限制地產生是通往 Token 爆炸的大門(第 5 課會回到這個問題)。根據一個誠實的問題來選擇 MAX_PARALLEL:不是「我的機器能跑多少」,而是「我實際上能審查多少個 PR」。
合併是人類的決定: Stripe 每週透過這樣的 Loop 處理超過 1,000 個 PR,而且人類仍然審查每一個。人類並沒有離開這個流程——他們換了工作桌:從撰寫程式碼變成了審查程式碼。
還有一個值得借鏡的 Stripe 案例細節:他們反直覺地使用了較小的模型,搭配嚴格的確定性關卡,而不是使用可用的最大模型。
這堂課的教訓: 一個嚴格的驗證關卡,在 Loop 工作中勝過原始模型能力。
這堂課要預防的疾病——糾結 Loop:
單一 Agent 的 Loop 看起來完全健康。問題只會在你開始並行的那一天出現——五個 Agent 運行,五個差異在同一個檔案中碰撞,合併就是一場混亂。
修復: 每個任務都獲得自己的工作目錄,絕不讓 Agent 之間共享工作目錄。
在繼續之前,回答這三個問題:
1/ 你把 MAX_PARALLEL 設成了多少——為什麼?
**(錢?機器?還是「我誠實地能審查多少個 PR」?)
2/ 如果一個工作目錄崩潰了——Agent 退出而沒有觸及任何東西
**明天的狀態檔案應該記錄關於它的什麼?
3/ Stripe 使用了較小的模型 + 嚴格的確定性關卡
**而不是最大的模型,這個選擇對你的 Loop 意味著什麼?
第 3 課 驗證:安裝一扇說「不」的門(最重的一課)
這是 Loop 工程中最難的動作,它值得比其他任何一課投入更多心力。
Anthropic 的工程師 Prithvi Rajasekaran,在處理長期運行的 Agent 應用程式時,注意到一件事:要求一個 Agent 給它剛寫的程式碼評分,它幾乎總是會稱讚自己——即使人類一眼就能看出它很平庸。
這不是模型笨:給自己的作業打分在結構上就是有問題的。 當程式碼完成時,Agent 的上下文已經塞滿了它為什麼這樣寫的自我辯護鏈。看著自己的輸出,它看到的不是結果——它看到的是為結果辯護的論證。
把這個放進 Loop 裡,它會放大成一場災難: 每一輪的「這個夠好了嗎?」都是由剛剛寫下它的 Agent 來回答。每一輪都在對自己點頭。運行得越久,它離真正的品質就越遠。這就是點頭 Loop——而且它是這份清單上最昂貴的疾病。
Rajasekaran 的解決方案,用他自己的話說:
「調整一個獨立的評估器使其保持懷疑,遠比讓一個生成器對自己的工作保持批判要容易處理得多。」
這是一個結構性問題,而不是措辭問題。你無法要求一個作者跳出自己的腦袋,但你可以引入一個不同的 Agent,帶著完全不同的指令,從零開始審視程式碼——沒有附加任何自我辯護鏈。
這個類比來自 GAN:一個網路建構,另一個攻擊:製造者和檢查者。同樣古老的銀行規則:匯款的人和批准匯款的人必須是不同的人。
你這堂課的任務——撰寫兩樣東西:
1) 一個評估器系統提示,位於 .claude/agents/reviewer.md,包含五個部分:角色 + 假設 + 檢查 + 使用 + 裁決。
2) 一個 /goal 指令,宣告這個 Loop 的停止條件——由一個獨立的新模型來判斷,而不是由生成器判斷。
1# .claude/agents/reviewer.md(修改 3 樣東西)2角色:對抗性程式碼審查者。3假設:這段程式碼在證明其無誤之前是 BROKEN 的。4不要讚美。找出失敗的地方。56# 修改:按你的專案真實的失敗模式來排序「檢查」,7# 可運行的檢查優先8檢查,按順序:9 1. 它能運行嗎?(執行,不要讀取)10 2. 測試:執行它們,貼上真實輸出。11 3. 作者跳過的邊界情況。12 4. 行為是否符合工單?1314# 修改:使用哪個 MCP 取決於你在測試什麼——15# 前端 → Playwright,API → curl/httpie16使用 Playwright MCP:開啟頁面,點擊,17截圖,檢查 DOM。18判斷行為,而不是意圖。1920裁決:僅當每個檢查都成立時才 PASS。21 否則 REJECT + 列出每個原因。
1# 停止條件——由一個新的小模型判斷,而不是生成器2# 修改:換成你的發現的真實可驗證條件3/goal all tests in test/auth pass and the lint step is clean45# 注意:/goal 和 /loop 不是同一回事6# /loop = 按間隔重新運行(沒有停止判斷——危險)7# /goal = 運行直到一個新模型判斷條件為真
兩個 Agent,最好是兩個模型: 「同一個模型,不同的提示」通常會保留相同的盲點。如果可以,也換掉模型。
預設懷疑: 評估器的基線是「假設有問題」——信任必須通過檢查來贏得,而不是預設授予。
判斷行為,而不是意圖: 「這個 JSX 看起來不錯」和「我點擊了按鈕,頁面導航了,這是截圖」是兩個不同的世界。評估器必須行動——執行測試,點擊頁面,而不是讀取程式碼並憑感覺判斷。
附帶理由地拒絕: 一個沒有列出理由的 REJECT 不是拒絕——生成器不知道該修復什麼。
還有終極測試: 你的評估器在過去 5 輪以上是否真的拒絕過什麼?一個在數百輪中從未說過一次「不」的 Loop,在任何真實工作負載上統計上都是不可能的。所以這證明了評估器沒有在運作。
這堂課要預防的疾病——點頭 Loop:
Loop 運行,Agent 撰寫程式碼,同一個 Agent 說「看起來不錯。」每一輪都自我批准,以機器速度堆疊看似合理的錯誤。修復:這整堂課:結構性分離 + 預設懷疑 + 透過行動判斷 + 第三方停止條件。
在繼續之前,回答這三個問題:
1/ 你的評估器是同一個模型配上不同的提示,還是一個不同的模型?為什麼?
2/ 將「判斷行為,而不是意圖」轉化為你的專案中
具體的一句話:「我的評估器不讀取程式碼,它執行
_____,並且只有在看到 _____ 時才 PASS」
3/ 一個「差不多夠好」的新模型有多大可能錯誤地 PASS 你的 /goal 條件?
如果你最可怕的失敗模式是 X——立即在你的停止條件中為 X 添加一個檢查
第 4 課 持久化:讓今天的工作存活到明天
第 3 課結束了。你的評估器判斷了三個發現——兩個 PASS,一個 REJECT。問題:這三個裁決現在存在哪裡?
如果答案是「在上下文視窗裡」——那麼明天早上 6 點,Loop 醒來時會發現上下文已被清空,什麼都不記得了。它會從頭開始重新分類,被昨天未修復的 REJECT 絆倒,可能又派另一個 Agent 去修復它,可能完全錯過它,可能掉進同一個坑裡。
這就是失憶 Loop——每一天都從同一個起點開始。
解藥只有一行: 記憶是寫入磁碟的狀態,而不是上下文。一個 Markdown 檔案、一個 Linear 看板、一個資料庫——一旦被寫下來,Agent 忘記得多徹底都無關緊要。
這兩者經常被混淆,所以釐清差異:
上下文 = Agent 在這一輪看到的視窗 -> 每次重新整理時清除。
記憶 = 跨輪次和天數存活的狀態 -> 寫入磁碟(Markdown / 資料庫 / 看板)。
一個 Loop 僅透過記憶來橋接今天 -> 明天。
你這堂課的任務:
- 建立 ./state/triage.md,至少包含 4 個欄位(發現 / 來源 / 優先級 / 狀態)——第 1 課的技能寫入它,第 2 課的工作目錄讀取它。
- 連接一個連接器(MCP):PASS 裁決自動開啟一個 PR,REJECT 裁決自動更新工單。
- 驗證明天的 Loop 確實可以讀回今天的狀態。
1# ./state/triage.md(Loop 的記憶——根據需要修改)23| 發現 | 來源 | 優先級 | 狀態 |4|-----------------|--------------|----------|------------|5| auth test flaky | CI #4821 | P0 | 修復中 |6| null deref | issue 92 | P1 | PR 已開啟 |7| stale dep | commit a3f9c | P2 | 待處理 |89# 根據需要擴展欄位:last_seen, retry_count, assigned_to10# 這個檔案必須提交到儲存庫——11# 否則明天的雲端運行器無法看到它
1// .mcp/connectors.json — 將 Loop 連接到外部世界2{3 "github_pr": {4 "type": "mcp",5 "on_event": "evaluator.verdict.PASS",6 "action": "open_pr",7 "branch": "fix/${slug}",8 "auto_merge": false // ← 必須為 false。人類關卡 = 第 5 課9 },10 "linear": {11 "type": "mcp",12 "on_event": "evaluator.verdict.REJECT",13 "action": "update_ticket",14 "fields": { "status": "Blocked", "reason": "${verdict.reasons}" }15 }16}
為什麼每個欄位都很重要: 沒有來源 -> 你無法審計發現來自哪裡。沒有優先級 -> 你無法安排工作順序。沒有狀態 -> 明天無法接續工作。
而這堂課的驗證是你唯一無法偽造的:等到明天。 醒來,檢查——待處理項目還在嗎?未完成的發現是否仍保留其狀態?早上 6 點的運行是否從昨天停止的地方繼續,而不是重新開始?這一個你需要透過運行來發現,而不是透過推理。
伴隨持久化而來的一個安靜紀律——每天讀取一個樣本。
一旦持久化生效,一個陷阱就打開了:Loop 快速產出 PR,你感覺很有生產力——而你對程式碼庫的心理模型卻在不知不覺中過時了。規則:不要讀取所有東西(那會違背 Loop 的目的),但每天讀取一個樣本 PR,並強迫自己解釋 Loop 改變了什麼以及為什麼。
當你無法解釋它的那一刻——你的心理模型已經落後了。在一個平靜的早晨修復它需要十分鐘。在生產事故期間修復它,成本要高得多。
這堂課要預防的疾病——失憶 Loop:
Loop 找到了好的工作,完成了它,然後忘記了自己做過——因為結果只存在於一個被清空的上下文裡。下一輪它會重新發現同樣的工作,或者更糟——重做一遍並覆蓋掉第一次的嘗試。
症狀: 沒有累積的進展,每一天都從同一個地方開始。修復: 磁碟上的狀態檔案。
在繼續之前,回答這三個問題:
1/ 將「記憶 ≠ 上下文」轉化為一句具體的話
來自你自己的專案:「我的 _____ 是記憶,我的 _____ 是上下文」
2/ 明天的 Loop 醒來——它會先讀取 state.md 的哪個欄位
來決定它的第一步?你把那個欄位命名對了嗎,還是你只是為它埋下了一個地雷?
3/ 紀律:你會在一天中的什麼時間讀取你的那一個
**樣本 PR?現在就設定日曆提醒——這是與你自己的約定。
第 5 課 排程:讓它成真,讓它安全,保留一扇門
第 1 到 4 課已經安裝好了,但 Loop 仍然會在你停止按下按鈕的那一刻停止。最後一個動作是一個動詞:把它掛在一個觸發器上。
但這堂課最危險的部分不是把 cron 設錯。而是把 cron 設對——因為那時 Loop 才真正獨自運行,一個錯誤就可能讓它整晚空轉,輔助程式產生輔助程式,直到你醒來看到一張你認不出來的帳單。
所以這堂課實際上做了三件事:掛上觸發器,設定上限,保留一扇人類的門。
首先——選擇你的排程器:
1雲端(GH Actions) 桌面排程 /loop(在 CC 中)2運行位置 雲端 你的機器 你的機器3需要機器開機? 不需要 需要 需要4需要會話開啟? 不需要 不需要 需要5最小間隔 1 小時 1 分鐘 1 分鐘6能看到本地檔案? 否 是 是
決定性的問題:這項工作能離開你的筆記型電腦嗎?
1「每分鐘檢查我的本地開發伺服器」2 → 必須是本地 + /loop(雲端 1 小時的間隔無法觸及它)34「在凌晨 3 點掃描 GitHub 議題並開啟 PR」5 → 必須是雲端(你的筆記型電腦是關機的——Loop 不能6 等待它)
還有整個實踐中最狡猾的自我欺騙:把本地計時器當作「在你睡覺時運行」。它不是。它是「在我還在的時候多跑幾輪。」
翻譯後的文字(僅繁體中文,無解釋):
你在此課程中的任務:
- 建立
.github/workflows/triage.yml,並設定一個 cron 觸發器來執行 morning-triage 技能。 - 設定三個上限:每次執行的預算、每日預算、以及最大重試次數。
- 在工作流程的結尾加入規則:PR 永不自動合併,任何不確定的內容都歸入
./inbox/。
1# .github/workflows/triage.yml (修改 3 個地方)2name: morning-triage34on:5 schedule:6 - cron: '0 6 * * *' # 修改:你所在時區的 UTC 06:0078jobs:9 triage:10 runs-on: ubuntu-latest11 timeout-minutes: 45 # ← 每次執行上限 · 修改12 permissions:13 contents: write14 pull-requests: write15 steps:16 - uses: actions/checkout@v41718 - name: morning triage19 env:20 ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}21 DAILY_BUDGET_USD: '20' # ← 每日上限 · 修改22 MAX_RETRIES: '3' # ← 重試次數上限 · 修改23 run: |24 claude --skill morning-triage \25 --max-retries "$MAX_RETRIES" \26 --daily-budget-usd "$DAILY_BUDGET_USD"2728 - name: 開啟 PR(永不自動合併)29 run: |30 # PR 會自動開啟。合併權限保留給人類。31 gh pr create --draft --base main \32 --title "[loop] $(date +%F) triage" \33 --body-file ./state/triage.md34 # 這裡刻意沒有 `gh pr merge` 指令3536 - name: 將不確定的內容歸入 inbox37 run: |38 ls ./inbox/ && echo "有待人工審查的項目"
讓你的迴圈在六個月後依然活躍的三條規則:
先設上限,再上線: 三個層級——每次執行超時、每日預算、最大重試次數——必須在第一次自主運行之前設定好,而不是在看到第一張嚇人的帳單之後。Token 上限不是為了省錢。它是一個斷路器,能把開放的風險轉變為可控的風險。一個沒有上限的迴圈,等於把它的花費權限外包給了自己的 bug。
舉例來說:Uber 在四個月內燒光了 AI 預算後,將每位工程師每個工具每月的花費上限設為 1,500 美元。你的每次迴圈上限,就是這個教訓的細化版本。
保留一扇門: PR 永不自動合併。不確定的項目會歸入 inbox。你每天會抽樣閱讀一個。這扇門的存在,不是因為人類一定會走進去,而是因為這扇門存在,讓你保有可以走進去的可能性。 把每扇門都焊死,等到你真的需要進去的那一天,你就會發現鑰匙已經不見了。
確認它真的會醒來。 至少讓它運行 3 次(試運行也算)。最常見的失敗模式是:展示日當天表現亮眼,星期四就掛掉了。「最後一次運行就是展示那天」是「手動迴圈」的診斷標誌。
在 Claude Code 之外也適用—— 這些功能並非綁定特定廠商,只是名稱不同:
1功能 Claude Code Codex2排程 /loop · worker Automations 分頁3條件式運行 /goal 自動化重新執行 + 評判4並行隔離 --worktree 背景 worktree5子 Agent .claude/agents/ .codex/agents/6外部連接 MCP + 插件 MCP 連接器7明確技能 SKILL.md $skill-name8離線運行 Cloud Routines 雲端(規劃中)
問題從來不是「選哪個廠商」。而是「這六項功能是否都已安裝」。
這堂課要預防的疾病——手動迴圈:
四個步驟都做得很好,但沒有設定 cron。這不是一個迴圈——這只是一個你跑過一次就忘記的腳本。
解決方法: 掛上任何一個不依賴你記憶的觸發器。
在上線之前,回答這三個問題:
1/ 你的三個上限的具體數字是多少?
如果一個 bug 整晚都在運轉——哪個上限會第一個擋下來?如果沒有任何一個會擋下來……這說明了什麼?
2/ 你的人類之門長什麼樣子?
(PR 審查 / inbox / 每日抽樣 / 每週對帳?)把它寫下來 = 與自己簽訂合約
3/ 總結性問題: 六個月後,這個迴圈會讓你變得更強(理解力、判斷力、對系統的感知)——還是讓你變成了一台你無法讀懂的機器的看護者?你打算如何避免後者?
四種債務與保持工程師身份
你的迴圈已經建立:它會醒來、尋找工作、自我批評、記住經驗、並安排自己的明天。
當一個迴圈運行時,有四種東西會悄悄累積——它們的共同特點是沒有一種會觸發警報。
1驗證債務 未經審核的輸出不斷堆積2理解力衰退 程式碼庫在增長,你的心智地圖卻沒有3認知投降 「我不想再仔細審查了」4Token 爆量 一個 bug 整晚運轉 → 你看到的是帳單
它們會互相餵養: 未經審核的輸出侵蝕你的理解力 -> 被侵蝕的理解力引導你走向投降 -> 投降讓迴圈運行更久、花費更多 -> 進而產生更多未經審核的輸出。
在它第一次獨立運行之前,用這四點審查你的新迴圈:
- 我的評估器真的會拒絕輸出——它不是裝飾品。
- 我每天會閱讀一個 PR 樣本,並且能解釋發生了什麼變化。
- 我保留了說「這是錯的」的習慣。
- 我的上限是在第一次運行之前設定的,而不是在看到第一張帳單之後。
而這裡是決定一切的關鍵:
同一個迴圈,由兩個人建立,最終可能走向完全相反的方向。一個人用它來加速前進,同時仍然閱讀程式碼並掌握方向——這個迴圈放大了他們已有的判斷力。
另一個人則用完全相同的迴圈,目的就是為了再也不去理解任何東西——六個月後,第一個人變得更敏銳,而第二個人則成了一台他們無法讀懂的機器的看護者。
Addy Osmani:「建立迴圈,但要像一個打算繼續擔任工程師的人那樣去建立它——而不僅僅是按下啟動按鈕的人。」
迴圈讓生成內容幾乎免費,真正稀缺的變成了判斷力:哪個計劃是對的,該在哪一行停下來,哪個東西雖然能運行但從根本上就是錯的。迴圈不會貶低判斷力的價值——它剝離了一切不是判斷力的東西,只留下判斷力本身。
迴圈是一個忠實的放大器:
帶著理解力來——它會放大你的理解力。
帶著懶惰來——它會放大你的懶惰。
在你建立它之前,先決定好你想要放大什麼。
敬請期待!
祝你好運 :)





