Worktree 隔離
使用每個任務一個 git worktree 實現完整的程式碼隔離與事件串流。
你將學到什麼
當兩個代理同時編輯同一個檔案時,其中一個會輸。它們的變更會被覆寫,或者兩組變更合併成一團混亂。Worktree 隔離通過給每個代理自己完整的工作目錄來消除這個問題。
完成後,你將了解:
- 為什麼共享工作目錄會破壞多代理工作流程
- git worktree 如何提供每個代理的隔離
- Worktree 的生命週期:建立、工作、合併或丟棄
- 用於監控 worktree 活動的事件串流
- 未使用 worktree 的自動清理
問題是什麼
兩個代理在同一個版本庫上平行工作:
AGENT A: Adding authentication AGENT B: Adding logging
Creates src/middleware/auth.ts Creates src/middleware/logger.ts
Modifies src/app.ts ←──── CONFLICT ────→ Modifies src/app.ts
Modifies src/routes/index.ts Modifies src/config.ts
兩者都修改了 src/app.ts。沒有隔離的話,有三種可能的結果:
1. LAST WRITE WINS
Agent A writes app.ts with auth import
Agent B writes app.ts with logger import → auth import lost
2. READ-BEFORE-WRITE RACE
Both read the same version of app.ts
Both write based on that version → second write overwrites the first
3. MERGE CONFLICT
Both stage changes → git conflict markers → manual resolution needed
沒有一個是可接受的。根本原因:多個代理共享單一工作目錄。
如何運作
Git Worktree:一個 Repo,多個目錄
Git worktree 從同一個版本庫建立額外的工作目錄。每個都有自己的分支和檔案,但它們共享 git 歷史。
MAIN REPOSITORY WORKTREE: AGENT A
/project/ /project/.worktrees/agent-a/
├── .git/ ◀── shared ──▶ (branch: feat/auth)
├── src/ ├── src/ ← independent copy
├── tests/ ├── tests/
└── package.json └── package.json
WORKTREE: AGENT B
/project/.worktrees/agent-b/
(branch: feat/logging)
├── src/ ← independent copy
├── tests/
└── package.json
代理 A 和代理 B 都可以修改 src/app.ts — 它們各自在自己的分支上有自己的副本。
以 Worktree 隔離生成代理
當父代理以隔離方式生成子代理時,流程如下:
Parent Agent
│
├──▶ 1. CREATE git worktree add .worktrees/task-42 -b task-42
│ → new directory + branch created (fast, uses hardlinks)
│
├──▶ 2. SET CWD Child agent works in .worktrees/task-42/
│ Agent sees a normal project — doesn't know it's a worktree
│
├──▶ 3. WORK Child reads, writes, tests — all local to worktree
│ No impact on main directory or other worktrees
│
├──▶ 4. COMPLETE Child commits to branch task-42
│ Returns: { worktree_path, branch, files_changed }
│
└──▶ 5. DECIDE Parent merges branch → or discards worktree
子代理不需要特殊的感知。從它的角度來看,它在一個正常的目錄中工作。隔離對工作者是透明的。
完整生命週期
┌─────────────────────────────────────────────────────┐
│ CREATE │
│ git worktree add <path> -b <branch> │
│ Fast: hardlinks, not full copy │
│ │ │
│ ▼ │
│ WORK │
│ Agent operates in worktree directory │
│ All reads/writes isolated. Can run tests locally. │
│ │ │
│ ▼ │
│ EVALUATE │
│ git diff --stat → changes exist? │
│ ┌──────┴──────┐ │
│ ▼ ▼ │
│ MERGE DISCARD │
│ Merge branch Remove worktree │
│ into main Delete branch │
│ └──────┬──────┘ │
│ ▼ │
│ CLEANUP │
│ git worktree prune │
│ Remove directory, clean git references │
└─────────────────────────────────────────────────────┘
事件串流:監控活動
父代理通過事件監控 worktree 活動,而不破壞隔離:
Parent Agent (orchestrator)
│
├── AGENT A (worktree: feat/auth)
│ ├── event: file_created src/middleware/auth.ts
│ ├── event: file_modified src/app.ts
│ ├── event: test_run 3 passed, 0 failed
│ └── event: task_complete files_changed: 3
│
├── AGENT B (worktree: feat/logging)
│ ├── event: file_created src/middleware/logger.ts
│ ├── event: file_modified src/app.ts
│ └── event: task_complete files_changed: 3
│
└── MERGE DECISION
Both modified src/app.ts on different branches.
Git merge handles it if changes are on different lines.
If conflict: parent resolves with full context of both tasks.
事件只從子代理流向父代理。父代理觀察但不干預 — 在子代理工作時修改 worktree 會破壞一致性。
自動清理
沒有變更的 worktree 會被自動清理:
1. Worktree created for exploration task
2. Agent reads 20 files, concludes "no changes needed"
3. git diff --stat → empty
4. Automatic: git worktree remove + git branch -d
5. No branch, no directory, no mess
這防止了在包含許多平行代理的長時間會話中 worktree 的堆積。
關鍵洞見
Worktree 隔離是讓真正的平行開發成為可能的關鍵。它與 feature branch 是相同的概念,但應用在代理層級。
更深層的洞見:worktree 改變了協調模型。沒有隔離的話,代理必須即時協調(「不要碰 app.ts,我正在編輯它」)。有了隔離,代理可以自由工作,衝突在合併時一次解決。這是樂觀並行而非悲觀鎖定 — 它的擴展性更好,因為代理永遠不會互相阻塞。
實作範例
兩個代理平行實作功能,然後合併:
STEP 1: Create worktrees
──────────────────────────────────
git worktree add .worktrees/auth -b feat/auth
git worktree add .worktrees/logging -b feat/logging
STEP 2: Agents work in parallel
──────────────────────────────────
Agent A (in .worktrees/auth/):
Creates src/middleware/auth.ts
Modifies src/app.ts:
+ import { authMiddleware } from './middleware/auth'
+ app.use(authMiddleware)
Runs tests → pass
Commits: "feat: add authentication middleware"
Agent B (in .worktrees/logging/): ← simultaneous
Creates src/middleware/logger.ts
Modifies src/app.ts:
+ import { logger } from './middleware/logger'
+ app.use(logger)
Runs tests → pass
Commits: "feat: add request logging"
STEP 3: Merge results
──────────────────────────────────
git checkout main
git merge feat/auth → clean merge
git merge feat/logging → auto-merge (different lines of app.ts)
Final app.ts has BOTH imports. No manual conflict resolution.
STEP 4: Cleanup
──────────────────────────────────
git worktree remove .worktrees/auth
git worktree remove .worktrees/logging
處理合併衝突
當變更重疊時,父代理帶著上下文解決:
Agent A adds line 15: app.use(authMiddleware)
Agent B adds line 15: app.use(logger)
Parent reads conflict → understands both intents → resolves:
app.use(logger) ← logger first (every request)
app.use(authMiddleware) ← auth second (validates credentials)
隔離策略比較
No Isolation: instant setup, zero safety → single agent only
Worktree: fast setup (hardlinks), full file isolation → parallel agents
Full Clone: slow (copies repo), full isolation → untrusted agents
Container: slowest (OS-level), maximum isolation → untrusted code
Worktree hits the sweet spot: strong isolation with minimal overhead.
前後對比
| 共享工作目錄 | Worktree 隔離 |
|---|---|
| 代理互相覆寫 | 每個代理有自己的目錄 |
| 工作期間產生衝突 | 衝突在合併時解決 |
| 必須協調檔案存取 | 代理獨立工作 |
| 循序執行以避免碰撞 | 真正的平行執行 |
| 單一分支 | 每個代理一個分支 |
下一堂課
這完成了模組 2:多代理系統。你現在理解了任務圖、背景任務、團隊通訊、協定、自主代理和 worktree 隔離。
在模組 3中,我們轉向配置和擴展 Claude Code 的系統。第 13 堂課從控制協定開始 — 外部工具如何向 Claude Code 發送結構化命令並接收回應,實現 IDE 整合和程式化控制。