最近一段时间我一直在折腾并行 AI Agent 编程。手头一个大仓库想让 Claude Code 和 Codex CLI 同时干活一个改登录鉴权一个做接口缓存另一个去优化前端构建脚本。理论上很美好实际一把梭下来全是坑——同一份工作目录里两个 Agent 会互相覆盖改动A 刚把依赖升级B 这边测试就挂了更别提谁动一下根目录配置另一个人直接崩盘。后来我把目光转向了 Git Worktree一开始还觉得它是个老古董功能用上手才发现这玩意儿简直是给 AI 编程时代准备的。今天要聊的 Worktrunk就是我围绕 Git Worktree 写的一个管理 CLI专门用来调度并行 AI Agent 工作流。不管你是用 Codex CLI、Claude Code、Trae CLI还是自己写基于 Agent 的自动化脚本只要你有同一个仓库多任务并发改代码的需求这篇文章都值得看完。我会把工具的设计思路、安装使用、实际跑通的三路并行案例以及我踩过的那些坑全部摊开讲。内容比较实操建议你打开终端边看边试。1. 为什么 AI Agent 写代码时目录会变成单行道先说结论绝大多数 AI 编程工具本质上就是一个能自主读文件、改文件、跑命令的进程它们消灭了键盘输入的人工成本却没有消灭文件系统层面的冲突。你让两个 Agent 在同一个工作目录里同时改代码就像把两个人塞进同一间办公室共用一张桌子不是不能干活是效率极低。1.1 单目录并行的三个痛点痛点一是文件互踩。Agent A 正在读api/client.ts准备加上重试逻辑Agent B 拿到同一份文件把超时时间从 3000 改成 5000保存。A 这边再写的时候基于的内存快照已经过期一提交就把 B 的逻辑覆盖了。这种情况在真实协作里几乎无解因为两个 Agent 之间没有天然的文件锁你也不可能给每个 AI 工具都加上别人正在编辑请等一等的通知机制。痛点二是依赖和构建产物互相污染。同一个node_modules、同一个target、同一个dist目录两个 Agent 同时在装依赖、跑测试结果就是共享缓存被写乱编译报错还会互相甩锅。我在第一次实验里就遇到过Agent A 把lodash从 4.x 升到 5.xAgent B 那边的单测立刻全红但它自己完全没动过依赖。痛点三是 Agent 会话的上下文污染。并行任务一旦共用一个工作区Agent 读取README、读AGENTS.md、扫全仓库文件时看到的改动可能是另一个任务写了一半的状态。这种情况下即使文件内容没有崩溃Agent 也会产生错误判断把别人没写完的代码当成既有逻辑去推导产出的方案经常驴唇不对马嘴。1.2 Git Worktree 为什么是对的方向Git Worktree 是 Git 2.5 引入的功能允许你在同一个仓库上创建多个工作目录每个目录可以检出不同的分支。原理上多个 worktree 共享同一个.git对象数据库但拥有各自的HEAD、索引文件和工作区文件。也就是说你在worktree-A里提交的分支对象在worktree-B里git log也能看到但两边改的文件互不干扰。这个特性对并行 AI Agent 工作流来说几乎是量身定做每个 Agent 住进一个独立的房间房间里有自己完整的代码副本和分支可以随便改、随便测、随便提交不会碰到其他 Agent 的桌子。等到任务完成再把分支合回主干。Git 的对象数据库共享机制还保证了集成时历史是连贯的不会出现两套独立仓库最后对不上的问题。但 Git 原生的 worktree 命令有几个现实局限。第一它只管创建目录和分支不管任务映射时间一长你根本记不住.worktrees/whatever对应的是哪个需求。第二它没有清理策略合并完分支之后 worktree 一个个堆在那里磁盘白白浪费。第三也是最重要的一点它没有为 AI Agent 场景做任何优化不会自动生成任务上下文、不会帮你规划并行启动流程、也不提供在指定 worktree 里跑 Agent的快捷方式。1.3 Worktrunk 的定位补齐 Worktree 的最后一公里Worktrunk 的定位很简单它是一个夹在 Git 和 AI Agent 之间的管理中间层。解决的问题是从你拿到一个需求到 Agent 真正开始写代码之间那一大段杂事——建分支、建目录、写任务说明、规划并行方式、最后合并清理。具体来说Worktrunk 做三件事把任务名、分支名、worktree 路径做成一个稳定映射为每个任务生成一份标准化的上下文文件让 AI Agent 一进目录就知道自己要干什么提供一套精简的命令集把git worktree add、git merge、git branch -D这些底层操作封装成对任务进行操作的高层指令。如果你只是偶尔开一两个 worktree手动敲 Git 命令完全够用。但如果你打算同时开五六个 Agent让它们像一个小团队一样并行推进需求没有一个统一调度入口很快会失控。Worktrunk 就是为了这个场景写的。2. 核心设计从任务到目录再到合并的一整套映射设计这个工具时我最优先想清楚的是一件事任务生命周期和 Git 对象的对应关系。一个任务从创建到合并要经过编号-分支-目录-上下文-状态-合并-清理这么一长串环节每一环都要有明确的命名规则和存储位置否则工具本身就会变成新的混乱源。2.1 任务与分支的命名规范我先定了一套非常严格的命名规则。任务名一律小写单词之间用连字符分隔例如fix-login-timeout、add-api-cache。分支名按照wt/{taskId}的格式生成例如wt/fix-login-timeout。worktree 路径则统一放在仓库根目录下的.worktrees/{taskId}/目录中。这套规则解决了三个问题第一可追溯性——看到分支名或目录名你能立刻知道这是哪个任务第二可清理性——所有 worktree 都在一个固定前缀目录里worktrunk prune可以安全遍历第三可排序性——wt/前缀让这些任务分支在git branch列表里聚在一起不会和手工分支混成一团。创建任务的命令长这样worktrunk add --name fix-login-timeout --desc 解决登录接口偶发超时 --base main这条命令背后做了一系列操作在.gitignore中追加.worktrees/、执行git worktree add .worktrees/fix-login-timeout -b wt/fix-login-timeout main、在该目录下写入AGENTS.md任务上下文、最后在.wt/manifest.json里登记一条任务记录。你不需要关心底层细节它全帮你搞定。2.2 状态清单与任务上下文Worktrunk 的调度核心是一份 JSON 清单文件默认放在仓库根目录的.wt/manifest.json里。每个任务在清单中占一条记录包含任务名、描述、分支名、路径、基于分支、创建时间、状态、以及最后负责的 Agent 工具名。{ taskId: fix-login-timeout, description: 修复登录接口偶发超时问题, branch: wt/fix-login-timeout, path: .worktrees/fix-login-timeout/, base: main, createdAt: 2025-06-10T10:00:00Z, status: in-progress, agent: codex }状态字段目前支持pending、in-progress、ready、merged、aborted五种。worktrunk list会读取这份清单并渲染成表格你可以一眼看出哪个任务在跑、哪个合并完了、哪个被废弃了。任务上下文文件是另一个关键设计。Worktrunk 会在每个 worktree 里生成一份AGENTS.md内容直接照抄当前任务的目标、影响范围和验收标准。AI 编程工具基本都支持自动读取这类文件Agent 一进入工作目录就能拿到我是谁、我要干什么、我不能碰什么的完整说明不需要你在对话里反复粘贴需求也不会出现两个 Agent 互相改错领域的情况。2.3 CLI 命令集Worktrunk 的命令集刻意保持精简核心命令一共九条覆盖任务从生到死的全部环节。命令作用示例worktrunk init初始化仓库创建.wt目录结构worktrunk init --remote originworktrunk add为任务创建 worktree 和分支worktrunk add -n fix-login-timeout -b mainworktrunk list查看所有任务状态worktrunk list --status in-progressworktrunk switch在 worktree 间切换目录worktrunk switch fix-login-timeoutworktrunk exec在指定 worktree 中执行任意命令worktrunk exec fix-login-timeout -- pnpm testworktrunk sync将基线分支最新代码同步到各 worktreeworktrunk sync --allworktrunk merge将任务分支合并回基线并删除分支worktrunk merge fix-login-timeout --base mainworktrunk prune清理已合并或废弃的 worktreeworktrunk prune --mergedworktrunk import接管手动创建的 worktree 目录worktrunk import --path .worktrees/legacy-a这里我要特别解释一下worktrunk exec的设计。它的本质是在指定 worktree 路径下启动一个子进程把命令原样透传给 shell。但它在透传之前会先检查该 worktree 是否存在、状态是否正常、目录是否可写并且在命令执行期间锁定任务的status防止另一个终端同时对该任务做 merge 或 prune。这个细节在手动使用 Git worktree 时容易被忽略但一旦并行任务多起来你正在跑测试另一个终端把 worktree 删了这种事故是真实会发生的。3. 快速上手十分钟搭起第一套并行 Agent 流水线我假设你已经有一台装了 Node.js 16 的电脑并且本机有 Git 2.30 以上的版本。Worktrunk 目前通过 npm 包分发安装命令npm install -g worktrunk安装完成后进入你的项目仓库先初始化。Worktrunk 会检查当前目录是不是一个合法 Git 仓库并在根目录创建.wt/和.worktrees/两个目录。注意.worktrees/会自动写入.gitignore因为你绝对不希望 worktree 里的代码副本被当成普通源码提交。cd ~/projects/monolith worktrunk init --remote origin首次运行会看到一条提示告诉你默认忽略规则已写入.gitignore同时确认当前基线分支为main或master。如果仓库有多个长期分支你可以在后续 add 时通过--base单独指定。3.1 一个任务对应一个工作区接下来我们一口气创建三个任务模拟真实的三路并行场景。假设我手上的需求是修复登录接口超时、给查询接口加缓存、优化前端构建脚本。三条命令如下worktrunk add --name fix-login-timeout --desc 修复登录接口偶发超时 --base main worktrunk add --name add-api-cache --desc 给查询接口添加Redis缓存 --base main worktrunk add --name optimize-build --desc 把前端构建改为并行任务 --base main每执行一条终端都会输出新 worktree 的路径、分支名和生成的AGENTS.md路径。三秒左右你的磁盘上就多出了三份独立的代码副本。用worktrunk list看一下整体状态worktrunk list输出会是一张表格列名分别是任务名、分支、状态、路径、Agent。此刻三个任务都是pending路径分别是.worktrees/fix-login-timeout/、.worktrees/add-api-cache/、.worktrees/optimize-build/。3.2 并行执行怎么让多个 Agent 一起开工任务创建完之后并行启动的关键一步来了。我先给每个 worktree 预装一次依赖这一步强烈建议在 Agent 干活之前做否则多个 Agent 同时跑包管理器会互相抢锁worktrunk exec fix-login-timeout -- pnpm install worktrunk exec add-api-cache -- pnpm install worktrunk exec optimize-build -- pnpm install依赖装完后就可以分别启动 Agent。以 Codex CLI 和 Claude Code 为例实际命令以你本机安装的工具为准worktrunk exec fix-login-timeout -- codex exec 修复登录接口超时问题验收标准见 AGENTS.md worktrunk exec add-api-cache -- claude -p 给查询接口添加Redis缓存改动范围限定在service层 worktrunk exec optimize-build -- codex exec 把前端构建改为并行任务参考 AGENTS.md三个进程同时跑在三份独立目录里互相看不见对方的改动也就不会产生文件覆盖和上下文污染。你可以打开三个终端窗口分别观察每个 Agent 的执行日志。这时候worktrunk list会显示任务状态逐渐变成in-progress非常直观。3.3 查看状态、提交与切换并行运行期间我习惯用worktrunk list来当仪表盘。如果某个任务已经完成Agent 会在 worktree 里做好提交此时你可以进目录人工检查产物或者直接跑一遍测试worktrunk exec fix-login-timeout -- pnpm test如果测试通过就进入集成环节。worktrunk switch fix-login-timeout会在当前终端里切换目录——这个命令的实现有点小心思因为实际切换目录必须由当前 shell 来执行Worktrunk 的 switch 子命令本质上会输出一行cd /absolute/path/to/worktree让你复制执行或者你直接cd .worktrees/fix-login-timeout一回事。我更喜欢直接用worktrunk exec因为它不改变终端状态尤其是跑 Agent 这种长任务时切换目录反而容易把后续命令发错位置。4. 并行工作流实战三路 Agent 并发改同一个仓库理论说完了下面我用一个真实跑通过的项目来演示完整流程。这个项目是一个典型的 Web 后端加前端工程代码量中等涉及 auth 模块、service 层和构建配置。我把三个任务拆给三个 Agent目标是同一个小时内全部合并回主干。4.1 任务拆解与依赖识别任务拆解是决定并行成败的关键环节。我的判断标准很简单两个任务之间不能有同一个文件的修改交集否则无论 worktree 怎么隔离合并时还是会冲突。任务 Afix-login-timeout改动范围在src/auth/、src/api/handler/auth.go目标是修复登录接口偶发超时。任务 Badd-api-cache改动范围在src/service/query.go、src/cache/redis.go目标是给查询接口加 Redis 缓存。任务 Coptimize-build改动范围在webpack.config.js、.github/workflows/build.yml目标是构建脚本并行化。三个任务在文件层面没有直接交集但它们有一个隐藏依赖都依赖package.json的依赖列表。如果 Agent A 顺手升级了某个包Agent B 的测试就会受影响。解决办法是在拆解阶段就定死依赖锁定规则——谁都不许改package.json里的版本号需要新依赖就单独提任务。我把这条规则写进每个AGENTS.md的约束栏里。4.2 并行运行记录创建好三个 worktree 并预装依赖后我同时启动了三个 Agent 终端。大约运行到第 12 分钟时worktrunk list显示add-api-cache已经把状态推成readyAgent B 在日志里报告缓存已加上单测通过。又过了 5 分钟fix-login-timeout也进入ready但 Agent A 提示登录接口的单元测试在本地跑通了集成测试没有跑因为集成测试需要启动数据库容器。optimize-build用时最长因为它要同时改 webpack 配置和 CI 文件Agent C 中途主动检查了两次构建产物确认输出正常后才提交。这里我观察到一个小规律给 Agent 的验收标准越具体它自己主动做验证的次数就越多。这个在AGENTS.md里写清楚验收标准比在对话里反复要求你要测试哦有效得多。4.3 集成合并与冲突处理三个任务都进入ready后我开始逐个集成。Worktrunk 的合并策略是先预检再合入避免直接把冲突炸到主干上worktrunk merge add-api-cache --base main --check-first--check-first参数会先用git merge-tree在后台模拟一次合并输出可能冲突的文件列表但不会真正改动工作区。如果检测到冲突终端会列出冲突文件和涉及的两个分支并建议你先人工查看。如果没检测到冲突它会真正执行git merge把任务分支合并到main然后询问是否立即清理该 worktree。三个任务里add-api-cache和optimize-build都是零冲突直接合入。fix-login-timeout出现了意外——它虽然没改package.json但src/api/handler/auth.go和src/api/handler/query.go在文件头部有一段公共的import区任务 B 在缓存改造时新增了一个依赖导入导致两个任务的变更在同一行上产生了冲突。这种我没有碰这个文件但文件头被改了的情况在并行开发里很常见。解决办法也简单先开一个终端人工处理冲突只保留两个任务的变更集合然后worktrunk merge继续执行。整个集成过程大概花了十分钟比单 Agent 串行做完三个任务至少省了一半时间。5. 常见问题与排查技巧实录工具用得越深踩的坑越有参考价值。我按实际频率排了个序把 Worktrunk 使用中容易遇到的问题整理成了下面的速查表。问题现象可能原因解决办法worktrunk add报分支已存在之前创建过同名任务或手工建过同名分支用git branch -D wt/xxx删除旧分支或改用worktrunk import接管worktrunk list不显示某个 worktree用原生git worktree add手动创建的目录没登记进 manifest执行worktrunk import --path .worktrees/xxx多个 worktree 下依赖安装重复工作区独立node_modules不会共享用 pnpm workspace 配合 symlink或接受首次安装成本Agent 改了根目录公共配置AGENTS.md没写清约束在AGENTS.md增加禁止改动清单必要时用文件权限隔离worktrunk prune删除失败目标目录下有进程占用Agent 或 shell 未退出先退出该 worktree 下所有进程再重试worktrunk sync中断某个 worktree 有未提交的本地改动先执行worktrunk exec 任务名 -- git add -A git commit合并时检测到不相关文件冲突两个任务同时改了公共文件头部或 import 区人工合并冲突只保留合理变更集不要无脑--ours磁盘空间快速膨胀worktree 共享对象库但工作区独立构建产物也独立定期worktrunk prune --merged并把构建产物目录加入.gitignore5.1 最容易踩的坑依赖安装和构建产物我最早踩的坑是并行跑pnpm install。三个 worktree 同时安装依赖pnpm-lock.yaml互相对不上最后两个 Agent 的测试全挂了。后来我改成先在所有 worktree 里预装依赖再启动 Agent并且严格禁止 Agent 修改依赖版本这条规则至今没再出过问题。构建产物的坑更隐蔽。.worktrees/目录最初放在仓库根目录下结果某个前端项目的 webpack 配置把整个根目录当成了内容目录构建时把其他 worktree 的源码也一并打包进去了。我当时的修复方案是两层第一层把.worktrees/路径加进.gitignore和构建工具的排除列表第二层调整项目结构把.worktrees/放到仓库外部。Worktrunk 目前默认生成时自动在.gitignore里追加忽略规则但如果你的项目构建工具不看.gitignore还是要自己处理。5.2 一个值得长期保留的技巧AGENTS.md 的写法任务上下文文件写得好不好直接影响 Agent 产出的质量。我的模板固定包含五个部分任务描述、影响范围、验收标准、约束条件、参考资料。影响范围写得越具体Agent 越不会越界乱改约束条件越明确越少出现把整个项目格式化一遍这种低级事故。我见过很多同学在AGENTS.md里只写一句修复登录超时问题结果 Agent 进来之后不知道改哪个文件也不知道怎么算完成最后照着错误路径写了一堆无用代码。任务上下文本质上就是给 Agent 的产品需求文档你给它信息越充分它回来的结果越可靠。6. 与 AI Agent 工具链的深度配合Worktrunk 本身不绑定任何具体 Agent 工具它只提供一个独立目录和一份任务上下文剩下的事情由你手头的 Codex CLI、Claude Code、Trae CLI 或者自研 Agent 脚本来完成。这个设计是刻意的——AI 编程工具迭代太快绑定任何一家都有风险。6.1 和主流 CLI 工具的对接方式以 Codex CLI 为例它的执行模式基本是在当前目录里接受指令并开始自主编码。Worktrunk 的做法是先把你送进目标 worktree再启动 Codex让它认为自己在独立仓库里干活worktrunk exec fix-login-timeout -- codex exec 修复登录接口超时验收标准见 AGENTS.mdClaude Code 的调用逻辑也类似但它的会话恢复能力更强。你可以在同一个 worktree 里反复启动 Claude Code让它读取上一次的对话记录继续干活。这种情况下Worktrunk 的价值在于你不用担心这个会话对应哪个目录——任务和目录的映射是确定的你只要把worktrunk exec的命令交给自动化调度平台就行。6.2 在自动化流程里用 Worktrunk 做任务分发如果你想做更复杂的任务编排比如接一个 Webhook 进来自动把需求拆成任务并按顺序分发给不同 AgentWorktrunk 的命令集很适合当底层调度原语。它的add和exec都是无状态命令你可以在任意一个自动化平台比如 n8n 或者自己写的任务队列里这样组合worktrunk add --name $TASK_NAME --desc $TASK_DESC --base main worktrunk exec $TASK_NAME -- codex exec $TASK_PROMPT worktrunk merge $TASK_NAME --base main --check-first --auto-clean这个流程对应的就是一条完整的需求生命周期创建任务、执行任务、验证并合并。你只需要在前面接一个任务拆解模型后面接一个通知机器人就成了一台非常简陋但能跑的并行 AI 开发流水线。我自己实测过这种流水线处理改 10 个不相关接口加日志之类的机械任务效率提升非常明显。6.3 工具可以扩展的方向Worktrunk 目前还很年轻我后续计划加的功能包括远程同步把清单文件推送到远端仓库让团队其他人也能看到任务状态工作流插件定义每个任务必须跑lint和test才能合并这样的规则Agent 报告自动沉淀把每个任务对应的 Agent 输出保存成文档方便回溯。不过就算不加这些功能光是把 worktree 管理从 Git 底层命令变成任务级操作这一点就已经解决了并行 AI Agent 工作流中最让人头疼的目录混乱问题。工具不一定要大而全把一个点的体验做透价值就出来了。最后分享一个我实际操作中的体会并行 AI Agent 工作流能不能跑起来工具只占一半另一半是任务拆解的纪律性。文件改动的交集越小Agent 之间的耦合越少worktree 的优势就越明显。反过来如果你拆出来的任务大量共享同一个文件再好的隔离机制也只能做到不互相踩脏工作区合并阶段照样一地鸡毛。我的建议是先用 Worktrunk 跑一个改动范围完全隔离的实验任务比如给模块 A 加接口日志和给模块 B 修一个空指针跑通一次之后再慢慢增加任务之间的重叠度。等你能顺畅处理有公共文件交集的并行任务时这套工作流才算真正上手了。