不同 agent 不要抢同一棵树
「Isolate by directory, coordinate by task ID.」两个平面,互不打扰。
并行 agent 的一个难题
s09-s11 让你能同时启多个 teammate,但有个暗坑:他们都在同一个工作目录里。alice 改 auth.py、bob 同时也在改 auth.py——git 冲突、文件错乱、测试互相污染。
s12 的解法是 git worktree:同一个仓库,通过 git worktree add 可以在不同目录里 checkout 不同分支。每个 agent 拿到自己的 worktree,在自己的目录里干活,互不可见。
my-repo/ # 主工作区(lead 用) .worktrees/ alice-auth/ # alice 的隔离目录 (branch: wt/alice-auth) bob-api/ # bob 的隔离目录 (branch: wt/bob-api) index.json # worktree 注册表 events.jsonl # 生命周期事件日志
两平面分工
s12 把系统显式地拆成两个平面:
- 控制面 (control plane):
.tasks/里的 JSON 文件。task 是「要做什么」的抽象单位,有依赖、owner、status。 - 执行面 (execution plane):
.worktrees/里的目录。worktree 是「在哪儿做」的物理容器,一个目录 + 一个分支。
两者通过 task.worktree 和 worktree.task_id 双向绑定。
这种解耦让你可以:复用 task 管理机制但换执行环境(比如不是 git worktree,而是 docker 容器)。或者换 task 机制但复用 worktree(比如不是 JSON 文件而是数据库)。
生命周期演示
下面完整走一遍:create task → create worktree → run commands → keep 或 remove。每步都有事件日志记录(events.jsonl),production 里靠它做可观测性。
keep vs remove
worktree 完成使命时有两个终局:
remove:git worktree remove --force,目录删除。分支一般也会被清理。相当于「这个探索不要了」。keep: 只在.worktrees/index.json里标status: kept,物理目录保留。相当于「这个结果要了,等我合并」。
常见模式:subagent 跑一个实验性 refactor → 跑出来效果好 → keep → 人类 review → 合入主分支 → 手工 remove。效果差?直接 remove 丢掉。