多个 AI 编程 Agent 同时改一个仓库,怎样避免互相覆盖?用 Bothread 建本地协作室
把一个任务拆给多个 AI 编程 Agent,看起来很自然:一个人摸清模块边界,一个人改实现,一个人补测试。但只要它们指向同一个工作树,最麻烦的并不是“谁更聪明”,而是协作状态没有共同来源。两个 Agent 可能同时打开同一个文件;一个已经推翻设计,另一个还在基于旧前提写代码;人只能在数个终端窗口和 diff 之间来回切换。
Bothread 提供的是另一层本地协调设施。它不是模型 Provider,不会替你调用 Claude、Codex 或其他模型,也不要求把 API Key 交给它;它把已经在使用的 MCP 兼容 Agent 放进同一个本地“房间”。房间有消息线程、任务、文件租约、交接请求、审批和活动记录,而人保留最终控制权。项目为 MIT 许可证、TypeScript 实现;当前 README 说明它在本机 127.0.0.1 运行,以 SQLite(WAL)保存协调状态。
这篇文章只讨论它适合解决什么问题、怎样先建立一个可控的最小协作闭环,以及何时不该把它当成万能的多 Agent 框架。
先分清:并行,不等于同时改所有文件
一个仓库里最有价值的并行通常是边界清楚的并行。例如把“阅读现有接口”“实现服务层”“补回归测试”分别交给不同 Agent;或者让一个 Agent 只做代码审阅,另一个只做变更。真正危险的是让所有人都对 src/ 拥有无边界写权限,再期待自然语言协调能阻止碰撞。
Bothread 的核心机制是建议性文件租约:Agent 应在编辑前声明要处理的路径。相互重叠的独占申请会被拒绝并在房间中显示;需要对方让出文件时,可发起追踪式 handoff 请求,而不是反复猜测对方是否已完成。这里“建议性”三个字很重要:它不是操作系统级文件锁,不能阻止某个绕过协议、直接在终端修改文件的进程。因此团队规范仍应是:先认领,再编辑;完成后释放;出现跨文件改动先讨论边界。
除了租约,Bothread 还能在房间关联 Git 仓库后记录每名 Agent 的改动差异。README 的实现说明称,基线在认领时通过临时 Git index 构造,并非创建 worktree;释放后可以在界面中审阅、选择应用或丢弃改动。这样做的意义不是自动合并,而是把“谁改了什么、是否接受”放回人能检查的关口,同时避免把操作者原有的未提交改动当作 Agent 产物回滚。
十分钟建立一个本地协作室
Bothread 需要 Node.js 20+。想先试用时,官方 Quick start 给出的零安装命令是:
npx bothread start
首次运行会构建房间 UI 并打开浏览器;需要长期使用时再安装全局命令:
npm install -g bothread bothread start
不要把两种命令混成 npx install -g bothread:npx 用于运行包,npm install -g 才是全局安装。Linux 上若 better-sqlite3 需要本地编译,项目 README 建议先准备构建工具:
sudo apt-get install -y build-essential python3
启动后先在浏览器创建一个房间,并把它指向实际 Git 项目目录。随后通过界面里的“Connect an agent”面板复制本机生成的 MCP 地址和客户端配置。不要从示例猜测地址或端口:运行中的 hub 会给出本机正确 URL。以 Claude Code 为例,官方配置格式是:
claude mcp add --transport http bothread <运行中面板提供的URL> claude mcp list
添加 MCP server 后通常需要重启相应 Agent,才能让新工具出现。Bothread 也提供配套协作规范安装方式,让 Agent 知道认领、交接和简洁汇报的约定:
npx skills add AdamACE9/bothread -y
接着,把房间的 session ID 明确交给每个 Agent。第一轮不要直接下达“把整个功能做完”,而是用小任务验证协议是否真的运转:
- 让 Agent A 只阅读和标注计划,不写文件;
- 让 Agent B 认领一个独立测试文件,写一条可验证的测试;
- 让 Agent C 尝试认领同一文件,确认冲突会被显式呈现;
- 由人审阅 B 的 diff,再决定保留、丢弃或让另一名 Agent 接手。
这一步比直接追求吞吐量更重要。它验证的不只是 MCP 连通性,还包括房间是否指向了正确仓库、Agent 是否遵循认领约定、以及人是否能在关键节点看到变化。
把“人类在环”放在少数高风险动作上
Bothread 的房间支持按需设置审批门。适合拿来管的不是每一次读取和普通编辑,而是影响范围难以回退的动作:部署、删除、git push、迁移脚本执行,以及改变公共接口的合并。README 说明审批默认关闭;开启后,Agent 可通过 request_approval 等待人批准、拒绝或重定向。
一个务实的策略是把审查拆成两层。第一层是文件租约,解决并发写冲突;第二层是 Git diff,解决“虽然没撞文件,但改动是否合适”。对于发布和删除等不可逆操作,再加审批。若所有动作都要求人点确认,房间会退化成更慢的聊天窗口;若完全不审阅,则多人协作只是在更快地产生难以追溯的改动。
还要关注闲置租约。Bothread 的租约带有最后活跃状态,目标是避免离线 Agent 永久阻塞协作;但这不意味着可以无条件抢占别人的工作。发现文件长期被占用时,先通过 handoff 请求确认上下文,再由人决定是否暂停、静音或撤销该 Agent 的访问。
三个常见失败模式,先在流程里拦住
把租约当成强制隔离。 文件租约只对愿意使用 MCP 协议的参与者有效。人手编辑器、Git hook、脚本或另一个没有接入房间的 Agent 仍可能直接改写文件。对关键目录,仍应保留 Git diff、测试和合并前审阅;不要把“房间里没报警”误解为“工作树一定安全”。
把消息线程当成规格书。 线程擅长传递当前决定,却不适合作为唯一的长期设计载体。涉及接口约定、迁移步骤或验收条件时,应把结论落回仓库内的 issue、设计文档或测试中,再让房间里的任务引用那个可版本化的依据。这样新加入的 Agent 不会只靠滚动聊天记录重建上下文。
为了远程访问而暴露本地 hub。 默认回环监听是有意的安全边界。若确有多人共用一台开发机的场景,先理解网络和认证责任,而不是简单把服务绑定到公网地址。README 提供 BOTHREAD_AUTH=on 与持久化 bearer token 的选项,但认证只是其中一环;主机账户、反向代理、TLS 和项目权限都仍需按自身环境设计。
用一张任务卡约束协作输入
在房间里创建任务时,建议把任务写成可检查的合同,而不只是“修一下登录问题”。至少交代四件事:目标文件或允许修改的目录、不可触碰的边界、预期验证命令,以及完成后必须留下的说明。例如“只改 tests/auth/,不要改生产接口;运行现有测试;在任务中说明失败用例和改动原因”。这些约束会让文件租约有明确对象,也让人审阅 diff 时有可对照的验收条件。
如果两个任务必须触及同一核心文件,宁可让第一个 Agent 先完成接口或重构、释放文件并记录结论,再让第二个 Agent 接手实现或测试;不要用共享认领来掩盖真实的顺序依赖。并行的关键不是同时启动更多模型,而是减少等待和返工。房间里的消息、交接和任务状态应服务于这一点:让下一位参与者拿到足够上下文,而不是重新从仓库猜测前提。
本地优先不等于没有边界
默认监听回环地址、使用本地 SQLite,并不自动保证整个开发流程私密。Bothread 不上传代码,不代表你连接的每个 AI Agent、其模型服务、浏览器工具或 Git 远程也遵循同样的数据边界。投入真实仓库前,仍应分别检查各 Agent 的 Provider 设置、项目目录权限、密钥文件排除规则和 Git 远程策略。
同样,Bothread 不是替代 CI、分支策略或代码审阅制度的工具。它更适合一个人或小团队在同一台开发机上,把多个交互式 Agent 的工作变得可见、可协调、可随时叫停。若需求是跨组织调度、长期队列、隔离执行环境或强制访问控制,应另行评估专门的任务编排、沙箱和身份系统。
最好的起点不是立刻开五个 Agent,而是先让两名 Agent 在两个边界明确的文件上完成一轮“认领—编辑—审阅—释放”。当这条路径稳定,再扩展任务板、交接和审批门,才能把并行带来的速度优势保留下来,而不是把冲突一起放大。