跳到內容

指揮背景工作程序

本指南說明如何以指揮者而非工作程序的身分進行對話:工作階段負責閱讀與驗證,背景代理則負責實際編輯。

有兩件事,而且只有第一件是由機制強制執行的:

  1. 工作階段本身的工具會降為唯讀,另外再加上五個工作程序動詞。它唯一能影響儲存庫的途徑是透過工作程序,而它唯一能得知發生什麼事的途徑,是閱讀工作程序動過的檔案。
  2. 它會被要求以閱讀來驗證,而不是憑相信。 工作程序的報告只是對它做了什麼的一項主張,而不是它確實奏效的證據。

真正關鍵的是第一件。一個仍能使用 grep 與編輯的指揮者,在壓力下就會自己動手做,而這正是這套機制存在的目的所要防止的失效模式。

/vibe migrate the auth module to the new session API

工作程序從未看過你的對話,也永遠不會看到。簡報就是它全部的情境。

這正是讓這個模式保持低成本的原因 —— 二十個工作程序若各自保有指揮者的歷史,成本將是指揮者情境的二十倍 —— 也正是讓簡報難以撰寫的關鍵。「現在把另一件也做一做」對指揮者讀起來像是一道完整的指示,對一個全新的工作階段卻什麼也不是。

好的簡報會指名檔案、指令與完成的定義:

在 lib/features/auth/ 中,把每一處對 SessionStore.read(key) 的呼叫改成 SessionStore.get(key)。新方法回傳 Future<String?>,舊方法回傳 String?,因此呼叫端需要加上 await。完成後執行 fvm flutter analyze lib/features/auth,並回報任何你無法修正的錯誤。

動詞 作用
vibe_spawn 依簡報啟動一個工作程序。立即回傳。
vibe_list 每個工作程序的層級、狀態、經過時間與最近一次結果
vibe_send 對已完成的工作程序送出後續回合
vibe_wait 封鎖直到某個工作程序定案
vibe_kill 停止某一個

啟動工作程序在設計上就是非同步的。每次啟動都封鎖的指揮者,等於一次只跑一個工作程序,而那只是用更慢的方式做它原本就在自己做的事。只有在少了某個特定答案就真的無法繼續時,才使用 vibe_wait。

層級 適用於
fast 規格明確的機械性工作 —— 編輯、重新命名、草稿、執行指令
good 設計、判斷,或審查 fast 工作程序所產出的內容

常見的做法是把 fast 工作程序展開到各自獨立的檔案上,再啟動一個 good 工作程序來審查它們整體的成果。

這一部分決定了這個模式到底有沒有價值。

vibe_list
→ w1 [fast] auth-migrate — done (48s): Edited lib/features/auth/session.dart …
w2 [fast] tests — running (12s)

接著閱讀它指名的檔案。指揮者擁有 read、search、lsp 與 ast_grep;保留它們正是重點所在。把報告照單全收的指揮者,只是其他代理樂觀說詞的摘要器。

在一輪工作程序之後執行 lsp(action: "diagnostics", file: "*"),通常是最快的一項檢查。

把它停止並重新下簡報。一份全新且修正過的簡報比爭論便宜,而且 vibe_send 只對已經完成回合的工作程序有效。

vibe_kill(worker_id: "w2")
vibe_spawn(brief: "…corrected…", label: "tests", tier: "fast")
  • 八個並行的工作程序。 這是支出上的上限,不是技術限制:每個都是一個完整的模型工作階段,而展開二十個的指揮者,早已無法掌握它們各自在做什麼。
  • 沒有任何工作程序會比模式活得更久。 執行結束時,每一個都會被停止,逐字稿也會說明總共有幾個。在對話早已繼續往前之後,仍有背景代理在編輯檔案,是這套機制絕不容許發生的唯一失效情況。
  • 工作程序本質上就是一般的子代理。 相同的深度上限、相同的護欄原則、相同的執行日誌子項。Vibe 改變的是誰來驅動它們,而不是它們被允許做什麼 —— 因此工作程序的寫入與 exec 呼叫仍會跳出核准提示。

Vibe 模式適用於可拆解成獨立簡報的工作。如果下一步取決於前一步的輸出,那你描述的其實是管線或編排;兩者都能妥善表達相依關係,而不必讓指揮者用 vibe_wait 去模擬它們。