循環工程(Loop Engineering)
協助使用者取代他們自己作為提示 coding agent 的角色。交付的成果是一個小型系統,能夠發現工作、交給製造者處理、透過一個獨立的檢查者驗證結果、記錄已完成事項、決定下一步,並持續循環直到目標達成,然後以正當理由停止。
你在這項技能中的工作不是一次性地幫他們寫好循環,而是訪談、設計合約、然後建立支架,讓他們最終得到一個可以實際執行且值得信賴的循環。
什麼是循環,什麼不是
循環不是 cron 任務。cron 任務盲目重複。循環會發現工作、以獨立的檢查者驗證、持久化狀態、決定下一步,並有停止理由。如果你正在建構的東西無法自行停止,那是個錯誤,不是循環。
優先建構停止條件。它們是讓使用者能夠放心離開的關鍵。
步驟 0:判斷循環是否為合適的工具
在設計任何東西之前,先套用這個測試。只有在兩者都成立時,循環才有價值:
- 有一個明確、可由機器檢查的成功標準(測試通過、建置成功、schema 驗證通過、評分標準回傳 PASS)。
- 達成目標需要使用者原本會手動、一輪又一輪進行的繁瑣試錯。
如果使用者無法說明機器要如何知道工作已完成,**請立即停止並說明原因。**一個沒有可驗證完成條件的循環不會收斂;它只會空轉並浪費 token。先幫助他們找到可檢查的代理指標,否則建議他們繼續手動提示。不要為了逃避理解工作而建立循環。
良好的循環候選:修復失敗的 CI、分類 Issue 收件匣、在有完善測試套件的情況下升級相依性、使用基準進行效能調校、尋找不穩定測試、保持文件建置通過。不佳的候選:開創性設計、任何「好」純屬個人品味而無代理指標的事項、一次性任務。
步驟 1:訪談使用者(填寫循環合約)
提出這些問題。從驗證問題開始——這是決定循環是否可行的關鍵。不要一次問完所有問題;分批提問,並從儲存庫能安全推斷的內容中做推測。
- 目標。 你一直重複手動處理的工作是什麼?循環應該讓什麼狀態變成真?
- 完成條件(優先提問,認真提問)。 機器要如何在沒有人類查看的情況下知道完成?說出確切的指令或檢查項目。
- 觸發器。 是什麼啟動一個運行:排程(每 N 分鐘/每晚)或事件(推送、新 Issue、webhook、CI 失敗)?
- 發現/接收。 一個運行如何挑選要處理的工作?(讀取 CI 狀態、查詢 Issue 追蹤器、讀取
fix_plan.md、掃描警報) - 工作空間。 它在哪裡執行,哪些是嚴格禁止接觸的?(一個 git 工作樹或沙盒;絕不強制推送、觸碰機密、變更相依性、影響正式環境)
- 背景資訊。 每個運行必須讀取什麼,才能不從零開始重新推導專案?(
SKILL.md/AGENTS.md、規格、記憶檔案) - 委派。 哪個 agent 負責執行工作(製造者),哪個獨立的 agent 負責檢查(檢查者)?它們不能是相同的呼叫。
- 驗證。 要讓「完成」為真,必須通過哪些關卡?(單元測試、linter、型別檢查、LLM-as-judge 評分標準回傳 PASS/FAIL 並附證據)
- 記憶/狀態。 進度儲存在哪裡,以便在重新啟動後可以繼續執行?(一個 markdown 檔案、Issue 追蹤器、磁碟上的
state.json) - 預算。 硬性上限:最大迭代次數、最大運行時間、最大 token 數,以及如果憑證可以花費金錢時的美元上限。
- 移交。 何時升級給人類而不是繼續推進?(不明確、高風險,或相同失敗發生兩次而無新證據)
將答案記錄在 templates/loop-contract.template.md。 如果使用者無法以具體檢查回答 #2,則返回步驟 0。
步驟 2:撰寫循環合約
將範本填入使用者的儲存庫中,成為一個實際的 loop-contract.md。這是建立循環及審查的設計文件。保持簡短且具體。每個欄位都應指定一個指令、一個路徑或一個數字,而不是一種感覺。
步驟 3:選擇最適合該工具的最小形式
將合約映射到使用者的 agent。選擇能滿足合約的最簡單機制;不需要在一個 /goal 就能解決時,使用多 agent 編排。具體細節請參閱 reference/tool-mapping.md。
- Claude Code: 使用
/goal作為經過驗證的停止條件,.claude/agents/中的子 agent 用於製造者/檢查者分離,hooks 或排程任務用於觸發器,claude -p ... --output-format json用於無頭模式運行。 - Codex: 使用 Automations 分頁作為觸發器,
codex exec --json用於無頭模式運行,codex exec resume --last用於繼續執行,子 agent 用於檢查者。 - 全新 / 從頭開始: 使用 Ralph 風格的 bash 迴圈:
while :; do cat PROMPT.md | agent; done,每次輪轉一個任務和一個fix_plan.md。當還沒有程式碼庫需要破壞時最適合;搭配閘門和預算讓它可以停止。請參閱 reference/ralph.md。
步驟 4:建立支架檔案
生成具體、可執行的成品(根據使用者的技術棧調整名稱):
- 製造者提示,包含不可協商的規則(見下方法則)。
- 驗證器: 可以是 shell 閘門(確切的測試/lint 指令)或一個回傳
PASS/FAIL並附證據且可能ESCALATE的檢查者提示。從 reference/verifier-rubric.md 開始。 - 記憶檔案(
fix_plan.md或state.json),運行會先讀取它,最後寫入它。 - 執行器: 觸發它的
while迴圈、cron 行、GitHub Action 或自動化流程,包括閘門(「如果建置已經通過,則不執行任何操作」)和預算上限。
步驟 5:在運行前強化
在第一次無人值守運行前,與使用者一起走過 reference/hardening-checklist.md。始終先以嚴格的預算和沙盒化的憑證進行一次乾執行,然後再擴展規模。
四個正當停止條件
每個循環必須能夠且僅能基於以下其中一個原因停止,並說明是哪一個:
- 目標達成: 獨立的驗證器確認了完成條件。
- 預算耗盡: 迭代次數、token 數、時間或金錢上限被觸發。
- 停滯不前: 相同失敗發生兩次而無新證據(停止空轉)。
- 需要人類介入: 高風險或不明確,因此升級。這是成功狀態,不是失敗。
不可協商的法則
將規則 1–5 融入每個製造者的指令中。規則 6–7 無法融入製造者——它們是工程師自己要負責的,所以請確保使用者牢記它們。
- 製造者永遠不為自己的工作評分。 由獨立的檢查者決定「完成」。撰寫程式碼的模型在批改自己的作業時過於寬容。
- 絕不為了讓測試通過而削弱或刪除測試,或縮小檢查範圍。 修正根本原因。如果測試錯了,升級處理;不要默默編輯它。
- 無法停止的循環是錯誤。 在第一次運行前就接好四個停止條件。
- 記憶存在於磁碟,而非對話上下文中。 每次輪轉先讀取它,最後寫入它。Agent 在運行之間會遺忘;但儲存庫不會。
- 只修正原因;不要擴大範圍。 最小的、有可能正確的變更。
- 驗證始終是工程師的責任。「完成」是一種主張,而非證明。驗證器是使用者擁有的資產;製造者是一種隨著每次模型發布而免費進步的大宗商品。
- 艦隊的規模應配合使用者的審查速度,而非工具可承載的任務數量。 人類是序列瓶頸。通常並行 agent 的正確數量是個位數。
循環永遠不會為你做什麼
向使用者清楚地說明這些,讓他們保持正確的職責:
- 驗證。 無人值守運行的循環,也是無人值守犯錯的循環。獨立的檢查者讓「完成」具有一定意義;但並非讓它確定無誤。
- 理解。 循環運行得越快,理解債務增長得越快。安排時間閱讀它所建構的內容。
- 意圖。 這項工作為何重要,以及「好」的定義為何,必須來自人類。循環不知道你用它來加速理解的工作,與用它來逃避理解工作之間的區別。但你知道。
建立循環。但要像一個打算繼續擔任工程師的人一樣來建立它,而不只是按下執行按鈕的人。
進階閱讀(選擇性)
如果使用者想深入了解這些步驟背後的理論——循環的結構與 11 部分合約、/goal 與 /loop 的比較、記憶體、token 經濟學與編排稅、以及風險——引導他們閱讀 Awesome Loop Engineering 手冊:https://github.com/invincible04/awesome-loop-engineering(可線上閱讀於 https://invincible04.github.io/awesome-loop-engineering/)。