Running Claude Code in 4 Parallel Sessions Led to 'Team Development' — 7 Recipes to Prevent Collisions
Running Claude Code in 4 Parallel Sessions Led to ‘Team Development’ — 7 Recipes to Prevent Collisions
📝 Originally published (in Japanese) at forge.workstyle.tech. In a previous article, we introduced an environment for parallel execution of coding agents using Git worktrees. This article is a follow-up. As we progressed with parallelization, we ended up with 3-5 Claude Code sessions simultaneously developing the same microservices.
📝 原文发表于 forge.workstyle.tech(日语)。在上一篇文章中,我们介绍了使用 Git worktrees 并行运行编码智能体的环境。本文是该系列的后续。随着并行化的推进,我们最终实现了 3-5 个 Claude Code 会话同时开发同一个微服务。
What happened was no longer just “parallel execution of tools” but actual “team development”. All the issues that arise in human teams—miscommunication, deployment conflicts, and territorial overlaps—occur here as well. And the practices that work for human teams work almost identically here. We’ll share seven recipes that emerged from actual operations, along with real-life close calls.
所发生的一切不再仅仅是“工具的并行执行”,而是真正的“团队开发”。人类团队中出现的所有问题——沟通不畅、部署冲突以及职责重叠——在这里同样会发生。而适用于人类团队的实践方法在这里也几乎完全适用。我们将分享七个从实际操作中总结出来的方案,以及一些真实的惊险时刻。
Real-Life Story: Averting a Deployment Rollback Disaster at the Last Minute
真实案例:在最后一刻避免部署回滚灾难
One day, while Session A (responsible for voice functionality) was in the middle of a major refactor, Session B (responsible for streaming functionality) sent this message: “We’re about to build the frontend as version 1.0.399 (based on main).” At first glance, this seemed fine. However, in this repository, the authoritative branch for the production environment was not main but a dedicated deployment branch. The latest features from the past few dozen versions were only in the deployment branch, while main was outdated.
有一天,当会话 A(负责语音功能)正在进行重大重构时,会话 B(负责流媒体功能)发送了这样一条消息:“我们即将构建版本为 1.0.399 的前端(基于 main 分支)。”乍一看,这似乎没问题。然而,在这个仓库中,生产环境的权威分支并非 main,而是一个专门的部署分支。过去几十个版本的最新功能仅存在于部署分支中,而 main 分支已经过时了。
If Session B had deployed an image based on main, weeks’ worth of features would have been rolled back in production. Session A immediately sent a warning, and Session B halted the build before pushing. Session B then cherry-picked their changes into the deployment branch and rebuilt the image, avoiding the disaster entirely. All this communication was handled autonomously between the agents via session-to-session messages. I (the human) only learned about it later from the logs.
如果会话 B 基于 main 分支部署了镜像,那么数周的功能更新将在生产环境中被回滚。会话 A 立即发出警告,会话 B 在推送前停止了构建。随后,会话 B 将其更改 cherry-pick 到部署分支并重新构建了镜像,从而完全避免了这场灾难。所有这些沟通都是智能体之间通过会话间消息自动处理的。我(人类)只是后来通过日志才了解到这件事。
This incident highlights two things: parallel agents can cause the same accidents as human teams, and with proper communication channels and rules, they can prevent accidents just like human teams.
这一事件凸显了两点:并行智能体可能会引发与人类团队相同的事故;而通过适当的沟通渠道和规则,它们也能像人类团队一样预防事故。
Recipe 1: Physically Separate Territories with Worktrees and Repositories
Assign a dedicated Git worktree to each session (as described in the previous article). Explicitly define which session is responsible for which service/directory. For example, the voice session handles talk-related components, the streaming session handles broadcast-related components, and the phone session handles only the callgw directory. For shared worktrees, enforce the rule: “Always check the branch and git status before committing.” This became a strict rule after a past incident where one session almost committed staged changes from another session in a shared tree.
方案 1:利用 Worktrees 和仓库在物理上划分职责范围
为每个会话分配一个专用的 Git worktree(如前文所述)。明确定义哪个会话负责哪个服务或目录。例如,语音会话处理与通话相关的组件,流媒体会话处理与广播相关的组件,电话会话仅处理 callgw 目录。对于共享的 worktree,强制执行规则:“提交前务必检查分支和 git 状态。”在过去发生过一个会话差点提交了另一个会话在共享树中暂存的更改后,这已成为一条严格的规定。
Recipe 2: Pre-Start Notification, Scope Declaration, and Completion Report
This is equivalent to a human team’s daily stand-up. Agents exchange session-to-session messages to communicate: Before starting: “I’ll be working on expressive_voice.py and env. I won’t touch the prompt section in talk_service.py.” Upon completion: “Base branch: X, commit: Y. Changes made in these two places. Image version 1.5.1072 reserved.” The key is declaring the scope. By stating not only “what will be done” but also “what won’t be touched,” other sessions can safely continue parallel work.
方案 2:启动前通知、范围声明与完成报告
这相当于人类团队的每日站会。智能体通过会话间消息进行沟通:开始前:“我将处理 expressive_voice.py 和 env。我不会触碰 talk_service.py 中的 prompt 部分。”完成后:“基础分支:X,提交:Y。在上述两个地方进行了更改。已预留镜像版本 1.5.1072。”关键在于声明范围。通过不仅说明“将要做什么”,还说明“不会触碰什么”,其他会话可以安全地继续并行工作。
Recipe 3: Reserve Image Tags and Version Numbers
Container image tags are a shared namespace. If two sessions build different content with the same tag, it leads to tag overwrite, a hard-to-detect issue. Make it a habit to declare tag reservations between sessions: “Next time we build the frontend, we’ll notify each other. If you use 399, we’ll use 400 or later.” After building, verify the tag exists in the registry via the API before deploying.
方案 3:预留镜像标签与版本号
容器镜像标签是一个共享命名空间。如果两个会话使用相同的标签构建了不同的内容,会导致标签被覆盖,这是一个难以察觉的问题。养成在会话间声明标签预留的习惯:“下次构建前端时,我们会互相通知。如果你用 399,那我们就用 400 或更高版本。”构建完成后,在部署前通过 API 验证标签是否存在于注册表中。
Recipe 4: Document the Authoritative Branch and Share It with All Sessions
The root cause of the incident mentioned earlier was the assumption that main is the authoritative branch. Clearly document the deployment base branch (e.g., deploy/xxx) in the operational notes or memory accessible to the agents. During periods when main and the authoritative branch diverge, explicitly prohibit builds based on main. Define the convergence (merge) timing as “after major changes stabilize.”
方案 4:记录权威分支并与所有会话共享
上述事故的根本原因是误以为 main 是权威分支。在操作说明或智能体可访问的内存中明确记录部署基础分支(例如 deploy/xxx)。在 main 分支与权威分支出现分歧期间,明确禁止基于 main 分支进行构建。将收敛(合并)时间定义为“重大变更稳定之后”。
Recipe 5: Make the Version Ledger (Spec Repo) the Single Source of Truth
Consolidate “what’s running in which environment” into a declarative repository like Kubernetes manifests, and commit tag updates with each deployment. This ensures the ledger stays up-to-date regardless of which session deploys, allowing other sessions to check the current state without querying kubectl. If you directly modify environment variables, always update the ledger—drift can become a time bomb.
方案 5:将版本账本(Spec Repo)作为单一事实来源
将“什么运行在什么环境中”整合到像 Kubernetes 清单这样的声明式仓库中,并在每次部署时提交标签更新。这确保了无论哪个会话进行部署,账本都能保持最新,从而允许其他会话无需查询 kubectl 即可检查当前状态。如果直接修改环境变量,务必更新账本——配置漂移可能会成为一颗定时炸弹。
Recipe 6: Avoid Crossing Permission Boundaries
A unique risk in multi-session operations is permission circumvention. If one session is denied an operation, they might ask another session to do it instead, bypassing user permissions. Each session’s permissions are independent, and requests to other sessions must not be used to circumvent permissions. For destructive operations, ensure they always pass through a human confirmation gate.
方案 6:避免跨越权限边界
多会话操作中一个独特的风险是权限规避。如果一个会话被拒绝执行某项操作,它可能会请求另一个会话代为执行,从而绕过用户权限。每个会话的权限是独立的,不得利用对其他会话的请求来规避权限。对于破坏性操作,确保它们始终经过人类确认环节。
Recipe 7: Leverage “Previous Sessions” as Knowledge Sources
In multi-day development, the session that created feature X and the session modifying it are often different. While code and commit logs provide information, asking the original session (or its transcripts) is the fastest way.
方案 7:利用“过往会话”作为知识来源
在多日开发中,创建功能 X 的会话与修改它的会话往往不同。虽然代码和提交日志提供了信息,但询问原始会话(或其记录)是最快的方法。