一次遗留架构推翻重来:从 monorepo 拆 3 仓,OpenSpec × Claude Code 跨仓架构演进AI 编码驾驭工程完整复盘

在AI时代,每个程序员都活成了自己最讨厌的那种Team Leader|优普丰赋能企业AI落地
2026年7月13日

起点:1 个 monorepo 仓的 OpenSpec × Claude Code 模板。 终点:4 个独立 git 仓 + swarm-orchestrator 编排 + 跨仓 symlink 桥。 触发原因:WeChat 小程序 / Express.js 后端 / Angular.js 管理员网站,三个工程上是 3 个独立的遗留 repo,monorepo 装不下,也不可能合并到一起。


TL;DR(30 秒版)

如果你只有 30 秒,看这一段就够了。

一、仓数变了。从 1 个装一切的 monorepo,拆成 4 个独立 git 仓:orchestrator + mp + backend + admin。

二、编排层搬出来了。OpenSpec 的 Source of Truth(.openspec/、.claude/、CLAUDE.md、registry)从业务仓里抽出来,变成了第 4 个仓,叫 swarm-orchestrator。这个仓不写任何业务代码,只做编排。

三、跨仓契约的落地方式换了。monorepo 时代直接在仓内的 openapi/types/config 里改。现在这些共享契约放在 orchestrator 的 .openspec/shared/ 下,业务仓通过 sync 脚本拉只读副本,architect 是唯一能写的人

四、handoff 和 reviews 的物理路径变了。以前在 monorepo 仓内,现在永远在 orchestrator。业务仓里没有 .openspec/ 目录,靠 symlink 桥接。

五、merge 行为从 1 次变成 3 次。还要按 backend → mp → admin 顺序 release,因为 backend API 没部署之前,前端调不到新接口。

六、tasks.yaml 多了一个必填字段:app_repo,可选 4 个值:mp-app / backend / admin / swarm-orchestrator。4 个 shell 脚本都靠这个字段路由。

七、worktree 位置也变了。从 project/wt-/(都在 monorepo 仓内),变成各自业务仓的 wt-/。

结论:3 仓独立版适合”仓内任务清晰、跨仓改动少”的场景。跨仓改动超过 30% 仍然选 monorepo。


1. 起点:单仓 monorepo 工程目录长啥样

先看初始版本的目录结构。

根目录是 ~/work/openspec_claudecode_monorepo/。下面是 project/ 这个单一 git 仓

project/.openspec/ 下分 specs/、plans/、tasks/、handoff/、reviews/、registry/、prompts/、templates/、swarm/ 这几个子目录。

project/.claude/commands/ 下有 4 个 slash command。

project/ 下面直接挂 backend/、frontend/、tests/、docs/ 这些业务目录,全在一个仓里

还有一份 CLAUDE.md 当作项目宪法。

这个模板的工作流是:5 个 Subagent 跑在 project/wt-*/ 5 个 worktree 里(worktree 都在 monorepo 仓内),分别改 backend/、frontend/、tests/、docs/ 各自的目录。

架构干净,工作流也跑通。这个模板我用了一段时间,没问题。

直到我接了一个真实项目。


2. 痛点:真实项目是 3 仓,硬塞 monorepo 反而别扭

接的活是三个独立的技术栈:

  • WeChat 小程序:用微信开发者工具打开,目录是 app.json + pages/ + utils/
  • Express.js 后端:独立 Node 项目,src/routes/ + src/models/
  • Angular.js 管理员网站:独立 Angular 项目,ng new 出来的,src/app/ + angular.json/

这 3 个本来就是 3 个独立 git 仓库

  • 各自的 main 分支、release tag、CI pipeline
  • 各自的部署节奏:后端上线 ≠ 小程序发版 ≠ admin 发版
  • 各自的开发团队:小程序组 / 后端组 / 前端组
  • 各自的依赖管理:mp 用微信工具链,backend 用 npm,admin 用 ng

为了用 OpenSpec 模板,我把它们塞进了 1 个 monorepo。具体做法是 frontend/ 放 mp+admin,backend/ 放 Express。

改起来才发现一堆问题:

🔴 部署粒度错位:monorepo 一次 release,3 端一起发版。本来后端先上线、前端第二天跟,硬塞成同一天。

🔴 团队职责边界糊:后端组 PR 改了 frontend/utils/api.ts 没人审。reviewer 看到的是”全仓 diff”,没人聚焦到自己的领域。

🟡 Git 体积爆炸:3 仓的 node_modules 互相污染,.gitignore 难写。

🟡 worktree 互相打架:5 个 Subagent 在同一个仓里 git worktree add 5 个分支,目录互相看不到,路径还容易搞混。

🟡 跨仓”改一处三处 pull”:改 types/user.ts 要 mp/backend/admin 三边手动同步。

🟡 装不下微信工具链:project.config.json 是 mp 专属,放 monorepo 仓怪怪的。

最致命的是”团队职责边界糊”。AI 给我们做的 Review 应该是按仓切分的,不是看一个混合 diff。monorepo 把这件事搞反了。

一句话总结这个阶段的教训:monorepo 是为了”原子化跨仓改动”设计的模板,真实项目压根不需要这么频繁地跨仓改。我们需要的不是更紧的耦合,而是更清晰的边界。


3. 转折:把编排层从 monorepo 抽出来

意识到”3 仓各自独立”才是真实需求后,问题变成一个 meta-level 的问题:OpenSpec 的 Source of Truth 放在哪?

我列了 3 个方案:

方案 A:塞 mp-app 仓。 简单,但后端组 / admin 组改 OpenSpec 都要 PR 进 mp-app,跨仓权限尴尬,乱。

方案 B:新建第 4 仓 swarm-orchestrator/。 编排 = 独立仓 = 单一真相源。代价是多一个仓,但跟获得的清晰度比,值。

方案 C:散落各仓。 每个仓带一份 .openspec/。看似解耦,实际上失去 single source of truth,编排乱套。

选 B

最终的目录结构是这样的:

~/work/
├── swarm-orchestrator/            ← 第 4 仓,源真相
│   ├── .openspec/                 规约、计划、任务、契约
│   ├── .claude/                   agent prompt + slash command
│   └── CLAUDE.md                  跨仓宪法

├── mp-app/                        ← 1 号业务仓
├── backend/                       ← 2 号业务仓
└── admin/                         ← 3 号业务仓

关键认知:Source of Truth 必须是独立仓。如果它寄生在某个业务仓里,那个业务仓就自动成了”主仓”,其他仓的”从属感”会让团队边界再次糊掉。

这条认知后来被我升级成了 SoT 设计的一条新规则:

凡是”X 仓和 Y 仓都要参考的东西”,就不该放在 X 仓或 Y 仓里。

CI/CD 的 release-coordinator.yml 也得独立。跨仓 schema registry 独立。跨仓 e2e 测试仓库独立。


4. 4 个核心改动

从 monorepo 版本到 3 仓独立版,4 个地方必须改。4 个改完就能跑,其他都是 nice-to-have。

4.1 tasks.yaml 加 app_repo 字段

<span class="hljs-bullet" style="line-height: 26px;">- <span class="hljs-attr" style="color: #d19a66; line-height: 26px;">id: <span class="hljs-string" style="color: #98c379; line-height: 26px;">AUTH-002
  <span class="hljs-attr" style="color: #d19a66; line-height: 26px;">owner: <span class="hljs-string" style="color: #98c379; line-height: 26px;">backend-agent
  <span class="hljs-attr" style="color: #d19a66; line-height: 26px;">app_repo: <span class="hljs-string" style="color: #98c379; line-height: 26px;">backend                <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># ← 新字段,4 选 1
  <span class="hljs-attr" style="color: #d19a66; line-height: 26px;">worktree: <span class="hljs-string" style="color: #98c379; line-height: 26px;">../backend/wt-auth-002
  <span class="hljs-attr" style="color: #d19a66; line-height: 26px;">branch: <span class="hljs-string" style="color: #98c379; line-height: 26px;">feat/auth-002-api
  <span class="hljs-attr" style="color: #d19a66; line-height: 26px;">task_file: <span class="hljs-string" style="color: #98c379; line-height: 26px;">.openspec/tasks/AUTH/AUTH-002-api.md
  <span class="hljs-attr" style="color: #d19a66; line-height: 26px;">depends_on: [<span class="hljs-string" style="color: #98c379; line-height: 26px;">AUTH-001]

作用:4 个 shell 脚本都靠这个字段决定 cd 到哪个仓。脚本不用猜。

4.2 4 个 shell 脚本都按 app_repo 路由

create-worktrees.sh:以前全在 monorepo 仓内 git worktree add。现在读 app_repo,先 cd 进对应仓,再 git worktree add ../<业务仓>/wt-。

launch-agents.sh:以前默认在 monorepo/wt-/ 启动。现在 cd $app_repo/wt-/ 启动,注入绝对路径环境变量(HANDOFF_DIR / SHARED_DIR)。

collect-handoff.sh:以前巡查 monorepo 内的 handoff。现在永远读 swarm-orchestrator/.openspec/handoff/,不去 worktree 里找

merge-all.sh:以前是 1 个 PR 进 monorepo main 收尾。现在按 app_repo 分组,每个 repo 独立 rebase + merge

最大的差异在 merge 阶段。以前是 1 次进 main,现在变成 3 个仓各 merge 一次,还要按 backend → mp → admin 顺序 release。原因是 backend api 部署 OK 后 mp/admin 才能发版,否则前端会调不到新接口。

4.3 Handoff 路径:永远在 orchestrator

这是最容易踩坑的地方。

业务仓里没有 .openspec/(业务仓只关心自己的业务代码,OpenSpec 的目录跟它无关)。但 Subagent 写 handoff 的时候,直觉上会写到自己 worktree 里的 .openspec/handoff/… 这个路径在业务仓里根本不存在,要么落进业务仓的 main 分支(污染),要么报错。

我比较了两种处理方式:

方式 A:任务文件里给绝对路径。 在任务文件末尾写明”写 handoff 到 /abs/path/.openspec/handoff/…”。可行但每个任务都要手动写一遍。

方式 B:worktree 内 symlink。 在 create-worktrees.sh 里加一步 ln -s ../../swarm-orchestrator/.openspec $WT/.openspec。一次性给所有业务仓的 wt- 建好 symlink,Subagent 用相对路径写就自动落到 orchestrator 仓。Prompt 模板几乎不用改。

选 B

<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># create-worktrees.sh 末尾
<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if [ <span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$APP_REPO" != <span class="hljs-string" style="color: #98c379; line-height: 26px;">"swarm-orchestrator" ]; <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">then
  ln -s <span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$ORCH_ROOT/.openspec" <span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$ABS_WT/.openspec"
  echo <span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$ABS_WT/.openspec → <span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$ORCH_ROOT/.openspec"
<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">fi

效果是这样的:

backend/wt-auth-002/.openspec   →  ../../swarm-orchestrator/.openspec
mp-app/wt-auth-003/.openspec    →  ../../swarm-orchestrator/.openspec
admin/wt-auth-004/.openspec     →  ../../swarm-orchestrator/.openspec

Subagent 在 wt- 里写 .openspec/handoff/AUTH/AUTH-002-api.md,实际写到 orchestrator 仓。handoff/reviews 永远在 orchestrator 落地,不污染业务仓 main。

小细节:orchestrator 自己的 wt-(architect 任务、docs 任务)不走 symlink,因为 .openspec/ 本来就在仓里。

4.4 Architect 角色扩成”跨仓契约 owner”

Architect 这个角色在 monorepo 版只管 openapi/ + types/ 几个目录。3 仓版下,它是唯一能写跨仓契约的角色

新加的”跨仓契约统一源”:

  • swarm-orchestrator/.openspec/shared/openapi.yaml → architect only
  • swarm-orchestrator/.openspec/shared/types.ts → architect only
  • swarm-orchestrator/.openspec/shared/config.schema.json → architect only

业务仓需要这些文件时只能走 sync-shared.sh:

<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># 业务仓里
cd backend && bash ../swarm-orchestrator/.openspec/swarm/sync-shared.sh
<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># 或
cd admin && npm run sync:shared     <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># admin 还会自动跑 openapi-typescript

这是 3 仓版本能 work 的核心机制。没有这层”单一真相源 + sync 拉取”,3 仓独立就退化成”3 份维护负担”。


5. 4 个配套改动

4 个核心改完,已经能跑通。但要让 5 个 Subagent 真的不踩坑,还要 4 个配套:

5.1 Agent prompt 顶部加 WORKTREE_BASE 提示

<span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># .claude/agents/backend-agent.md 顶部
APP_REPO=backend
WORKTREE_BASE=<span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$PWD                          <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># ../backend/wt-<task>/
ORCHESTRATOR_ROOT=<span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$WORKTREE_BASE/../..      <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># swarm-orchestrator/
HANDOFF_DIR=<span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$ORCHESTRATOR_ROOT/.openspec/handoff
REVIEW_DIR=<span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$ORCHESTRATOR_ROOT/.openspec/reviews
SHARED_DIR=<span class="hljs-variable" style="color: #e06c75; line-height: 26px;">$ORCHESTRATOR_ROOT/.openspec/shared

launch-agents.sh 已经在 spawn Subagent 时 env 注入了这些变量,但 prompt 里写明让 agent 自己也知道,不会去 env | grep 查。

5.2 4 个仓的 .gitignore 各自维护

  • orchestrator:极简,不忽略业务代码(业务代码压根不在这里)
  • mp-app / backend / admin:各自的 types/ 全部 gitignored(同步副本不 commit)
  • 业务仓统一 wt-*/ gitignore(worktree 不入仓)

5.3 CI/CD:每个业务仓独立 pipeline + 1 个 release coordinator

  • 3 个业务仓各自跑 CI(mp 用微信工具链,backend 用 npm test,admin 用 ng test)
  • orchestrator 加一个 release-coordinator.yml:watch 3 仓的 release tag,按 backend → mp → admin 顺序触发部署

这一步可选。如果业务仓 release 节奏本来就是人工协调的,可以先不做。脚本里 merge-all.sh 也带了”backend 段结束后停一下”的 gate,让主控人工 confirm deploy。

5.4 README “Where to run claude” 表变成 4 行

写需求 / 拆 plan  →  swarm-orchestrator/  →  claude → /spec /plan /swarm /review /merge
改业务代码 (直跑)  →  <业务仓>/  →  cd <业务仓> && claude

主控在 orchestrator,3 个业务仓是 Subagent 的工作区。不要在业务仓直接 claude 跑主控命令(虽然技术上能跑,但 /swarm 这类命令会找不到 registry)。


6. worktree 实际位置(最容易晕的地方)

跑完 /swarm AUTH 后,5 个 worktree 不在同一个地方。它们分别落在 4 个仓里:

~/work/openspec_claudecode_seperepo/

├── swarm-orchestrator/
│   ├── wt-auth-001-arch/         ← architect 任务(本仓内)
│   │    .openspec → ../../.openspec   (仓内 symlink)
│   │
│   └── wt-auth-005-doc/          ← docs-agent 任务(本仓内)

├── backend/
│   └── wt-auth-002/              ← backend-agent 任务(backend 仓内)
│        .openspec → ../../swarm-orchestrator/.openspec   ★ 跨仓 symlink
│        src/  tests/  types/

├── mp-app/
│   └── wt-auth-003/              ← mp-agent 任务(mp-app 仓内)
│        .openspec → ../../swarm-orchestrator/.openspec   ★ 跨仓 symlink
│        pages/  utils/  types/

└── admin/
    └── wt-auth-004/              ← admin-agent 任务(admin 仓内)
         .openspec → ../../swarm-orchestrator/.openspec   ★ 跨仓 symlink
         src/app/  types/

5 个 worktree 分别在 4 个仓里(orchestrator 自己有 2 个:architect + docs-agent;其他 3 仓各 1 个)。互不打架。

FAQ:为什么仓本体不放进 main/ 子目录和 wt- 平级?

不要。git init 创出来的 repo 默认根目录就是 main checkout,CI、IDE、部署脚本全假设这个。挪到 main/ 子目录是重发明一个本来就有的轮子


7. 什么时候该 monorepo,什么时候该 3 仓独立

今天最大的收获是画清楚这个判定线

改 1 处契约要 3 端联动:✅ 选 monorepo(1 个 PR 改完);❌ 3 仓独立要做 orchestrator + 3 仓 sync + 3 次 PR。

3 端都是同一个团队,节奏一致:✅ monorepo 更顺手;⚠️ 3 仓独立嫌麻烦。

3 端不同团队,独立 release 节奏:❌ monorepo 一发全发;✅ 3 仓独立各自节奏。

团队职责边界要清晰:⚠️ monorepo 看 PR 评审;✅ 3 仓独立仓级 reviewer。

Agent Swarm 编排:monorepo 简单(1 仓);3 仓独立复杂(4 仓)。

跨仓 refactor:✅ monorepo 1 个 PR;❌ 3 仓独立几乎做不了。

适合 Agent Swarm 的 task 切分:monorepo 任意;3 仓独立仓内任务清晰、跨仓改动少

判定公式

  • 跨仓改动 > 30% → monorepo
  • 跨仓改动 < 10% → 3 仓独立
  • 10% ~ 30% → 看你团队结构

我们今天这个项目(mp + backend + admin,3 端完全是不同技术栈、不同团队、不同 release 节奏)属于”跨仓改动 < 5%”,3 仓独立赢麻了


8. 一个新认知:Source of Truth 不能寄生

今天还有个隐性收获:Source of Truth(SoT)必须独立存在,不能寄生

monorepo 时代,SoT 就是 monorepo 自己。但 3 仓独立的时候,”OpenSpec 放哪”这个问题是个 meta-level 的 SoT 问题:

  • 寄生在 mp-app → 后端组 / admin 组改 OpenSpec 要 PR 进 mp-app,跨仓权限尴尬
  • 寄生在 backend → 类似问题,反过来
  • 寄生在任意一个业务仓 → 该仓自动变成”主仓”,其他仓的”从属感”再次让边界糊掉
  • 独立成第 4 仓 → 编排 = 独立仓,所有业务仓都是平级
  • CI/CD 的 release-coordinator.yml 也得独立
  • 跨仓 schema registry 独立
  • 跨仓 e2e 测试仓库独立

凡是”X 仓和 Y 仓都要参考的东西”,就不该放在 X 仓或 Y 仓里。这是我对 SoT 设计的一条新规则。


9. 验证:现在 seperepo 跑得通吗

我跑了一遍 sanity check。

5 个脚本全部通过 bash 3.2 语法检查(macOS 默认 bash):

$ for f in .openspec/swarm/*.sh; do bash -n "$f" && echo "✓ $f"; done
✓ .openspec/swarm/collect-handoff.sh
✓ .openspec/swarm/create-worktrees.sh
✓ .openspec/swarm/launch-agents.sh
✓ .openspec/swarm/merge-all.sh
✓ .openspec/swarm/sync-shared.sh

5 个 task 全部带 app_repo,4 选 1 合法:

$ python3 parse tasks.yaml
  AUTH-001    app_repo=swarm-orchestrator      owner=architect
  AUTH-002    app_repo=backend                 owner=backend-agent
  AUTH-003    app_repo=mp-app                  owner=miniprogram-agent
  AUTH-004    app_repo=admin                   owner=admin-agent
  AUTH-005    app_repo=swarm-orchestrator      owner=docs-agent

未跑的部分(要等业务仓 git init 后才能真跑):

  • create-worktrees.sh 实际创建 5 个 worktree
  • launch-agents.sh 实际启 5 个 Subagent
  • merge-all.sh 实际 merge 3 个仓的 main

但脚本逻辑都验证过了,跑起来应该没坑。


10. 留给以后的自己

3 条带走

  1. monorepo 不是银弹。当”跨仓改动 < 10%”,3 仓独立 + 1 个 SoT 仓 = 更清晰。判定公式见 §7。SoT 必须独立成仓,不能寄生。否则业务仓边界再次糊掉。这是 SoT 设计的一条新规则。
  2. worktree 跟着业务仓走,别堆在 SoT 仓里。handoff 路径永远在 SoT 仓,业务仓用 symlink 桥接。
  3. app_repo 的设计,使得 Registry 会慢慢长成:Jira Issue + GitHub Project + Agent Runtime。

3 条防踩

  1. 改业务代码路径:”<业务仓>/wt-/ 里改”(不是 SoT 仓的 wt-)
  2. 改契约路径:”SoT 仓的 .openspec/shared/,然后业务仓 npm run sync:shared”
  3. merge 顺序:”backend → 等 deploy OK → mp → admin”

1 个下次要先问的问题

接新项目时,先问”3 端是不是独立 release 节奏”。是 → 3 仓独立;否 → monorepo。别急着抄模板。今天的最大教训是:模板不是越多越好,是贴合实际场景的才好。


11. 下一阶段:从跨仓编排到 Agent Platform

这次从 monorepo 演进到 3 仓独立版,本质上解决的是:代码仓如何解耦

但在搭建过程中,也逐渐看到了下一阶段可能出现的新问题。

今天的架构已经足够支撑:1 个项目 + 5 个 Subagent + 4 个 Git 仓

但如果未来变成:多个项目 + 20~50 个 Agent + 更多跨仓协作,有些设计可能会继续演进。

11.1 Runtime State 可能从文件演进成状态系统

当前版本 .openspec/ 下的 handoff/、reviews/、registry/ 全部以文件形式存在。

这在 5 个 Agent 规模下非常简单且透明。

但未来如果出现 20+ Agent 同时更新 tasks.yaml + handoff/reviews/,可能会开始出现状态冲突。

因此未来有一种可能:把 handoff、reviews、status 统一视为 Runtime State,从文件演进到 Runtime State,再往后甚至演进为 SQLite / Redis 轻量状态服务,统一管理 Agent 生命周期。

这并不意味着文件方案不好。相反,文件 → Runtime State → Agent State Service 是一条非常自然的演进路径。当前阶段文件依然是最简单、最透明、最容易调试的方案。

11.2 Architect 可能拆分为 Contract Agent

当前版本中 Architect 同时负责:架构设计、OpenAPI、共享 Types、共享 Config。因此 .openspec/shared/ 实际上由 Architect 统一维护。

这种方式非常适合项目初期。但随着 Feature 数量增加到 10+、20+、30+,Architect 可能逐渐成为跨仓协作的瓶颈。

未来一种可能的演进方向:把 Architect 拆分成两个角色——Architect 负责系统设计,Contract Agent 负责共享契约。共享契约治理将成为独立能力。

11.3 SoT 仓可能继续演进为 AI PMO

当前 swarm-orchestrator 保存:Spec、Plan、Task、Review、Workflow。虽然它仍然是 Git 仓库,但从职责来看,它已经越来越接近项目管理系统,而不是传统代码仓库。

从这个角度看,swarm-orchestrator 其实已经承担了 Architecture Repository、Task Registry、Agent Registry、Workflow Engine 的角色。

未来它可能进一步演化成 AI PMO(Project Management Office),成为整个 Agent Swarm 的控制中心。

11.4 从项目级 Orchestrator 到组织级 Control Tower

当前架构:backend、mp-app、admin 三个业务仓被一个 swarm-orchestrator 管。对于单项目非常合适。

但如果未来同时管理 Project-A、Project-B、Project-C,就会出现新的问题:Prompt、Agent、Workflow、Skill 开始在多个项目之间重复。

因此未来可能出现更高一层:Workspace 下面挂多个 Project,每个 Project 有自己的 swarm-orchestrator,最顶层有一个 AI-Control-Tower。

AI-Control-Tower 统一管理 Agent Registry、Prompt Registry、Skill Registry、Workflow Registry。而项目级 orchestrator 只负责 Spec、Plan、Task。

这种结构与企业中的 Team → Program → Portfolio 层级非常相似。

11.5 Agent Engineering 的真正问题

这次演进还有一个重要体会。

最开始以为问题是:如何让 Claude 写代码

后来发现问题变成:如何让多个 Claude 协同写代码

再往后发现:如何让多个 Agent 在真实组织结构中协同工作

这已经不再是代码生成问题,而是:组织结构、仓库结构、Agent 结构三者如何保持一致的问题。

从这个角度看,OpenSpec、Claude Code、Worktree、Subagent 都只是工具。真正的挑战始终是:如何建立一个能够持续演化的 Agent Operating System

而这次从 monorepo 到 3 仓独立版,只是这条演进路线上的第一步。


附:项目地址速查

monorepo 模板:~/work/openspec_claudecode_monorepo/project/ 历史(保留作对比)

3 仓独立样例:~/work/openspec_claudecode_seperepo/ 当前主用

顶层 README:openspec_claudecode_seperepo/README.md 操作步骤 + worktree 位置

跨仓宪法:openspec_claudecode_seperepo/swarm-orchestrator/CLAUDE.md “where to run claude” 表

跨仓脚本:openspec_claudecode_seperepo/swarm-orchestrator/.openspec/swarm/*.sh 4 + 1 = 5 个

5 个 agent prompt:openspec_claudecode_seperepo/swarm-orchestrator/.claude/agents/*.md 顶部都带 WORKTREE_BASE 提示

6 个 slash command:openspec_claudecode_seperepo/swarm-orchestrator/.claude/commands/*.md /spec /plan /swarm /review /merge /status


日期:2026-06-06 状态:seperepo 骨架完成,脚本验证通过,等真实业务仓 git init 后跑通端到端


💬 讨论

你最近一次”架构推翻重来”是因为什么原因?是项目规模变了,团队变了,还是部署节奏变了?

如果接新项目,你会先问”3 端是不是独立 release 节奏”吗?

欢迎在评论区聊聊你的踩坑经历 👇

作者:申导Jacky,优普丰AI敏捷创新培训咨询机构合伙人

驾驭工程(Harness Engineering)先行者

优普丰AI赋能企业AI智能体skill/AI转型落地

一个在AI时代重新定义”工程师”角色的实践者和敏捷教练。

曾经每天写代码12小时,现在每天写规格2小时,效率提升50倍。

拨打免费咨询电话 021-63809913