跳至主要內容
模組 2:多 Agent 6 / 6
中階 Session 12 Worktree Isolation Git

Worktree 隔離

使用每個任務一個 git worktree 實現完整的程式碼隔離與事件串流。

2026年3月20日 15 分鐘閱讀

你將學到什麼

當兩個代理同時編輯同一個檔案時,其中一個會輸。它們的變更會被覆寫,或者兩組變更合併成一團混亂。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 整合和程式化控制。