Git Worktree 多 Agent 并行开发实战
Git Worktree 多 Agent 并行开发实战:3 个 Agent 同时写代码,为什么最后还是合不起来?
三个 Agent 同时开工后,我第一次感受到 AI 编程从“更快的助手”变成了“小型开发团队”。但几十分钟后,我也收到了三份互相打架的代码。
一个 Agent 写登录接口,一个 Agent 做登录页面,另一个 Agent 补自动化测试。三个终端同时滚动,原本需要排队完成的任务开始并行推进——这种感觉确实很爽。
问题出现在合并阶段。
后端返回的是 access_token,前端读取的却是 token;测试 Agent 根据旧接口写了断言;两个分支还同时修改了公共路由文件。Git 只提示了一处文本冲突,剩下的问题直到端到端测试失败才暴露。
这正是多 Agent 编程最容易被忽略的一面:
并行执行不等于并行交付。Git Worktree 解决了工作目录隔离,却不会自动解决任务拆分、接口设计和系统集成。
下面用一个可复现的小项目,完整搭建三 Agent 并行工作流,并拆解合并阶段最常见的四类冲突。
一、为什么要让 3 个 Agent 同时写一个项目
假设我们有一个使用 Node.js、TypeScript 和前端框架构建的 Web 应用,现在需要增加登录功能:
- Agent A:实现后端登录接口;
- Agent B:实现登录页面与请求逻辑;
- Agent C:编写接口测试和端到端测试。
如果交给一个 Agent 串行完成,它通常要依次阅读后端、修改接口、切换到前端、补页面,再回头写测试。
这种方式有三个明显问题:
1. 任务必须排队:前端和测试只能等待后端完成;
2. 上下文不断膨胀:Agent 既要记住接口设计,又要理解页面状态和测试框架;
3. 单点阻塞严重:某个模块报错,后续任务都可能暂停。
Git Worktree 提供了另一种思路:让同一个 Git 仓库同时检出多个工作目录,每个目录绑定一条独立分支。
主仓库 main
├── ../project-auth → agent/auth
├── ../project-ui → agent/ui
└── ../project-test → agent/test
它不是简单复制三份项目。多个 Worktree 共享同一个 Git 对象数据库,但拥有彼此独立的工作区和分支。
这意味着 Agent A 修改后端文件时,不会覆盖 Agent B 正在编辑的前端代码;Agent C 也可以独立运行测试、提交代码。
Worktree 隔离的不是模型,而是它们的“办公桌”。截图建议一:展示 git worktree list 输出,隐藏本地用户名、绝对路径和仓库地址。
二、从零搭建 3 Agent 并行工作流
1. 检查主分支
开始前,先确保主分支已经同步,并且没有未提交修改:
git switch main
git pull
git status
如果 git status 显示工作区不干净,应先提交、暂存或丢弃相关修改。不要带着半成品创建多个 Worktree,否则每个 Agent 的起点都可能不一致。
2. 创建三个 Worktree
git worktree add ../project-auth -b agent/auth
git worktree add ../project-ui -b agent/ui
git worktree add ../project-test -b agent/test
git worktree list
随后分别进入三个目录,在三个终端中启动你使用的编程 Agent:
cd ../project-auth
启动 Agent A
cd ../project-ui
启动 Agent B
cd ../project-test
启动 Agent C
具体启动命令可以来自不同工具,Worktree 的隔离逻辑不变。你甚至可以让不同模型分别负责后端、前端和测试,但不要把“选择哪个模型”和“如何隔离代码”混为一谈。
截图建议二:三个终端窗口并排展示 Agent 同时工作,注意隐藏 API Key、Cookie 和系统路径。
3. 不要只给一句“帮我完成登录功能”
多 Agent 协作最危险的做法,就是让三个 Agent 自由发挥。
每个 Agent 都应该收到一张结构一致的任务卡,至少包括:
- 当前分支;
- 任务目标;
- 允许修改的目录;
- 禁止修改的公共文件;
- 输入输出协议;
- 验收命令;
- 提交要求。
Agent A 的任务卡可以这样写:
你当前位于分支 agent/auth,只负责后端登录接口。
允许修改:
- src/server/auth/**
- tests/auth/**
不要修改:
- package.json
- package-lock.json
- 数据库公共 Schema
- 前端目录
- 公共路由入口
接口约定:
POST /api/login
输入:{ email, password }
成功返回:{ token, user }
认证失败返回 HTTP 401
完成后:
1. 运行后端相关测试
2. 总结修改文件和设计决策
3. 创建一次 Git commit
Agent B 的任务卡:
你当前位于分支 agent/ui,只负责登录页面和请求逻辑。
允许修改:
- src/pages/login/**
- src/components/auth/**
- src/api/auth.ts
不要修改:
- 后端目录
- package.json
- 公共类型定义
- 全局路由入口
接口约定:
POST /api/login
输入:{ email, password }
成功返回:{ token, user }
认证失败返回 HTTP 401
完成后运行:
npm run lint
npm run typecheck
最后创建一次 Git commit。
Agent C 的任务卡:
你当前位于分支 agent/test,只负责登录功能测试。
允许修改:
- tests/api/login/**
- tests/e2e/login/**
不要修改:
- 业务实现代码
- package.json
- 锁文件
- 数据库迁移文件
覆盖场景:
- 正确账号登录成功
- 密码错误返回 401
- 登录页面展示错误信息
- 登录成功后保存 token 并跳转
完成后总结测试范围并创建一次 Git commit。
任务边界越具体,合并阶段越轻松。Prompt 写得长不是重点,能不能消除歧义才是重点。
三、并行确实更快,但不要迷信“三倍速”
串行执行的总时间,大致接近三个任务耗时之和:
后端开发 → 前端开发 → 测试开发 → 集成验证
并行执行时,主要等待时间由最慢的任务决定:
后端开发 ┐
前端开发 ├→ 合并 → 修复 → 全量测试
测试开发 ┘
但这不意味着三个 Agent 就一定带来三倍速度。完整耗时还包括:
并行总耗时
= 最慢 Agent 执行时间
+ 任务拆分时间
+ 人工检查时间
+ 合并时间
+ 冲突修复时间
+ 全量验证时间
由于不同项目、模型和运行环境的差异很大,本文不虚构一组漂亮的“提速百分比”。复现实验时,应记录下面这些原始数据:
| 指标 | 单 Agent 串行 | 3 Agent 并行 | |---|---:|---:| | 总墙钟时间 | 实测填写 | 实测填写 | | Agent 执行总时长 | 实测填写 | 实测填写 | | 人工任务拆分时间 | 实测填写 | 实测填写 | | 合并与修复时间 | 实测填写 | 实测填写 | | API/Token 成本 | 实测填写 | 实测填写 | | 测试失败次数 | 实测填写 | 实测填写 |记录时还要注明:
- 项目规模与技术栈;
- 使用的模型及版本;
- Agent 是否自动执行命令;
- 是否允许访问网络;
- 是否包含依赖安装时间;
- 是否把人工修复计入总时间。
适合并行的任务通常具有低耦合特征,例如不同页面、独立接口、测试补齐、文档编写和代码审查。
以下任务则不适合强行并行:
- 多个 Agent 同时重构核心模块;
- 同时修改一套数据模型;
- 同时升级框架和依赖;
- 需求本身尚未确定;
- 大量代码集中在少数公共文件中。
四、合并前必须解决的 4 类冲突
1. 文本与代码冲突:多个 Agent 修改同一文件
这是 Git 最容易发现的一类冲突。
例如后端 Agent 和前端 Agent 都修改了公共路由入口,合并时会出现:
<<<<<<< HEAD
registerAuthRoutes(app)
=======
registerLoginPageRoutes(app)
>>>>>>> agent/ui
处理流程如下:
git status
手动编辑冲突文件后
git add src/routes/index.ts
git commit
不要只删除 <<<<<<<、======= 和 >>>>>>>。还要理解两个分支各自想实现什么,确认最后代码同时保留了正确行为。
更隐蔽的情况是:Git 没有报错,但后合入的代码改变了前一个分支依赖的行为。
应对方法包括:
- 提前划定文件所有权;
- 公共入口由主控者统一修改;
- 要求 Agent 提交小而清晰的 commit;
- 每合并一个分支就立即运行测试。
截图建议三、四:分别展示 git log --graph --oneline --all 和一次真实文本冲突。
2. 接口与语义冲突:代码能合并,功能却对不上
这比文本冲突危险得多,因为 Git 根本不会报警。
后端可能返回:
{
"access_token": "example-token",
"user": {
"id": "u_001"
}
}
前端却这样读取:
const { token, user } = await login(email, password);
localStorage.setItem("token", token);
两边修改的是不同文件,Git 会顺利合并,但运行时的 token 是 undefined。
解决办法是开工前冻结共享协议。例如建立统一类型:
export interface LoginRequest {
email: string;
password: string;
}
export interface LoginUser {
id: string;
email: string;
}
export interface LoginResponse {
token: string;
user: LoginUser;
}
也可以使用 OpenAPI 或 JSON Schema:
paths:
/api/login:
post:
responses:
"200":
description: Login succeeded
content:
application/json:
schema:
type: object
required: [token, user]
properties:
token:
type: string
user:
type: object
"401":
description: Invalid credentials
Git 冲突是“两个 Agent 写了同一行”,业务语义冲突则是“两个 Agent 对同一件事理解不同”。后者通常更贵。
合并前应优先运行契约测试和端到端测试,而不只是单元测试。
截图建议五:展示 Git 合并成功,但因access_token与token不一致导致测试失败。
3. 依赖与环境冲突:各自能跑,合在一起装不上
三个 Worktree 的代码彼此隔离,但依赖目录、环境变量和数据库状态未必完全一致。
常见问题包括:
- 多个 Agent 同时修改
package.json; - 锁文件出现大面积变化;
- 前端依赖新的环境变量,但没有更新示例文件;
- 数据库迁移顺序错误;
- 一个 Agent 升级了框架,另一个仍按旧 API 编码。
更稳妥的规则是:只指定一个 Agent 管理依赖和基础设施文件。
其他 Agent 如果确实需要增加依赖,应在提交说明中提出,不要擅自重写锁文件。
.env.example 也应明确列出必需配置:
DATABASE_URL=
JWT_SECRET=
VITE_API_BASE_URL=http://localhost:3000
全部合并后,在干净环境重新验证:
rm -rf node_modules
npm ci
npm run lint
npm run typecheck
npm test
npm run build
npm run test:e2e
还要检查:
git diff main~1 -- package.json package-lock.json
git diff main~1 -- .env.example
git diff main~1 -- docker-compose.yml
4. 集成与合并顺序冲突:三个正确答案组成错误系统
假设测试 Agent 根据旧接口写了测试,前端 Agent 又依赖尚未合入的共享类型。三个分支单独看都合理,但合并顺序错误,可能导致:
- 测试验证的是旧行为;
- 前端重复定义接口类型;
- 后合入的分支重新引入旧代码;
- 临时兼容逻辑被误当成最终实现。
建议采用固定集成顺序:
共享类型/基础设施
→ 后端核心能力
→ 前端或调用方
→ 测试与文档
→ 全量回归
合并前,先让各分支同步最新 main:
git switch agent/ui
git rebase main
如果发生冲突:
git status
修复文件后
git add
git rebase --continue
如果决定取消
git rebase --abort
再由主控者逐个合并:
git switch main
git merge --no-ff agent/auth
npm test
git merge --no-ff agent/ui
npm run typecheck
npm test
git merge --no-ff agent/test
npm run test:e2e
npm run build
--no-ff 可以保留分支合并节点,让后续复盘时更容易看出每个 Agent 交付了哪些内容。
截图建议六:三个分支合并后,展示测试通过或 CI 全绿。截图建议七:绘制串行与并行执行时间线,并把合并、返工时间包含在内。
五、一套可以直接复用的多 Agent 合并 SOP
真正稳定的多 Agent 工作流,可以压缩成下面九步:
1. 将需求拆成低耦合任务;
2. 为每个 Agent 创建独立分支和 Worktree;
3. 固定接口契约、目录边界和验收命令;
4. 明确公共文件所有权;
5. 要求 Agent 用小提交交付,并附带修改说明;
6. 合并前让各分支同步主分支;
7. 按依赖顺序逐个合并;
8. 每合并一次就运行测试;
9. 最后在干净环境完成安装、构建和端到端验证。
任务完成后,删除 Worktree:
git worktree remove ../project-auth
git worktree remove ../project-ui
git worktree remove ../project-test
git worktree prune
git worktree list
确认分支已合并后,再删除本地分支:
git branch -d agent/auth
git branch -d agent/ui
git branch -d agent/test
如果 Git 拒绝删除,先检查分支是否真的完成合并,不要习惯性使用 -D 强制删除。
复现实验:先从一个小仓库开始
如果你想验证这套方法,不要一上来就让多个 Agent 重构核心代码。更合理的行动清单是:
1. 准备一个带测试的小型 Git 项目;
2. 选择三个边界清晰的任务;
3. 创建三个 Worktree;
4. 分别分配开发、测试和审查任务;
5. 记录墙钟时间、调用成本和合并返工时间;
6. 用四类冲突清单逐项验收;
7. 对比串行执行和并行执行的完整成本。
如果需要集中管理模型调用、切换不同模型或对比成本,可以前往 api.884819.xyz 配置接口。8848AI 平台内置 AI 对话功能,用户名加密码即可注册,不需要邮箱验证;国产模型如 Deepseek、千问等可免费使用,没有月租和订阅,其他模型按量付费。
新用户注册即送体验token。最终结论并不复杂:
Worktree 让三个 Agent 不再抢同一张桌子,但只有清晰的任务边界和验收流程,才能让它们真正成为一个团队。
可扩展的多 Agent 开发,本质上不是“同时打开更多终端”,而是并行执行、统一协议、串行验收。Worktree 解决了“多个 Agent 在哪里工作”,却还没有解决“谁来拆任务、检查结果和决定返工”。
下一篇,我们将继续实测如何设计一个主控 Agent:让它自动创建分支、分配任务、审查代码,并在合并失败时把问题退回对应 Agent——看看多 Agent 开发能否从手动协作,进一步升级为自动化流水线。
本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。#GitWorktree #AI编程 #多Agent #Git教程 #编程Agent #软件开发 #8848AI #人工智能