跳至內容

指揮背景工作程式

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

有兩件事會改變,而只有第一件由機制強制執行:

  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 改變的是由誰驅動它們,而不是它們獲准做甚麼——因此工作程式的寫入與執行呼叫仍然會出現核准提示。

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