我原本只想搞懂 worktree,结果拆出了一套 Orca 多 Agent 并行栈
一篇AI总结的探索笔记。起点是一个很具体的问题:「Orca 里的 Git Worktree 到底是什么意思」;终点是一张从 Git 到进程的七层并行地图。中间绕了两个弯:代码不在本地,以及「能不能同时开两个 Claude」。
起因:一个仓库,四个实验,两个 Claude
事情的起点很朴素。我手上同时挂着几条互不相干的线:试一版新算法、优化一段性能、复现一篇文献、修一下分析脚本。
按以前的做法,这四条线很难一起做,做到一半大概率记不清哪些改动属于哪条线。后来听说 Orca 是每个任务一个 worktree,可以让多个 agent 同时干活。听起来正合我意,但我不确定自己是不是真的理解了 worktree。
所以我先问了最基础的那个问题。
第一站:worktree 到底是什么
我原以为「多开几个工作区」就是把仓库复制几份,但复制出来的东西是三个互不相关的仓库。后来发现 git worktree 是:同一个仓库,多份工作目录。
# 共享同一个 repository 的 Git 数据git worktree add ../project-a feature-agit worktree add ../project-b feature-b shared Git repository │ ┌────────────┼────────────┐ │ │ │ main WT feature WT test WT │ │ │ files A files B files C于是:
my-project/ -> mainmy-project-fix/ -> fix-bugmy-project-exp1/ -> experiment-1my-project-exp2/ -> experiment-2这四个目录共享同一套 Git objects 和 refs,但各自有独立的 HEAD、index 和真实工作文件。也就是说,my-project-fix/ 里 git commit 出来的东西,my-project/ 立刻就能 git log 看到,因为它们本来就是同一个仓库。也因为没有重复的 Git 数据,worktree 比 clone 更适合频繁创建临时开发环境。
另一个容易混的点:worktree 也不是 branch。
这两个词在日常语境里经常被混着用,但它们根本不在一个维度上:
- branch 是逻辑上的一条开发线,存在于 Git 内部(
main、feature-a); - worktree 是磁盘上真实存在的一个目录,存在于文件系统里。
它们通常是配对使用的:worktree A -> branch feature-a,worktree B -> branch feature-b。一句话概括就是:
branch 是这个分支的逻辑身份,worktree 是这个分支在磁盘上实际展开的那套文件。
想清楚这一点之后,Orca 的设计忽然就顺了。它基本可以浓缩成一行:
一个任务 ≈ 一个 worktree ≈ 一个 branch ≈ 一组 agent于是同一个仓库可以同时长成这样:
main│├── worktree: test-new-algorithm -> Codex Agent A├── worktree: optimize-performance -> Claude Agent B├── worktree: reproduce-paper -> Codex Agent C└── worktree: fix-analysis-script -> Agent D每个 agent 操作的其实是不同的目录,所以它们可以真的同时编辑 src/、跑 pytest、改 pyproject.toml、git commit,谁也不会踩到谁。
Orca 在 worktree 之上还加了一层东西。它替你做的不只是敲一句 git worktree add,一个 Orca worktree 同时还挂着一串状态:
Git worktree + branch + agent terminals + editor tabs + browser tabs + diff/review 状态 + UI 状态所以在 Orca 的语义里,worktree 更接近一个独立任务工作区,生命周期也完整得多:创建 -> 起 agent -> 改代码 -> review diff -> commit -> push -> PR/merge -> 删 worktree。而且删的时候它会处理对应 branch:如果还有未合并的 commit,它会保留并提示 review,而不是把成果直接扔掉。
顺手踩到的一个坑
新 worktree 是干净 checkout,.gitignore 里的东西默认不会跟过来:
.venv/ .env build/ data/ cache/对科研代码来说这挺要命:一个没有 .venv、没有本地配置的新 worktree,agent 一进去就跑不起来。Orca 为此提供了 Worktree Shared Paths、orca.yaml 里的 sharedDirectories,以及 .worktreeinclude,用来共享大型依赖目录或者复制本地配置。记住这三个词,后面在服务器上会再遇到它们。
第二站:代码根本不在本地
第一站的结论让我很兴奋,直到我意识到一个问题:我的项目在课题组的 Linux 服务器上。
一开始我下意识想的是「那就同步到本地再开 worktree 呗」。但这个思路很快就崩了:同步本身就是个持续性的麻烦,而且服务器上有 GPU、有数据、有 uv/micromamba 环境,本地同步过来也只是个残缺的副本。
真正需要区分的是两件事:
- Orca 本身跑在哪台机器上?
- worktree 创建在哪台机器的文件系统上?
想通之后答案其实很直接:让 Orca 在服务器上创建和管理 worktree。
Windows 本地└── Orca GUI │ SSH ▼Linux 服务器├── /home/mzhu/project/ # 原始 Git repo├── /home/mzhu/.../worktree-A/ # Orca 创建├── /home/mzhu/.../worktree-B/└── /home/mzhu/.../worktree-C/ │ ├── codex / claude / ai-cli ├── python └── uv / micromambaOrca 的编辑器、Diff、控制界面留在 Windows 上,但文件、Git worktree、agent 进程全部在服务器上。被 agent 修改的文件从来没有离开过服务器。
配置方式
在 Windows 版 Orca 里打开 Settings → SSH → Add Target:
Host: server.example.eduUser: mzhuPort: 22Identity file: C:\Users\<用户名>\.ssh\id_ed25519Orca 也能直接读你已有的 ~/.ssh/config,包括 Include、jump host / proxy 这些。如果你平时就是 ssh myserver,而 C:\Users\mzhu\.ssh\config 里有:
Host myserver HostName 123.45.67.89 User mzhu IdentityFile ~/.ssh/id_ed25519那么 Orca 里基本直接选 myserver 就行,点 Test 确认连通。
加项目的时候注意别选 Local,选 SSH → myserver,然后指到服务器目录:
/home/mzhu/projects/my-project这里有个细节值得记下来:普通远程文件夹也能打开,但worktree 功能要求它本身是 Git repository。
于是创建 worktree 时,真正发生的事是在服务器上:
服务器my-project/ mainworktrees/├── feature-a/ -> branch: feature-a├── feature-b/ -> branch: feature-b└── feature-c/ -> branch: feature-c而不是在 C:\... 下。Agent 也一样,SSH worktree 里的 terminal 调用的 codex、claude、python、uv、micromamba 全是服务器上那一份,跟 Windows 上装没装没关系。
这里还有一个我一开始想绕、后来发现完全没必要的弯:Windows Orca -> WSL -> SSH -> Server。既然项目本来就在服务器上,直接 Windows Orca -> SSH -> Linux Server 干净得多。
不过这里有个我一开始没算到的门槛:服务器端得先把东西装齐。 SSH 连得上不等于能用,worktree 里要跑的 agent CLI、python、uv/micromamba 环境,都得在服务器上一个个装好、配好。如果服务器权限受限,或者你只是临时想试一下,这个前置成本可能比想象中高,甚至高到不值得。这一段我一开始讲得太轻巧了。
数据目录绝对不能复制
这是我在这一步最警惕的地方。假设仓库长这样:
project/├── src/├── scripts/├── data/ # 500 GB├── trajectories/ # 2 TB└── results/如果 worktree 各复制一份,那三个 worktree 就是 6 TB。好在 Git worktree 只 checkout Git tracked 文件,所以只要一开始就把代码和数据分开:
/home/mzhu/project/ # 代码,进 Git src/
/data/group/my-datasets/ # 数据,不进 Git trajectories/ datasets/ simulations/代码里通过 DATA_ROOT=/data/group/my-datasets 访问,于是:
worktree-A ─┐worktree-B ─┼──→ /data/group/my-datasetsworktree-C ─┘几个 agent 共享 TB 级数据,每个 worktree 只复制几十 MB 源码。至于那些 gitignored 的缓存和依赖目录,就交给第一站里记下的 sharedDirectories / Worktree Shared Paths。
到这里,我脑子里已经有一套完整的架构了:
Windows└── Orca │ SSH ▼Linux 服务器├── ~/projects/my-project # main repo├── Orca worktree: feature-a -> Claude / Codex├── Orca worktree: feature-b -> Claude / Codex├── Orca worktree: feature-c -> Claude / Codex└── Orca worktree: validation -> Claude / Codex
共享: /data/... ~/.cache/... micromamba env uv cache还有一个意外收获:SSH worktree 的远程 terminal session 有恢复机制。笔记本断网或者 Orca 关掉之后,远程 agent session 可以继续存在,重连时 Orca 会尝试恢复 terminal 和 scrollback。对长时间跑的科研任务来说,这一点比想象中重要。
第三站:那能同时开两个 Claude 吗
能,而且这本来就是 Orca 常见的用法。最推荐的形态:
repo├── worktree-A -> Claude Code #1└── worktree-B -> Claude Code #2两个 Claude 从同一个 main 出发,各走一条 branch。比如让它们解同一个问题但给不同策略:
Claude #1: "尝试从算法复杂度和数据结构方向优化性能"Claude #2: "保持算法不变,只从 NumPy/Numba/并行化角度优化"跑完之后分别看两个 worktree 的 diff,再决定 cherry-pick 哪个。这种「同题并行比较」是 Orca 官方推荐的 workflow。
按角色分工
对科研场景,我更倾向于按角色分工,而不是按数量堆:
研究问题├── Claude A -> 理论/算法方案 A├── Claude B -> 理论/算法方案 B├── Codex A -> 独立实现 / code review└── Claude C -> 测试、验证、找反例Orca 的价值在于让两个 Claude 在隔离的 worktree 里并行探索,同时打开两个只是顺带的结果。
第四站:把「并行」拆成七层
走到这里我发现,前面所有讨论都挤在「并行」这一个词里,其实它们根本不是一回事。按「谁有独立上下文、谁能改同一份代码、谁负责协调」,能拆成七层:
Level 0 Machine / SSH hostLevel 1 Git Worktree 文件 + branch 隔离Level 2 Agent Session Claude / Codex 独立上下文Level 3 Agent Team 多个完整 agent 协作Level 4 Subagent 临时子任务 workerLevel 5 Parallel Tool Calls 一次并发多个 read / grep / bashLevel 6 OS Process Python / pytest 进程| 层级 | 典型对象 | 独立上下文 | 文件隔离 | 谁协调 | 适合什么 |
| | | : | : | | |
| Worktree | method-A, method-B | ✅ | ✅ 强 | 你 / Orca | 不同方案、不同 branch |
| Agent Session | Claude #1 / Claude #2 | ✅ 强 | ❌ 同 WT 时共享文件 | 你 | 独立长任务 |
| Agent Team | lead + teammates | ✅ 每个 teammate | 通常 ❌ | Lead Claude | 多角色协作 |
| Subagent | research / debug / test | ✅ 临时/局部 | ❌ | Parent Agent | 快速委派子问题 |
| Parallel tools | grep / read / bash / test | ❌ 主要共享父上下文 | ❌ | 模型 | 小粒度加速 |
| Processes / jobs | Python / pytest | 进程级 | 取决于目录 | shell | 真正计算并行 |
真正值得分清的是 Level 1 到 4 这四层:
- Worktree 隔离文件。每个 worktree 一套 branch 和磁盘文件,不同方案各占一个,互不干扰。官方推荐的用法就是同一 prompt 发到 3 个 worktree,跑完比 diff。
- Agent Session 隔离上下文,不隔离文件。同一 worktree 里跑两个 Claude,各有各的 conversation 和 context window,但改的是同一批磁盘文件。
- Agent Team 是协作。一个 Lead 拆任务、派发、收拢,几个并列的 teammate 各管一块(API / tests / docs),teammate 是长期、完整的协作者。
- Subagent 是委派。主 Claude 把局部独立问题甩出去,拿结果回来,不新开 workspace。打个类比:Agent Team ≈ PI + 几个研究生,Subagent ≈ 一个研究生临时派几个 research assistant。
后两层已经不是 AI agent 并行,而是被 agent 调用的并行:Parallel Tool Calls 是一个 Claude 同时读多个文件、跑多个 grep;OS Process 是它提交一批独立 Python 进程同时跑。这时 AI 并没有那么多个 agent,只是 1 Claude -> 一次提交 -> N 个进程,和自己那套并行概念要分开。
收尾
对科研场景,好用的是一个三尺度设计:
研究路线级 -> Worktree复杂任务级 -> Agent / Agent Team局部调查级 -> Subagent如果只记一句话:
Worktree 用于「竞争 / 独立路线」;Agent Team 用于「合作」;Subagent 用于「委派」。
由此推出的两条反直觉结论:
- 不要用 Agent Team 替代 worktree 隔离。 想让 Claude A 和 Claude B 独立实现同一个算法再比谁更好,就该开两个 worktree,而不是塞进同一个 Team。Team 的成员是协作关系,不是竞争关系。
- 也不要为了并行而并行。 理论上确实可以做到
3 worktrees × 每 WT 1 team × 每 team 3 teammates × 每 teammate 若干 subagents,但这不是越多越好。真正该先回答的问题是:在哪一层拆任务。
还有点问题
- 服务器端的安装成本。 Remote Worktree 要求服务器上装好一堆 agent CLI 和运行环境,权限受限或者只是临时试用时,这一步很容易劝退。它值不值得,取决于你是不是真的长期在这台服务器上开工,而不是偶尔连上去跑一下。
- Agent Team 目前默认关闭,需要手动在设置里开启。它在长任务里的实际稳定性,我还没有体感。
- 额度是共享的。 多个 Claude session 并行很好看,但 rate limit 是同一个账号的。多账号 hot-swap 能缓解,不能消除。
- worktree 的数量不是免费的。 每个都是完整 checkout,仓库一大、依赖一多,磁盘和
uv/micromamba环境的复用策略需要专门设计,sharedDirectories能覆盖一部分,但不是全部。 .worktreeinclude该包含什么,其实取决于哪些文件是「环境」、哪些是「状态」。这条线我还没划清楚。