3KProject Agent Workflow Notes

我怎麼把多 Agent 協作做成 3KProject 裡真正可執行的工作流

這篇文章整理的是我在 3KProject 裡處理 Agents 協作的做法。真正讓流程穩下來的,不是再加一個更聰明的模型,而是把協作拆成鎖卡、閘門、handoff、context budget 四條主線,並且讓它們各自對應到明確的文件與工具。

Lock 先鎖 task 再開始做,避免多個 Agent 在同一張卡上互撞,或同時改同一個高風險檔。
Gate 把 pre-flight、in-flight、post-flight 的檢查固定下來,讓規則不只存在於文件裡。
Handoff 交接不是丟一段長文,而是把 changed files、決策、blocker 與下一步壓成可接手的摘要卡。

我後來發現,問題不在模型夠不夠強

多 Agent 協作最難的地方,不是生成能力,而是接手能力。只要接手時沒有清楚的範圍、狀態與驗證方式,再強的模型也會把 repo 搞亂。

我一開始其實也把問題想得太簡單,覺得只要 instructions 寫得夠細,Agents 就會自然協作。但實際做下去才發現,真正的失敗場景都很工程化:同一張卡被兩個人碰、上一位改了什麼下一位看不懂、handoff 帶了太多背景導致 context 爆掉、規則寫在文件裡卻沒有被工具執行。

所以我最後不是去追一個更厲害的 prompt,而是反過來收斂出一套 repo operating system。這套 operating system 背後對應的,就是幾份我在專案裡反覆打開的文件:協作指令、任務卡手冊、keep workflow shard、context budget guideline,以及多 Agent 協作協議。

如果把單一 Agent 想成 Unity 裡一個很會幹活的 component,那多 Agent 協作就比較像整個 scene 的 execution order、event contract 與 runtime guard。單個 component 再強,也不能取代整個執行順序與生命週期管理。

我最後收斂出的協作主鏈

看完整個 repo 之後,我把協作流程收斂成一條很短的主鏈:先讀共識摘要、先做 context budget 檢查、先鎖卡,接著只在局部範圍內修改,再用 focused validation 做第一輪驗證,最後把結果壓成 handoff 交給下一位 Agent。這條鏈一短,很多隱性風險就會直接浮出來。

接到新需求或任務卡 Pre-flight 讀 keep.summary → 跑 check-context-budget → task-lock.js check / lock → 確認本輪 scope In-flight 只改局部檔案與局部行為,修改後立刻做第一個 focused validation,不在同一輪擴大範圍 驗證是否通過 cheap check 優先 失敗:就地修補 回到同一 slice,修同一個缺口,再跑同一個檢查 成功:handoff + unlock 寫 changedFiles / decisions / blockers / nextAction,交給下一位 Agent FAIL PASS
圖 1:我最後讓所有 Agents 都走同一條主鏈,目的不是增加流程感,而是把「何時該擴範圍、何時不能擴」變成明確規則。

為什麼要先鎖卡

我不再把 task lock 當成流程負擔,而是把它當成最便宜的碰撞避免器。只要一開始沒鎖,後面所有 handoff 都會變得很難信任。

為什麼要先做 cheap check

最先跑的驗證一定要夠便宜、夠局部。這樣它才能真的跟著每次修改一起跑,而不是變成收工前才想起來的儀式。

我真正常打開的協作文件

如果要把這套協作方法拆回文件層,我最常打開的是五組文件。它們不是平行存在,而是各自扮演不同層級的角色:入口層、共識層、協作層、任務層與節流層。也因為這樣,我不需要把所有規則都塞進一份超大文件裡。

入口層:AGENTS.md / .github/copilot-instructions.md 先把語言、硬規則、pre-flight 與 task lock 的第一層入口收斂起來,讓任何 Agent 進場都有同樣的起手式。 共識層:docs/keep.summary.md + docs/keep-shards/keep-workflow.md - 用摘要而不是全文保留專案共識 - 任務卡、交接、撞檔與 Git 規則都在這裡落地 協作層:.github/instructions/ agent-collaboration.instructions.md - 三道防線:pre-flight / in-flight / post-flight - 直接把 task lock、compute gate、handoff 變成操作流程 任務層:docs/agent-briefs/Readme.md - 任務卡 lifecycle、notes 格式、commit 批次與交接規則 - 讓「誰在做什麼」與「做到哪裡」有正式落點 節流層:docs/agent-context-budget.md + docs/agent-collaboration-protocol.md - handoff 摘要卡、圖片節流、token hard-stop - 規定下一位 Agent 接手前要驗證什麼 支援腳本:task-lock.js / compute-gate.js / check-context-budget.js / report-turn-usage.js 文件負責講清楚規則,腳本負責把規則真的跑起來。這兩邊分開,協作才不會退化成口頭約定。
圖 2:我最後不是用一份大全文件處理所有協作問題,而是把它拆成多層文件,各自負責入口、共識、執行、節流與交接。
  • AGENTS.md / CLAUDE.md / .github/copilot-instructions.md:這三個專屬入口負責讓 Codex、Claude Code、Copilot 一進場就先看到硬規則,而不是先做事再回頭補流程。
  • .github/instructions/agent-collaboration.instructions.md:共享入口層,讓 Antigravity 與其他共用流程的 Agent 也能先吃到同一條鎖卡規則與三道防線。
  • docs/agent-briefs/Readme.md:任務卡與 notes 格式的正式落點,負責把協作狀態變成可回查紀錄。
  • docs/keep.summary.md / docs/keep-shards/keep-workflow.md:專案共識層,讓 Agents 不必重讀整份 keep 也能知道目前母規則。
  • docs/agent-context-budget.md / docs/agent-collaboration-protocol.md:把上下文節流與 handoff contract 明文化,防止協作在訊息層失控。

一個我後來認定必修的補洞:四大入口都要先看到鎖卡硬規則

我後來發現一個很危險的空洞:`task-lock` 規則其實早就存在,但它主要躲在 `docs/agent-briefs/Readme.md` 這種深層文件裡。這代表如果 Agent 是從 Copilot、Codex、Claude Code 或 Antigravity 的入口直接進場,它完全可能在不知情的情況下就跳過鎖卡流程。

這個問題的本質不是「規則不存在」,而是「規則沒有放在必經入口」。只要入口沒看到,後面的手冊寫再完整,也只是事後補課,而不是真正的 pre-flight guard。

四大 Agent 入口如果不先看到鎖卡規則,後面所有流程都有可能從第一步就偏掉 Copilot 入口: .github/copilot- instructions.md Codex 入口: AGENTS.md Claude Code 入口: CLAUDE.md Antigravity 共享入口: agent-collaboration instructions + keep.summary 硬規則 #0:先鎖卡 node tools_node/task-lock.js check <task-id> node tools_node/task-lock.js lock <task-id> <agent-name> 並立即補 status / started_at / started_by_agent 之後才准進 Pre-flight / 修改 / 驗證 / Handoff 如果這條規則沒有出現在入口,Agent 可能在第一步就直接繞過整個協作防線
圖 3:我後來把鎖卡規則往前搬到所有入口,因為只要入口沒看到,Agent 很可能在完全不知情的情況下就直接開工。
我最後採取的修補方式,不是再寫一篇更長的協作手冊,而是把硬規則 #0 直接前推到所有 Agent 的第一層入口。這件事看起來很小,但它對協作成功率的影響非常大。
  • 新建 `CLAUDE.md`:把 Claude Code 主入口的硬規則 #0 放到最上面,讓它在任何 pre-flight 之前先出現。
  • 更新 `AGENTS.md`:讓 Codex 入口一打開就先看到鎖卡規則,而不是只看到一般工作準則。
  • 更新 `.github/copilot-instructions.md`:在 Copilot 的 pre-flight 之前先補上硬規則,避免它把鎖卡誤當成次要流程。
  • 更新 `.github/instructions/agent-collaboration.instructions.md`:把鎖卡規則從 pre-flight 的其中一步,提升成共享的顯眼硬規則。
  • 更新 `docs/keep.summary.md` §5:把原本一句話的規則升級成明確指令區塊,讓共享共識層也能第一時間提醒這件事。

錯誤做法

把鎖卡規則放在深層文件,期待所有 Agent 都會自己往下讀到那一段。這在單人時可能還撐得住,但多人接力時幾乎一定會漏。

正確做法

每個入口第一屏就先看到 `check`、`lock` 和 frontmatter 更新要求。讓 Agent 一進場就知道「現在還不能改檔,先上鎖」。

這些文件實際在攔什麼錯

對我來說,這些文件最有價值的地方不在「寫得完整」,而在它們各自擋住了不同類型的失敗。只要把失敗類型拆出來,協作規則就會變得很具體,不再只是抽象口號。

常見失敗不是抽象的「Agent 變笨」,而是這四種具體事故 撞 task / 撞檔 主要靠 task-lock.js、docs/agent-briefs/Readme.md、agent-collaboration.instructions.md 先鎖卡、補 started_by_agent、限制高風險檔同時修改 先把同時做事的人分流開 接手失憶 主要靠 handoff contract、notes 格式、changedFiles 檢查 下一位 Agent 不是猜上一位做了什麼,而是先對照摘要與實際 diff 讓交接變成可驗證,不是靠記憶 context 爆量 主要靠 docs/agent-context-budget.md 與摘要卡格式 限制只帶 1 到 3 個必要檔、禁止整份 keep 與大圖直接塞進 handoff 讓下一輪仍然能保持局部推理 規則只停留在文件 主要靠 compute-gate、validate、encoding check、report-turn-usage 等腳本 把規則變成 pre-flight 與 post-flight 命令,而不是只靠 review 時口頭提醒 讓文件變成可執行流程
圖 4:協作文件之所以有效,是因為每一份文件都在攔不同類型的事故,而不是所有規則都混在一起。

我最怕的不是 bug

我真正怕的是「改動已經發生,但沒有人能確定它是誰改的、基於什麼規則改的、現在還能不能回放」。多 Agent 協作一旦沒有這三件事,就會很快變成無法維護的黑盒。

所以我才一直把規則拆小

規則拆小之後,每一層都只解一個問題。這種分層方式比一份總規範更實用,因為它真的能在當下支援某個具體動作。

我每天實際怎麼用這套文件

把這些規範看完之後,我的日常工作流其實變得很固定。每次接手前,我會先確認共識摘要、跑健康掃描與 context budget,接著鎖卡;改完之後先跑最便宜的檢查,再視情況補完整 gate,最後把 changed files 與 decisions 壓成 handoff。

Pre-flight:開始前固定跑的東西

node tools_node/compute-gate.js --profile quick --agent-feedback --no-stop
node tools_node/check-context-budget.js --changed
node tools_node/task-lock.js check <task-id>
node tools_node/task-lock.js lock <task-id> <agent-name>

Post-flight:收工前固定跑的東西

node tools_node/compute-gate.js --profile standard --agent-feedback
node tools_node/check-encoding-touched.js <changed-files...>
node tools_node/task-lock.js unlock <task-id> <agent-name>
node tools_node/report-turn-usage.js --changed --emit-final-line
這裡我最重視的不是命令本身,而是順序。先讀摘要再鎖卡,先做 focused validation 再擴範圍,先寫 handoff 再離場。順序一亂,後面的規則就算存在,也很容易變成補救而不是防守。

這種工作流的好處,是它非常適合小模型與接力式協作。只要每一輪都被限制在很小的 slice,模型不需要理解整個系統,也能穩定完成其中一段工作。這也是我後來越來越確定的一件事:多 Agent 協作不是在追求「同時很多人做事」,而是在追求「任何一個人接上來都還看得懂」。

我要求每一輪至少留下什麼 handoff

在這個 repo 裡,handoff 已經不是自由發揮的摘要,而是有明確欄位的 contract。對我來說,最好用的格式不是長文,而是讓下一位 Agent 一眼就知道這輪該看哪幾個檔案、哪些事情已經定了、哪些不要重讀。

Task: HARN-ARCH-0002
Goal: 修掉 battle -> ui 的非法引用
Read:
- docs/keep.summary.md
- docs/agent-briefs/tasks/HARN-ARCH-0002.md
- shared/interfaces/IBattleUIBridge.ts
Known:
- 任務卡已 lock
- battle 端只能碰 interface,不可直連 ui 元件
- 目前 blocker 是橋接注入點還未補齊
Need:
- 補 bridge 注入點
- 用 focused validation 確認非法引用已清掉
Avoid:
- 不要重讀 keep.md 全文
- 不要擴到無關的 UI contract 檔案

我很喜歡這種摘要卡,因為它讓 handoff 的作用非常明確:不是把所有背景再講一次,而是幫下一位 Agent 限縮他該看的範圍。只要範圍被限縮,接手成本就會直接降下來,token 也不會一下子炸掉。

好的 handoff 長什麼樣子

檔案少、結論短、下一步清楚,並且明確告訴下一位不要重讀哪些大文件或 artifacts。

壞的 handoff 長什麼樣子

把 keep、manifest、QA notes、長 diff 全部貼上來。表面上很完整,實際上是把下一輪直接推進 hard-stop。

人類參與 AI 協作時,真正該扮演的角色

讀 Harness Engineering 時,我覺得最重要的一段提醒是:好的 Harness 不是為了把人類完全移出流程,而是把人類的注意力導向最有價值的地方。人類開發者帶進 codebase 的,不只是寫程式能力,還有品味、組織記憶、技術債取捨、產品目標,以及「這個團隊不會這樣做」的直覺。

Agent 沒有這些東西。它不會自然知道哪條慣例是 load-bearing,哪條只是歷史習慣;也不會知道某個 technically correct 的解法,是否符合我現在想讓 3KProject 走的方向。所以我後來把人類角色從「逐行檢查 Agent」改成「調校整個 Harness」。

Human Steering 目標、品味、取捨、例外批准 Guides 把經驗寫成入口規則、 任務卡、how-to、禁區 Coding Agent 執行局部任務、修正錯誤、 產出草案與 patch Sensors 用 type、lint、test、schema、 runtime smoke 回傳訊號 人類處理工具無法決定的部分 產品方向、技術債是否可接受、架構例外、語意曖昧、最終驗收標準
圖 5:人類不是被 Harness 排除,而是負責決定目標、調校 guides / sensors,並處理工具與 Agent 都無法可靠判斷的取捨。

人類不要一直做低階檢查

格式、schema、模組邊界、encoding、型別錯誤,這些應該交給計算型 sensors。人類一直手動檢查這些東西,只會讓協作成本卡在人工審查。

人類要負責調整系統

當同一類錯誤重複發生,我要做的不是罵 Agent,而是補 guide、補 sensor、補 fixture,或把某條規則前推到入口。

所以在 3KProject 裡,我希望自己扮演的是 steward,而不是人工 linter。Agent 負責局部執行,工具負責確定性檢查,人類負責方向、風險與例外。這樣多 Agent 協作才會越跑越穩,而不是把所有不確定性都丟回人腦。

最後我給自己的判斷準則

如果要用一句話講我現在對多 Agent 協作的理解,那就是:不要把協作寄望在大家都很聰明,而要把協作建立在任何人接手時都能立刻對齊的系統上。

在 3KProject 裡,我現在更願意把這套東西看成 Harness Engineering 的延伸。單一 Agent 的 Harness 解的是「怎麼讓模型少犯錯」,多 Agent 的 Harness 解的則是「怎麼讓多個人接力時,錯誤不會因為交接而放大」。

適合交給 Agent 的部分

需求拆解、局部修改、文件整理、語意歧義判讀,以及高階方案比較。

適合交給系統的部分

task lock、scope 管理、驗證順序、handoff 結構、context budget 與檔案邊界。

我現在不再把多 Agent 協作理解成「多開幾個聊天視窗」,而是把它理解成:我要先把 repo 的生命週期、執行順序與 guard 寫好,Agents 才會真的變成團隊,而不是一群彼此看不到彼此的臨時工。