9.1 什麼是 Ultrawork

Ultrawork 是 OpenCode 的核心工作哲學——一種由多代理協作驅動、全自動化的開發流程。與傳統開發者工具不同,OpenCode 不會被動等待指令,而是主動解析意圖、規劃路徑、分派任務並反覆驗證,直到目標達到 100% 完成。

整個流程將開發者從繁瑣的細節中解放出來,讓 AI 代理負責執行與驗證,開發者則專注於創意決策與架構設計。

💡 核心概念: Ultrawork 不是單純的「自動完成」,而是一種帶有自我修正能力的協作循環。每個代理都有獨立的驗證機制,確保輸出的品質。

Ultrawork 六步驟流程

完整的 ultrawork 執行循環包含以下六個階段:

①

意圖解析

Sisyphus 代理透過 IntentGate 分析使用者輸入,區分「直接指令」與「複雜任務」,決定是否需要啟動規劃流程。

②

自動規劃

Prometheus 代理以面試模式引導開發者補充需求細節,自動產出結構化執行計畫,包含任務分解、依賴關係與驗證標準。

③

計畫審查

Metis(邏輯審查)與 Momus(批評審查)雙代理獨立分析計畫,找出盲點、安全問題與可優化之處。

④

任務分派

Sisyphus 根據任務類別路由至對應代理,並自動注入所需的領域技能(Skill)與上下文。

⑤

並行執行

多代理同步工作,各自擁有獨立驗證器。每個代理完成後立即觸發同儕審查,確保品質。

⑥

循環驗證

Ralph Loop 持續檢查完成度。若有未達標的項目,自動重新調度代理執行修正,直到全部通過。

9.2 Ralph Loop:不完成不停止

Ralph Loop 是 OpenCode 最強大的自動化機制之一。它的核心理念非常簡單——一旦啟動,就絕不停歇,直到 100% 完成。

當開發者下達 /ulw-loop 指令時,Sisyphus 會進入自我參照循環(self-referential loop):

  1. 執行當前待辦事項中優先級最高的任務
  2. 執行完成後立即標記並驗證
  3. 檢查是否還有未完成的任務
  4. 若有,回到步驟 1;若無,宣布完成並結束循環
~/project — Ralph Loop 執行範例
$ /ulw-loop
🔍 Ralph Loop 啟動 — 目標:實作使用者認證系統
📋 待辦清單:5 項任務
[ ] 1. 建立 User 資料庫模型
[ ] 2. 實作註冊 API
[ ] 3. 實作登入 API(JWT)
[ ] 4. 建立前端登入頁面
[ ] 5. 撰寫測試案例
────────────────────────────────
▶ 執行任務 1:建立 User 模型...
✅ 任務 1 完成 (驗證通過)
▶ 執行任務 2:實作註冊 API...
✅ 任務 2 完成 (驗證通過)
▶ 執行任務 3:實作登入 API...
❌ 任務 3 驗證失敗:Token 過期時間未設定
↻ 重新執行任務 3...
✅ 任務 3 完成 (驗證通過)
▶ 執行任務 4...
✅ 任務 4 完成 (驗證通過)
▶ 執行任務 5...
✅ 任務 5 完成 (驗證通過)
────────────────────────────────
🎉 Ralph Loop 完成 — 5/5 任務通過驗證
$
⚠️ 注意: Ralph Loop 會持續執行直到所有任務完成。若任務數量過大或依賴外部資源,建議搭配定時中斷機制或 Boulder 系統使用。

9.3 Prometheus 規劃模式

Prometheus 是 OpenCode 的規劃代理,透過 /start-work 指令啟動。它採用「面試模式」與開發者對話,逐步收斂需求範圍,最終產出一份完整的執行計畫。

面試模式流程

Prometheus 不會憑空猜測需求,而是像一位資深技術經理一樣,有條理地詢問關鍵問題:

階段 提問內容 具體提問範例 輸出成果
範圍界定 想完成什麼?目標是什麼? 「這個功能的核心使用者是誰?希望解決什麼痛點?」
「成功上線後,使用者會看到什麼不一樣?」
明確的任務邊界
技術約束 使用什麼語言/框架?有無特定限制? 「此專案是否與現有系統相容?有無特定的佈署環境要求?」
「是否需要支援舊版瀏覽器或特定裝置?」
技術棧與約束列表
優先順序 什麼最重要?哪些可以延後? 「如果時間只剩一半,哪些功能可以犧牲?」
「這個任務的依賴關係是什麼?哪些必須先完成?」
排序後的待辦清單
驗證標準 怎麼知道完成了?通過條件是什麼? 「這個功能通過測試的具體指標為何?」
「是否需要經過 Code Review 或效能 benchmark?」
可量化的驗證條件
風險評估 可能出錯的地方?備援方案? 「這個步驟若失敗,對整體進度的影響範圍為何?」
「是否有 rollback 機制或備用方案?」
風險矩陣與應對策略

執行計畫結構

Prometheus 產出的計畫包含以下元素:

  • 任務清單 — 每個任務有獨立的編號、描述與分類
  • 依賴圖 — 任務之間的先後關係(DAG)
  • 驗證條件 — 每個任務的「完成」定義
  • 路由策略 — 每個任務由哪個類別的代理執行
  • Skill 注入 — 需要載入哪些領域技能
💡 實戰技巧: 若需求較為模糊,建議先手動整理一份粗略的 TODO 清單再啟動 /start-work,Prometheus 會以你的清單為基礎進行深化,效率更高。

9.4 /init-deep:階層式知識庫

/init-deep 是 OpenCode 的專案初始化指令,會遞迴掃描專案目錄結構,在每個目錄下產生對應的 AGENTS.md 知識庫檔案。

這種階層式設計讓每個模組、每個目錄都能擁有獨立的上下文說明,代理在執行任務時只載入相關的知識庫片段,大幅減少雜訊、提升精準度。

# 在專案根目錄執行
/init-deep

# 執行後產生的結構:
project/
├── AGENTS.md          # 全域知識庫
├── src/
│   ├── AGENTS.md      # 模組層知識庫
│   ├── components/
│   │   ├── AGENTS.md  # 元件層知識庫
│   │   └── Button.tsx
│   └── utils/
│       └── AGENTS.md
└── tests/
    └── AGENTS.md
📘 了解更多: 階層式知識庫的設計模式在第 7 章有更詳細的探討。每個 AGENTS.md 可以定義該目錄的命名慣例、設計模式、常見陷阱與測試策略。

9.5 Hashline:內容雜湊驗證

Hashline 是 OpenCode 的內容完整性驗證機制。每一次檔案編輯完成後,系統會自動計算檔案的內容雜湊值,並與預期的 Hash 比對。

這項機制確保了:

  • 檔案在寫入過程中沒有被意外修改
  • 多代理並行工作時不會產生衝突
  • 編輯操作是可追溯、可驗證的

Hashline 的驗證發生在每次 Edit 或 Write 工具呼叫之後,若雜湊不匹配,系統會自動重試或回報錯誤。

9.6 背景任務與並行執行

在傳統的單代理工作流程中,任務只能依序執行——代理必須完成一個任務後才能開始下一個。OpenCode 提供了背景任務機制,透過 run_in_background=true 參數讓代理能夠同時啟動多個獨立任務,大幅提升執行效率。

使用 run_in_background

當代理需要執行多個互不依賴的任務時,可以將部分任務設定為背景執行。背景任務會在獨立的上下文中執行,不會阻塞主流程的進行:

# 在前端背景中啟動三個獨立任務
task(subagent_type="explore",
     run_in_background=true,
     prompt="搜尋最新的 React 18 文件...")
     
task(subagent_type="explore",
     run_in_background=true,
     prompt="檢查現有專案的相依性版本...")

task(subagent_type="librarian",
     run_in_background=true,
     prompt="查詢常用的測試框架比較...")

# 主流程繼續執行其他工作...
📘 注意: 背景任務適合讀取密集或調研類的工作。寫入操作(如修改檔案、執行資料庫遷移)不建議在背景執行,因為可能產生存取衝突。

並行工作的好處

多代理並行執行帶來了顯著的好處:

  • 縮短整體時程 — 原需依序花費 15 分鐘的三個調研任務,並行後可在 5 分鐘內完成
  • 充分利用模型配額 — 不同代理可以使用不同的模型,同時處理不同類型的任務
  • 獨立錯誤隔離 — 一個背景任務失敗不會影響主流程或其他背景任務
  • 資源最佳化 — 讀取密集型與計算密集型任務可以交錯執行,充分利用系統資源

收集背景任務結果

背景任務啟動後,系統會回傳一個唯一的 task_id。主流程可以在適當的時機透過 background_output 收集任務結果:

# 取得背景任務的輸出
const result = await background_output(task_id="task_abc123")

# 也可以設定逾時(以毫秒為單位)
const result = await background_output(
  task_id="task_abc123",
  timeout=300000  # 最多等待 5 分鐘
)

task_id 的追蹤與重複使用

每個背景任務都有唯一的 task_id,這個 ID 不僅用於收集結果,還可以用於:

  • 取消任務 — 若任務已不再需要,可以透過 background_cancel(task_id) 終止執行
  • 重複使用結果 — 同一個 task_id 可以被多個代理查詢,避免重複執行相同任務
  • 任務依賴管理 — 可以在一個背景任務完成後自動啟動另一個依賴它的任務
  • 日誌追蹤 — 所有的背景任務輸出都會被記錄,便於事後審計與除錯
💡 實戰技巧: 在啟動 Ralph Loop 前,可以先將資料收集類的任務以背景方式啟動。當 Ralph Loop 執行到需要這些資料的步驟時,資料通常已經準備就緒,形成自然的管線化流程。

CLI 模擬:背景任務實戰

以下展示一個完整的背景任務工作流程:

# 場景:開發一個新的登入頁面
# 步驟 1:並行收集資料
→ task(subagent_type="explore",
       run_in_background=true,
       prompt="調研主流登入頁面設計模式")

→ task(subagent_type="explore",
       run_in_background=true,
       prompt="查詢 OAuth 2.0 最新安全規範")

→ task(subagent_type="librarian",
       run_in_background=true,
       prompt="收集專案現有 UI 元件庫的文件")

# 步驟 2:主流程繼續進行架構規劃
→ 分析現有路由系統
→ 設計認證流程圖

# 步驟 3:收集背景任務結果
→ background_output(task_id="task_001")  # 取得設計模式調研結果
→ background_output(task_id="task_002")  # 取得安全規範
→ background_output(task_id="task_003")  # 取得 UI 元件文件

# 步驟 4:綜合所有資訊開始實作
→ 結合調研結果撰寫登入頁面程式碼
⚠️ 注意: 背景任務雖然強大,但不要濫用。每個背景任務都會消耗 Token 配額。建議只將純粹的讀取、調研、搜尋類任務放在背景執行,寫入與修改類任務應在主流程中依序處理。

9.7 生命週期掛鉤(32 個 Hooks)

OpenCode 提供了 32 個生命週期掛鉤,讓開發者能在代理執行的各個階段插入自訂邏輯。這些掛鉤涵蓋了從任務開始到結束的完整流程:

類別 掛鉤名稱 觸發時機
任務生命週期 beforeTask, onTaskComplete 任務開始前 / 完成後
工具生命週期 afterToolUse, beforeToolUse 工具呼叫前後
代理回覆 beforeAgentReply, afterAgentReply 代理產生回覆前後
會話管理 onSessionStart, onSessionEnd 會話開始 / 結束
錯誤處理 onError, onRetry 錯誤發生 / 重試時
驗證 beforeVerify, onVerifyFail 驗證前 / 驗證失敗
💡 使用場景: 例如透過 beforeAgentReply 掛鉤自動加入專案規範的簽名檔,或利用 onError 掛鉤實現自動 Slack 通知。

為什麼 LLM 無法有效協作?

在傳統的多 LLM 協作架構中,存在三個根本性的問題:

  • 缺乏上下文共享 — 每個 LLM 實例擁有獨立的對話上下文,不知道其他代理做了什麼決定、產生了什麼程式碼。這導致重複工作與衝突。
  • 任務碎片化 — 當一個任務需要多個代理接力完成時,中間結果的傳遞依賴於開發者手動複製貼上,容易出錯且效率低下。
  • 無品質控制 — 沒有統一的驗證機制,每個代理各自為政。一個代理的輸出錯誤會向下游擴散,最終產生難以除錯的連鎖問題。

32 個 Hooks 如何解決這些問題

OpenCode 的 32 個生命週期掛鉤並非隨意設計,而是有系統地對應上述三個問題:

問題 對應掛鉤 解決方式
上下文共享 beforeTask, onTaskComplete, onSessionStart 在任務開始前注入相關的歷史上下文,在任務完成後將結果廣播給相關代理
任務碎片化 afterToolUse, beforeAgentReply, onSessionEnd 在工具呼叫後自動保存中間產出,在代理回覆前檢查所有依賴是否已滿足
品質控制 beforeVerify, onVerifyFail, onRetry, onError 在驗證前注入測試標準,驗證失敗時自動觸發修正循環,錯誤發生時記錄完整堆疊

實際應用場景

以下展示幾個生命週期掛鉤在實戰中的具體應用:

  • beforeAgentReply — 自動注入專案規範:在代理每次回覆前,自動從 AGENTS.md 中提取與當前任務相關的規範片段(如命名慣例、程式碼風格),確保所有輸出都符合團隊標準。
  • onError — 自動 Slack 通知:當代理執行過程中發生不可恢復的錯誤時,自動將錯誤訊息、堆疊追蹤與當前上下文打包,透過 Webhook 發送到團隊 Slack 頻道。
  • afterToolUse — 自動保存檢查點:每次檔案寫入操作完成後,自動觸發 git commit 並記錄 Hashline 驗證結果,形成可追溯的變更歷史。
  • onVerifyFail — 自動建立 Bug 報告:當驗證失敗時,自動建立包含重現步驟、預期行為與實際行為的結構化報告,並指派給對應的修正代理。
  • onSessionStart — 載入開發環境:在新會話開始時,自動檢查必要的環境變數、連線至資料庫、載入專案專用的 MCP 設定,確保代理從正確的起點開始工作。
📘 設計哲學: 32 個 Hooks 並非功能堆疊,而是一套完整的「代理協作協議」。每一個 Hook 都在解決一個特定的協作斷點——從任務開始前的準備、執行中的同步、到完成後的交接——形成一條沒有縫隙的協作鏈。

9.8 內建 MCP 伺服器

OpenCode 出廠即內建了三個強大的 MCP 伺服器,無需額外設定即可使用:

🔍

Exa Websearch

提供即時的網路搜尋能力,代理可以直接查詢最新的技術文件、API 變更、社群討論與解決方案。

📚

Context7

官方文件檢索服務,支援 500+ 主流框架與函式庫的最新文件。代理可精確查詢 API 簽名、參數說明與使用範例。

💻

Grep.app

GitHub 程式碼搜尋引擎,讓代理能從數百萬個開源專案中尋找真實世界的實作參考與最佳實踐。

9.9 Tmux 整合與互動式終端

OpenCode 支援 Tmux 整合,讓代理能夠操作互動式終端機——包括 REPL、除錯器、資料庫客戶端等需要持續互動的工具。

這項能力讓代理不僅僅是執行靜態命令,更能與長時間運行的程序互動、監控輸出並根據結果動態調整下一步操作。

// opencode.json 中的 Tmux 設定
{
  "tmux": {
    "enabled": true,
    "session": "opencode-dev",
    "pane": "main",
    "scrollback": 5000
  }
}

9.10 代理模型覆蓋

在 opencode.json 中,開發者可以針對不同代理指定不同的模型,以最佳化成本與效能:

{
  "agents": {
    "Sisyphus": {
      "model": "gpt-5.2-codex"
    },
    "Prometheus": {
      "model": "gpt-5.2-codex"
    },
    "Metis": {
      "model": "gpt-5.2-codex",
      "temperature": 0.3
    },
    "Momus": {
      "model": "gpt-5.2-codex",
      "temperature": 0.7
    },
    "explore": {
      "model": "gpt-5.2-codex"
    }
  }
}
📘 提示: 創意型任務(如 Momus 批評審查)可選用較高 temperature 值以產生更多樣化的見解;精確型任務(如 Metis 邏輯審查)則建議較低的 temperature。

9.11 Boulder 系統:中斷與恢復

Boulder 系統是 OpenCode 的中斷恢復機制。當長時間執行的工作被意外中斷(如網路斷線、系統重啟),Boulder 會自動保存當前狀態,並在下次啟動時恢復。

搭配 Ralph Loop 使用時,Boulder 確保即使開發環境重啟,已經完成的任務不會遺失,未完成的任務會自動繼續執行。

💡 最佳實踐: 在執行預計超過 30 分鐘的 Ralph Loop 前,確認 Boulder 系統已啟用。可以透過 /context-save 手動觸發狀態保存,或設定自動間隔保存。

9.12 工作流程比較

流程 啟動指令 適用場景 持續時間
Ultrawork 完整流程 /start-work 新功能開發、大型重構 數分鐘~數小時
Ralph Loop /ulw-loop 多步驟實作、Bug 修復系列 直到 100% 完成
Prometheus 規劃 /start-work 需求模糊需要收斂 5~15 分鐘
快速任務 直接描述需求 單一檔案修改、簡單查詢 數秒~數分鐘
背景代理 run_in_background=true 並行調研、獨立驗證 非同步執行

9.13 實戰案例:完整 OmO 工作流程

以下展示一個完整的 OpenCode 實戰案例,從需求輸入到最終交付,涵蓋本章介紹的所有核心機制。

場景:為一個電商平台新增搜尋功能

開發者輸入:「幫我為這個電商平台加上全文搜尋功能,支援模糊比對與分類過濾。」

步驟 1:意圖解析與規劃

Sisyphus 代理收到需求後,判斷這是一個多步驟的複雜任務,自動啟動 Prometheus 面試模式:

Prometheus: 「這個搜尋功能要涵蓋哪些欄位?商品名稱、描述、還是包含評論?」
開發者:   「商品名稱和描述就好,評論先不做。」
Prometheus: 「前端要什麼互動方式?即時搜尋還是提交表單?」
開發者:   「即時搜尋,輸入停止後 300ms 觸發。」
Prometheus: 「有無效能要求?預計的商品筆數為何?」
開發者:   「大約 10 萬筆,搜尋回應要在 500ms 內。」

步驟 2:背景任務並行調研

Prometheus 產出計畫後,Sisyphus 啟動兩個背景任務進行資料收集:

→ task(run_in_background=true,
       prompt="查詢 PostgreSQL 全文搜尋的最佳實作與效能調校")

→ task(run_in_background=true,
       prompt="調研 React 即時搜尋元件的設計模式與無障礙規範")

步驟 3:生命週期掛鉤確保品質

在實作過程中,多個生命週期掛鉤被自動觸發:

  • beforeTask — 注入專案的資料庫連線規範與現有 API 風格指南
  • afterToolUse — 每次檔案寫入後自動進行 Hashline 驗證與 git commit
  • beforeVerify — 自動載入搜尋功能的測試案例
  • onVerifyFail — 當模糊比對的準確率未達標時,自動觸發修正循環

步驟 4:Ralph Loop 確保 100% 完成

當其中一個任務(前端防抖實作)未通過驗證時,Ralph Loop 自動重試:

→ Ralph 偵測到「前端搜尋輸入」任務失敗 (失敗原因: 防抖未達 300ms 標準)
→ 自動修正防抖實作
→ 重新執行驗證套件
→ 全部通過 ✓
→ 繼續下一個任務...

步驟 5:Boulder 中斷恢復

在執行過程中開發環境意外斷線,Boulder 保存了當前狀態。重新連線後:

→ Boulder 恢復最後狀態 (已完成 7/10 任務)
→ Ralph Loop 從第 8 個任務繼續執行
→ 無需人工介入

產出結果

整個流程在無需開發者手動介入的情況下,完成了以下交付:

  • PostgreSQL 全文搜尋索引遷移腳本
  • RESTful 搜尋 API 端點(含分頁、模糊比對、分類過濾)
  • React 即時搜尋元件(含 300ms 防抖、無障礙支援)
  • 單元測試與整合測試套件(覆蓋率 > 90%)
  • 效能測試報告(驗證回應時間 < 500ms)
💡 關鍵啟示: 這個案例展示了 OmO 的核心價值——開發者只需描述「做什麼」,系統自動處理「怎麼做」。從 Prometheus 的規劃、背景任務的並行調研、生命週期掛鉤的品質控制、到 Ralph Loop 的自我修正,每個環節都在無需人工介入的情況下自主運作。

📝 本章測驗

1. Ralph Loop 的核心運作原則是什麼?
2. 關於背景任務與 run_in_background=true,下列敘述何者正確?
3. 生命週期掛鉤中,beforeAgentReply 的主要用途是什麼?
4. Prometheus 規劃模式的「面試模式」中,不包含以下哪個階段?

❓ 常見問題

Ralph Loop 和一般的 TODO 自動執行有什麼差別? ▼

Ralph Loop 的核心差異在於「自我驗證與修正」。一般的 TODO 自動執行只是依序完成清單,但 Ralph Loop 在每個任務完成後會立即觸發驗證,若驗證不通過,會重新執行該任務直到通過為止。此外,Ralph Loop 會動態調整任務優先順序,並在發現依賴問題時自動重新排序。

Boulder 系統如何與 Ralph Loop 協作? ▼

Boulder 系統在 Ralph Loop 執行的每個步驟完成後,都會自動保存當前的狀態快照——包含已完成任務、進行中任務的上下文、以及待辦清單的優先順序。如果進程意外中斷(如網路斷線、編輯器關閉),重新啟動後 Boulder 會載入最後一次快照,Ralph Loop 會從中斷點繼續執行,不會丟失任何進度。

什麼情況下應該使用 /start-work 而不是直接描述需求? ▼

當需求較為複雜、涉及多個檔案或步驟、或需要多個代理協作時,建議使用 /start-work。直接描述需求適合單一步驟的簡單任務(如「幫我修正這個函數的名稱」)。如果您不確定需求是否夠清晰,可以先簡單描述,若 Sisyphus 判斷需要更完整的規劃,它會主動建議啟動 Prometheus 模式。