Claude Code 实战(2):构建工业级 AI 并行开发流水线
-
- [一、核心痛点:为什么单实例 Claude 会"崩溃"?](#一、核心痛点:为什么单实例 Claude 会"崩溃"?)
- 二、四大并行架构:从"工具"进化为"团队"
-
- [1. Subagents(子代理):同项目内的角色分工](#1. Subagents(子代理):同项目内的角色分工)
- [2. Agent Teams(代理团队):真正的多头脑协作](#2. Agent Teams(代理团队):真正的多头脑协作)
- [3. Git Worktree(工作树):分支级的硬隔离](#3. Git Worktree(工作树):分支级的硬隔离)
- [4. Workflow Orchestration(工作流编排)](#4. Workflow Orchestration(工作流编排))
- 三、Routines:向"无人值守"跨越
-
- [1. 定时触发](#1. 定时触发)
- [2. API 触发](#2. API 触发)
- [3. 事件触发](#3. 事件触发)
- [四、工业级 AI 开发的 5 步闭环](#四、工业级 AI 开发的 5 步闭环)
-
- [Step 1:任务分解(Plan 模式)](#Step 1:任务分解(Plan 模式))
- [Step 2:角色分配(Agent Teams)](#Step 2:角色分配(Agent Teams))
- [Step 3:并行执行(Git Worktree + Agent Teams)](#Step 3:并行执行(Git Worktree + Agent Teams))
- [Step 4:整合 Review(Subagents)](#Step 4:整合 Review(Subagents))
- [Step 5:代码合并(Git Worktree 物理验证)](#Step 5:代码合并(Git Worktree 物理验证))
- 五、总结:如何选择你的并行方案?
- 分享金句(建议背诵,技术分享时假装不经意说出)
免责声明:本文中的"崩溃""失忆""崩溃"等词汇均为修辞性夸张,用于形容开发过程中的效率瓶颈。Claude 不会真的崩溃,但你的耐心可能会。另外,文中提到的"工业级"指的是"比个人玩具项目更严肃一点",而非"能造火箭"。请根据团队实际情况选择性采纳,不要直接复制粘贴到生产环境然后来问我为什么 CI 挂了。
一、核心痛点:为什么单实例 Claude 会"崩溃"?
事情要从一个平凡的周二下午说起。
我正在用 Claude Code 开发 vupStack------那个 Vue 3 + TypeScript 前端、Java Spring Boot 后端、MySQL 数据库的部署管理系统。当时的需求看起来人畜无害:"在前端版本详情页加一个 License 构建状态展示,后端要同步改接口,再补几个测试。"
我信心满满地敲下了第一句话:"帮我实现这个功能。"
三小时后,我盯着屏幕,陷入了存在主义危机。
第一阶段:上下文爆满
Claude 已经处理了 47 个文件的前后端改动,从 VersionDetailsTab.vue 到 LicenseBuildServiceImpl.java,再到 LicenseBuildConcurrencyTest.java。当我让它"顺便把前端国际化也补一下"的时候,它突然开始把 zh-CN.ts 里的 key 命名成 license.build.status.is.not.building.but.already.built.maybe。
"你还好吗?"我问。
"当然,我很好。"它回答,然后继续生成了一段把 customerName 和 customerCode 混为一谈的代码------而这两个字段的区分,恰恰是 vupStack License 模块的核心业务规则(customerName 由 OA 直传,本身就是简短代号如 "GAAK",没有独立的 customerCode)。
我意识到,它"失忆"了。不是那种 dramatic 的科幻片失忆,而是那种------你刚跟同事说完"这个字段叫 customerName 不叫 customerCode",五分钟后他问你"customerCode 怎么映射来着"------的日常失忆。
第二阶段:任务串行化
我试图抢救局面:"先别写代码了,你帮我写测试吧。"
"好的,但我需要先理解你之前的改动。"
"那你理解了吗?"
"让我看看... 你改了哪些文件来着?"
于是我们陷入了经典的"你先写测试还是先写实现"的死锁。单实例模式下,Claude 就像一个单核 CPU,在处理前端 Vue 组件的时候,后端的 MyBatis Mapper 就进了 swap;在写单元测试的时候,前端 API 层的改动就已经被逐出了上下文窗口。
第三阶段:多模块失联
最致命的是前后端的对齐问题。
我:"前端需要 License 构建状态的枚举值:PENDING、BUILDING、SUCCESS、FAILED。"
Claude(正在写前端):"好的,定义好了。"
十分钟后。
我:"后端接口返回的状态字段叫什么?"
Claude(正在写后端):"叫 status,类型是字符串。"
我:"具体有哪些值?"
Claude:"PENDING、PROCESSING、OK、ERROR。"
我:"..."
Claude:"怎么了?"
我:"前端叫 SUCCESS,你后端叫 OK?前端叫 FAILED,你后端叫 ERROR?前端叫 BUILDING,你后端叫 PROCESSING?"
Claude:"哦。那... 改前端还是改后端?"
这就是单实例的宿命:它没有一个"持久化的共享白板"来记录"咱们刚才说好了状态值叫什么"。每次切换上下文,就像换了一个新同事接手,你得把所有约定重新讲一遍。
那一刻,我明白了:我需要的不只是一个"更聪明的 AI",而是一个"能同时存在的多个 AI",以及让它们协作的机制。
二、四大并行架构:从"工具"进化为"团队"
1. Subagents(子代理):同项目内的角色分工
Subagents 是 Claude Code 最轻量级的并行方案。它的本质很简单:在同一个 Claude 实例内,通过 Markdown 文件定义不同的"角色",然后用 @角色名 快速切换。
实战配置:vupStack 的 Agent 团队
我在项目根目录创建了 claude/agents/ 目录,把角色定义文件放进去,随 Git 提交:
markdown
# claude/agents/code-reviewer.md
## 角色:Code Reviewer
你是 vupStack 项目的代码审查专家。你的职责是:
1. **安全检查**:检查是否有硬编码密钥、SQL 注入风险、XSS 漏洞
2. **质量检查**:函数长度 < 50 行,文件长度 < 800 行,无深层嵌套
3. **风格检查**:前端使用 `<script setup lang="ts">`,后端数据库 boolean 用整数(0/1)
4. **业务规则检查**:
- License 的 `customerName` 字段就是简短代号,没有独立的 `customerCode`
- Video 软删除时 `version_no` 必须改为 `__deleted__{id}` 以规避唯一约束
- `VersionSqlChange.db_type` 必须是 MySQL 或 Doris,VARCHAR NOT NULL
审查完成后,按 CRITICAL / HIGH / MEDIUM / LOW 分级输出。
markdown
# claude/agents/test-writer.md
## 角色:Test Writer
你是 vupStack 项目的测试专家。你的工作流必须是 TDD:
1. 先写测试(RED)
2. 运行测试确认失败
3. 写最小实现(GREEN)
4. 运行测试确认通过
5. 重构(IMPROVE)
**覆盖率要求**:后端 >= 80%,前端单元测试覆盖核心 API 模块。
**后端测试命令**:
```bash
mvn test -Dtest="LicenseScriptExecutorTest,LicenseBuildServiceImplTest"
前端测试命令:
bash
npx vitest run src/__tests__/api/license.spec.ts
注意:License 模块是关键业务,已有 97 个测试,新增功能必须补充对应测试。
```markdown
# claude/agents/frontend-dev.md
## 角色:Frontend Developer
你是 vupStack 前端开发专家。技术栈:Vue 3 + TypeScript + Element Plus + Vite + Pinia + Less。
**强制规范**:
- 所有颜色必须用 CSS 变量(`--app-*` 前缀),禁止硬编码
- 所有用户可见文本使用 `$t()` / `t()`,i18n key 按功能组织
- 样式使用 `<style lang="less" scoped>`
- Props/Emits 使用泛型声明 `defineProps<T>()`
- 严格 TypeScript:禁止 `any`,使用 `unknown` + 类型守卫
**路径别名**:`@` → `src/`,Less 变量全局预加载 `@import "@/styles/variables.less"`
**API 层规范**:每个模块导出 `getList()`, `getById()`, `create()`, `update()`, `remove()`,有额外操作在此基础上扩展。
markdown
# claude/agents/backend-dev.md
## 角色:Backend Developer
你是 vupStack 后端开发专家。技术栈:Java 17 + Spring Boot 3.2.3 + MyBatis + Maven。
**强制规范**:
- 数据库 boolean 字段用整数(0/1)而非 Java boolean
- 软删除字段为 `deleted_at`
- MyBatis XML 映射文件在 `src/main/resources/mapper/*.xml`
- 统一响应格式:`{ code: 0, message: "success", data: T }`
- 操作人追踪:从 `X-Username` header 读取,fallback "system"
**包结构**:
- `com.semitronix.de.vupstack.controller` - REST 控制器
- `com.semitronix.de.vupstack.service` - 业务接口 + impl/
- `com.semitronix.de.vupstack.dao` - MyBatis Mapper
- `com.semitronix.de.vupstack.dto` - Controller 入参
- `com.semitronix.de.vupstack.entity` - 数据库实体
- `com.semitronix.de.vupstack.vo` - API 响应数据结构
调用方式
在对话中直接 @角色名:
我:@frontend-dev 帮我写 License 构建状态展示组件
[Claude 切换为 Frontend Developer 角色,自动加载前端规范]
我:@backend-dev 同步改一下后端接口,返回构建状态
[Claude 切换为 Backend Developer 角色,自动加载后端规范]
我:@test-writer 给这个新功能补测试
[Claude 切换为 Test Writer 角色,自动加载 TDD 工作流]
我:@code-reviewer 审查一下刚才的改动
[Claude 切换为 Code Reviewer 角色,按检查清单审查]
真实效果
Subagents 解决了一个核心问题:角色状态的持久化 。当我切换到 @frontend-dev 时,它不会忘记"前端要用 CSS 变量";当我切到 @backend-dev 时,它不会把 customerName 和 customerCode 搞混------因为这些规则写在了角色文件里,而不是依赖对话上下文的记忆。
但它仍然有一个局限:这些角色是"串行"切换的。当我让 @frontend-dev 写组件的时候,@backend-dev 处于"休眠"状态,它不会自动知道前端定义了什么接口。要解决这个问题,需要更硬核的方案。
2. Agent Teams(代理团队):真正的多头脑协作
Agent Teams 是 Claude Code 的实验性功能,它允许真正的多实例并行------多个 Claude 进程同时运行,通过共享状态协作。
开启方式
powershell
# PowerShell 配置文件 ($PROFILE)
$env:CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1"
Windows Terminal 多标签页配置
我创建了一个 scripts/claude-team.ps1 脚本,一键启动 vupStack 的 AI 开发团队:
powershell
# scripts/claude-team.ps1
# 启动 vupStack AI 开发团队(Windows 版)
$PROJECT_ROOT = "D:\workspace\dataManager\vupstack"
$WINDOWS_TERMINAL_SETTINGS = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
Write-Host "正在启动 vupStack AI 开发团队..." -ForegroundColor Cyan
Write-Host "项目根目录: $PROJECT_ROOT" -ForegroundColor Gray
# 使用 wt.exe(Windows Terminal)启动多标签页
# 标签页 1: Architect
wt.exe -w 0 nt --title "🧠 Architect" -d "$PROJECT_ROOT" powershell -NoExit -Command "Write-Host '角色: Architect' -ForegroundColor Magenta; claude --role architect"
Start-Sleep -Milliseconds 500
# 标签页 2: Frontend Dev
wt.exe -w 0 nt --title "🎨 Frontend" -d "$PROJECT_ROOT\vupStack-frontend" powershell -NoExit -Command "Write-Host '角色: Frontend Dev' -ForegroundColor Blue; claude --role frontend-dev"
Start-Sleep -Milliseconds 500
# 标签页 3: Backend Dev
wt.exe -w 0 nt --title "⚙️ Backend" -d "$PROJECT_ROOT\vupStack-backend" powershell -NoExit -Command "Write-Host '角色: Backend Dev' -ForegroundColor Green; claude --role backend-dev"
Start-Sleep -Milliseconds 500
# 标签页 4: Test Writer
wt.exe -w 0 nt --title "🧪 Tester" -d "$PROJECT_ROOT" powershell -NoExit -Command "Write-Host '角色: Test Writer' -ForegroundColor Yellow; claude --role test-writer"
Start-Sleep -Milliseconds 500
# 标签页 5: Code Reviewer
wt.exe -w 0 nt --title "🔍 Reviewer" -d "$PROJECT_ROOT" powershell -NoExit -Command "Write-Host '角色: Code Reviewer' -ForegroundColor Red; claude --role code-reviewer"
Start-Sleep -Milliseconds 500
# 标签页 6: 共享状态看板
wt.exe -w 0 nt --title "📋 Board" -d "$PROJECT_ROOT" powershell -NoExit -Command "
while ($true) {
Clear-Host
Write-Host '=== vupStack AI 团队共享状态板 ===' -ForegroundColor Cyan
Write-Host ''
if (Test-Path '.claude/shared-state.md') {
Get-Content '.claude/shared-state.md' | ForEach-Object { Write-Host $_ }
} else {
Write-Host '等待共享状态...' -ForegroundColor Gray
}
Write-Host ''
Write-Host '刷新间隔: 5秒 | 按 Ctrl+C 退出' -ForegroundColor DarkGray
Start-Sleep -Seconds 5
}
"
Write-Host ""
Write-Host "✅ vupStack AI 团队已启动!" -ForegroundColor Green
Write-Host ""
Write-Host "标签页列表:" -ForegroundColor White
Write-Host " 🧠 Architect - 架构师(全局设计)" -ForegroundColor Magenta
Write-Host " 🎨 Frontend - 前端开发" -ForegroundColor Blue
Write-Host " ⚙️ Backend - 后端开发" -ForegroundColor Green
Write-Host " 🧪 Tester - 测试工程师" -ForegroundColor Yellow
Write-Host " 🔍 Reviewer - 代码审查" -ForegroundColor Red
Write-Host " 📋 Board - 共享状态看板" -ForegroundColor Cyan
Windows Terminal 布局效果
启动后,Windows Terminal 会变成这样:
+-------------------------------------------------------------+
| [🧠 Architect] [🎨 Frontend] [⚙️ Backend] [🧪 Tester] [🔍 Reviewer] [📋 Board] |
+-------------------------------------------------------------+
| |
| 🧠 Architect 标签页: |
| > 正在设计 License 状态展示的数据流... |
| > 前端需要:status, buildTime, errorMessage |
| > 后端需要:/api/licenses/{id}/build-status 接口 |
| |
+-------------------------------------------------------------+
| 🎨 Frontend 标签页: | ⚙️ Backend 标签页: |
| > 正在写 LicenseStatusBadge.vue... | > 正在写 LicenseBuildController.java... |
| > 定义接口类型... | > 定义 VO... |
| | |
+-------------------------+-----------------------------------+
PowerShell 7 优化
Windows 用户建议安装 PowerShell 7(跨平台,比 Windows PowerShell 5.1 好用太多):
powershell
# 使用 winget 安装 PowerShell 7
winget install Microsoft.PowerShell
# 在 PowerShell 7 中运行脚本
pwsh -File .\scripts\claude-team.ps1
分屏快捷键
Windows Terminal 支持快捷键快速分屏:
| 快捷键 | 功能 |
|---|---|
Alt + Shift + + |
垂直分屏 |
Alt + Shift + - |
水平分屏 |
Alt + Shift + d |
复制当前标签页 |
Ctrl + Shift + w |
关闭当前标签页 |
Ctrl + Tab |
切换到下一个标签页 |
共享状态机制
Agent Teams 的核心是共享状态。我在项目根目录创建了 .claude/shared-state.md,作为所有 Agent 的"共享白板":
markdown
# vupStack AI 团队共享状态板
## 当前任务
- **任务 ID**: LICENSE-STATUS-001
- **描述**: 版本详情页展示 License 构建状态
- **状态**: 进行中
## 架构决策(由 Architect 维护)
### 数据流
前端 VersionDetailsTab.vue
-> API: GET /api/licenses/{id}/build-status
-> 后端 LicenseBuildController
-> LicenseBuildService.getBuildStatus(id)
-> 返回 BuildStatusVO
### 接口契约
- **URL**: `GET /api/licenses/{id}/build-status`
- **响应**: `BuildStatusVO`
- `status`: String - "PENDING" | "BUILDING" | "SUCCESS" | "FAILED"
- `buildTime`: DateTime - 构建开始/完成时间
- `errorMessage`: String - 失败原因(仅 FAILED 时有值)
- `outputPath`: String - license 文件路径(仅 SUCCESS 时有值)
### 前端组件设计
- `LicenseStatusBadge.vue` - 状态徽章(颜色:PENDING=gray, BUILDING=blue, SUCCESS=green, FAILED=red)
- `LicenseBuildPanel.vue` - 构建详情面板(展开显示时间、日志、下载链接)
## 各 Agent 进度
### Frontend Dev
- [x] 接口类型定义 `BuildStatusVO`
- [x] `LicenseStatusBadge.vue` 组件
- [ ] `LicenseBuildPanel.vue` 组件
- [ ] 国际化 key
### Backend Dev
- [x] `BuildStatusVO`
- [x] `LicenseBuildController.getBuildStatus()`
- [ ] `LicenseBuildService.getBuildStatus()` 实现
- [ ] Mapper 查询
### Test Writer
- [ ] 后端单元测试
- [ ] 前端 API 测试
### Code Reviewer
- [ ] 等待实现完成
## 阻塞项
- 无
## 最近变更
- 2024-XX-XX 14:30: Architect 定义了接口契约
- 2024-XX-XX 14:35: Frontend Dev 开始写 Badge 组件
- 2024-XX-XX 14:36: Backend Dev 开始写 Controller
真实协作场景
[Architect 窗口]
我:设计一下 License 构建状态展示的方案
Architect:好的,我建议......(输出架构方案,写入 shared-state.md)
[Frontend 窗口]
Frontend Dev:(读取 shared-state.md)收到接口契约,开始实现 Badge 组件......
[Backend 窗口]
Backend Dev:(读取 shared-state.md)收到接口契约,开始实现 Controller......
[Test Writer 窗口]
Test Writer:(读取 shared-state.md,等待实现完成)准备测试用例......
[Reviewer 窗口]
Reviewer:(定期轮询 shared-state.md)等待审查......
优势
- 真正的并行:Frontend Dev 和 Backend Dev 同时工作,不需要等待对方
- 自动对齐:通过 shared-state.md,前后端自动同步接口契约
- 状态持久化:即使某个 Agent 的上下文满了,它可以从 shared-state.md 恢复状态
- 可审计:整个协作过程记录在文件中,事后可以复盘
局限
Agent Teams 目前还是实验性功能,偶尔会有"脑裂"问题------两个 Agent 同时修改 shared-state.md 导致冲突。解决方案是给每个 Agent 分配独立的写入区域,或者使用更正式的协作工具(比如 Git 本身)。
3. Git Worktree(工作树):分支级的硬隔离
Git Worktree 是最硬核的并行方案。它允许你在同一个仓库的多个分支上同时工作,每个分支有独立的物理目录。
适用场景
- 大范围重构(比如把 vupStack 的 License 模块从同步改为异步)
- 紧急 Bug 修复(生产环境 License 构建失败,需要热修复)
- 防止代码改动在文件系统层面冲突(前端在改 Vue 组件,后端在改 Java 类)
实战操作
powershell
# 当前在 master 分支,正在开发新功能
# 突然接到紧急任务:生产环境 License 构建失败,需要热修复
# 1. 创建独立工作树,基于 master 分支创建 hotfix 分支(Windows 路径)
git worktree add D:\workspace\dataManager\vupstack-hotfix -b hotfix/license-build-fail
# 2. 进入新目录,启动独立的 Claude 实例
cd D:\workspace\dataManager\vupstack-hotfix
claude
# 3. 在这个独立环境里修复 Bug
# - 修改 LicenseBuildServiceImpl.java
# - 添加防御性代码
# - 跑测试验证
# 4. 修复完成,提交并推送
git add .
git commit -m "fix(license): 修复生产环境 License 构建失败问题"
git push origin hotfix/license-build-fail
# 5. 回到主开发目录
cd D:\workspace\dataManager\vupstack
# 6. 合并热修复(如果主分支也需要这个修复)
git fetch origin
git cherry-pick hotfix/license-build-fail
# 7. 清理工作树
git worktree remove D:\workspace\dataManager\vupstack-hotfix
git branch -d hotfix/license-build-fail
多工作树并行开发
更激进的做法是:为每个 Agent 分配一个工作树。
powershell
# 创建前端开发工作树(Windows 路径)
git worktree add D:\workspace\dataManager\vupstack-frontend-dev -b feature/license-status-frontend
# 创建后端开发工作树
git worktree add D:\workspace\dataManager\vupstack-backend-dev -b feature/license-status-backend
# 创建测试工作树
git worktree add D:\workspace\dataManager\vupstack-test -b feature/license-status-tests
# 现在你有四个独立的物理目录:
# D:\workspace\dataManager\vupstack - 主分支,整合用
# D:\workspace\dataManager\vupstack-frontend-dev - 前端开发
# D:\workspace\dataManager\vupstack-backend-dev - 后端开发
# D:\workspace\dataManager\vupstack-test - 测试开发
每个工作树可以启动独立的 Claude 实例,完全物理隔离,不会互相干扰。
vupStack 实战:License 模块重构
我们有一次大规模重构:把 License 构建从同步改为异步(因为构建过程要 SSH 到远程服务器执行脚本,同步等待会阻塞 HTTP 请求)。
powershell
# 主目录继续日常开发
cd D:\workspace\dataManager\vupstack
# ... 日常维护 ...
# 重构目录进行大规模改动
cd D:\workspace\dataManager\vupstack-refactor
claude --role architect
# Architect 设计异步架构:
# 1. 前端轮询接口 GET /api/license-builds/{id}/status
# 2. 后端提交任务到线程池
# 3. LicenseBuildTask 异步执行 SSH 脚本
# 4. 状态存储在数据库,前端轮询获取
# 前端工作树实现轮询逻辑
cd D:\workspace\dataManager\vupstack-refactor-frontend
claude --role frontend-dev
# 实现 usePolling composable,轮询构建状态
# 后端工作树实现异步任务
cd D:\workspace\dataManager\vupstack-refactor-backend
claude --role backend-dev
# 实现 LicenseBuildTask、线程池、状态机
# 测试工作树补测试
cd D:\workspace\dataManager\vupstack-refactor-test
claude --role test-writer
# 补并发测试、状态机测试
重构完成后,通过 Git 合并回主分支:
bash
cd D:\workspace\dataManager\vupstack
git merge feature/license-async-refactor
# 解决冲突(如果有的话)
# 跑完整测试套件
mvn test
npm run test
物理隔离 vs 逻辑隔离
| 方案 | 隔离级别 | 适用场景 | 开销 |
|---|---|---|---|
| Subagents | 逻辑(角色切换) | 小功能,单文件改动 | 低 |
| Agent Teams | 逻辑(多窗口) | 中等功能,前后端联动 | 中 |
| Git Worktree | 物理(独立目录) | 大重构,紧急修复 | 高 |
物理隔离的优势是"绝对可靠"。即使 Claude 在某个工作树里"发疯"了(比如误删了 src/ 目录),其他工作树完全不受影响。这在工业级开发中很重要------你不能让重构实验毁掉正在运行的生产分支。
4. Workflow Orchestration(工作流编排)
前面三种方案解决的是"并行执行"问题,Workflow Orchestration 解决的是"流程规范"问题。
Plan 模式:先规划,后动手
Claude Code 的 Plan 命令(或 /plan)会强制执行"先规划、后执行"的工作流:
我:/plan 实现 License 构建状态展示功能
Claude:
## 计划:License 构建状态展示
### 阶段 1:架构设计
- [ ] 定义前后端接口契约
- [ ] 设计数据库变更(如有)
### 阶段 2:后端实现
- [ ] 创建 BuildStatusVO
- [ ] 实现 LicenseBuildController.getBuildStatus()
- [ ] 实现 LicenseBuildService.getBuildStatus()
- [ ] 添加 Mapper 查询
### 阶段 3:前端实现
- [ ] 创建 LicenseStatusBadge.vue
- [ ] 创建 LicenseBuildPanel.vue
- [ ] 更新 VersionDetailsTab.vue 引入新组件
- [ ] 添加国际化 key
### 阶段 4:测试
- [ ] 后端单元测试
- [ ] 前端 API 测试
- [ ] E2E 测试
### 阶段 5:审查
- [ ] Code Review
- [ ] 运行 check:i18n
- [ ] 运行 build 验证
请确认计划后,我将按阶段执行。
我:确认
Claude:开始执行阶段 1......
Plan 模式的核心价值是解耦思考与执行。在普通模式下,Claude 是"边想边做",容易陷入局部最优;在 Plan 模式下,Claude 先完成全局思考,再按步骤执行,每一步都可以验证。
CLAUDE.md 固化:即插即用的开发标准
vupStack 项目根目录的 CLAUDE.md 文件是整个工作流的"宪法":
markdown
# CLAUDE.md
## 工作流指令(最高优先级)
### 1. 任务分解
所有功能需求必须经过 Plan 模式分解为可验证的子任务。
### 2. 角色分配
根据任务类型自动选择角色:
- 架构设计 -> @architect
- 前端开发 -> @frontend-dev
- 后端开发 -> @backend-dev
- 测试 -> @test-writer
- 审查 -> @code-reviewer
### 3. 并行执行规范
- 前后端开发可并行
- 测试必须在实现完成后串行执行
- 审查必须在测试通过后执行
### 4. 完成检查清单
任何 fix / feat / refactor 完成后必须:
1. 运行单元测试(后端 `mvn test`,前端 `npm run test:unit`)
2. 同步数据库 SQL(如有 DDL 变更)
3. 同步国际化(如有新增用户可见文本)
4. 运行 `npm run build` 验证前端构建
### 5. 提交规范
:
``` Types: feat, fix, refactor, docs, test, chore, perf, ci ```
这个文件的作用类似于团队的"开发手册",但它是给 AI 看的。新成员加入项目时,不需要花一周时间"熟悉代码风格",Claude 读取 CLAUDE.md 后就能立即按规范工作。
组合使用:Plan + Subagents + Git Worktree
最工业级的用法是把所有方案组合起来:
1. 在主目录执行 /plan,生成任务分解
2. 根据计划创建 Git Worktree(前端、后端、测试)
3. 在每个 Worktree 启动 Claude,加载对应 Subagent 角色
4. 各 Agent 并行执行子任务
5. 完成后合并回主分支,运行完整检查清单
三、Routines:向"无人值守"跨越
如果说 Agent Teams 是"多人协作",Routines 就是"无人值守"。
Routines 是 Claude Code 的云端调度功能,允许你把任务打包丢给云端运行,不需要本地终端保持连接。
三类触发机制
1. 定时触发
yaml
# .claude/routines/daily-review.yaml
name: daily-code-review
schedule: "0 9 * * 1-5" # 工作日早上 9 点
tasks:
- name: 检查昨日提交
command: |
git log --since="yesterday" --pretty=format:"%h %s" > /tmp/yesterday-commits.txt
- name: 运行代码审查
command: |
claude --role code-reviewer --input /tmp/yesterday-commits.txt
- name: 发送报告
command: |
cat /tmp/review-report.txt | mail -s "vupStack 每日代码审查" team@semitronix.com
每天早上 9 点,Routines 会自动:
- 拉取昨日提交
- 调用 Code Reviewer Agent 审查
- 发送审查报告到团队邮箱
2. API 触发
bash
# 接入 CI/CD 流水线
# .gitlab-ci.yml
stages:
- build
- test
- ai-review
ai-review:
stage: ai-review
script:
- |
curl -X POST https://api.anthropic.com/v1/routines \
-H "Authorization: Bearer $CLAUDE_API_KEY" \
-d '{
"routine": "pr-review",
"params": {
"repo": "vupstack",
"pr_id": "$CI_MERGE_REQUEST_IID",
"diff_url": "$CI_MERGE_REQUEST_DIFF_URL"
}
}'
每次提交 MR 时,自动触发 Claude 进行代码审查,审查结果作为评论添加到 MR 中。
3. 事件触发
yaml
# .claude/routines/pr-review.yaml
name: pr-review
trigger: github-pr
tasks:
- name: 获取 PR diff
command: |
gh pr view $PR_ID --json files > /tmp/pr-files.json
- name: 安全审查
command: |
claude --role security-reviewer --input /tmp/pr-files.json
- name: 质量审查
command: |
claude --role code-reviewer --input /tmp/pr-files.json
- name: 发布审查结果
command: |
gh pr comment $PR_ID --body-file /tmp/review-result.md
终极形态:Routines + Agent Teams = 无人值守生产线
GitHub PR 提交
-> Routines 触发(云端)
-> 启动 Agent Teams(5 个并行 Agent)
-> Architect:检查架构影响
-> Security Reviewer:安全检查
-> Code Reviewer:质量检查
-> Test Writer:检查测试覆盖
-> Frontend/Backend Reviewer:领域检查
-> 汇总审查结果
-> 发布 PR 评论
-> 如果通过,自动添加 "AI-Approved" 标签
这个流程在 vupStack 中的实际应用:
开发者提交 PR:"feat(license): 添加 License 构建状态展示"
|
v
Routines 自动触发审查
|
v
Security Reviewer:检查是否有新的 SSH 命令注入风险
-> LicenseScriptExecutor 已经用了参数化输入,通过
|
v
Code Reviewer:检查函数长度、文件长度、命名规范
-> LicenseBuildController.getBuildStatus() 48 行,通过
-> BuildStatusVO 字段命名规范,通过
|
v
Test Writer:检查测试覆盖
-> 新增 LicenseBuildStatusTest.java,覆盖率 87%,通过
|
v
Frontend Reviewer:检查 Vue 组件规范
-> LicenseStatusBadge.vue 使用 CSS 变量,通过
-> 国际化 key 已添加,通过
|
v
发布审查结果:"AI 审查通过,5/5 项检查全部通过"
当前局限
Routines 目前还是预览功能,vupStack 团队还没有完全迁移过去。现在的折中方案是:在 Windows 上用"任务计划程序" + PowerShell 脚本模拟 Routines:
powershell
# scripts/daily-review.ps1
# 每日自动代码审查(Windows 版)
$PROJECT_ROOT = "D:\workspace\dataManager\vupstack"
$LOG_FILE = "$PROJECT_ROOT\.claude\reviews\daily-$(Get-Date -Format 'yyyyMMdd').md"
# 确保目录存在
New-Item -ItemType Directory -Path "$PROJECT_ROOT\.claude\reviews" -Force | Out-Null
# 获取昨日提交
$commits = git -C $PROJECT_ROOT log --since="yesterday" --pretty=format:"%h %s"
if ($commits) {
# 写入临时文件
$commits | Out-File -FilePath "$env:TEMP\yesterday-commits.txt" -Encoding UTF8
# 运行代码审查(模拟,实际需接入 Claude API)
$review = @"
# vupStack 每日代码审查报告
生成时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
## 昨日提交
$commits
## 审查结果
[此处为模拟输出,实际接入 Claude API 后自动填充]
"@
$review | Out-File -FilePath $LOG_FILE -Encoding UTF8
Write-Host "审查报告已生成: $LOG_FILE" -ForegroundColor Green
} else {
Write-Host "昨日无提交,跳过审查" -ForegroundColor Yellow
}
创建 Windows 计划任务:
powershell
# 创建每日 9:00 执行的计划任务
$action = New-ScheduledTaskAction -Execute "pwsh.exe" -Argument "-File D:\workspace\dataManager\vupstack\scripts\daily-review.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "09:00"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName "vupStack-Daily-Code-Review" -Action $action -Trigger $trigger -Settings $settings
Write-Host "计划任务已创建!每天 9:00 自动执行代码审查" -ForegroundColor Green
四、工业级 AI 开发的 5 步闭环
把前面的所有方案整合起来,vupStack 团队形成了一套"工业级 AI 开发流水线":
Step 1:任务分解(Plan 模式)
产品经理:"版本详情页要展示 License 构建状态"
|
v
我:/plan 在版本详情页添加 License 构建状态展示
|
v
Claude(Architect 角色):
输出:
1. 后端新增 GET /api/licenses/{id}/build-status
2. 前端新增 LicenseStatusBadge + LicenseBuildPanel
3. 数据库无需变更(已有状态字段)
4. 测试:后端单元测试 + 前端组件测试
5. 国际化:4 个状态值的 i18n key
Step 2:角色分配(Agent Teams)
bash
# 启动团队
./scripts/claude-team.sh
# 在 Architect 窗口确认架构方案
# 在 Frontend 窗口分配 Badge 组件
# 在 Backend 窗口分配 Controller + Service
# 在 Test 窗口准备测试用例
# 在 Reviewer 窗口设置审查清单
Step 3:并行执行(Git Worktree + Agent Teams)
bash
# 前端工作树
cd D:\workspace\dataManager\vupstack-frontend-dev
# Claude(Frontend Dev)实现 LicenseStatusBadge.vue
# 使用 CSS 变量:--app-status-pending, --app-status-building, etc.
# 使用 i18n:$t('license.status.pending'), etc.
# 后端工作树
cd D:\workspace\dataManager\vupstack-backend-dev
# Claude(Backend Dev)实现 LicenseBuildController.getBuildStatus()
# 返回 BuildStatusVO,状态值严格匹配前端约定
# 两个工作树同时推进,通过 shared-state.md 同步接口契约
Step 4:整合 Review(Subagents)
# 合并到主分支
cd D:\workspace\dataManager\vupstack
git merge feature/license-status-frontend
git merge feature/license-status-backend
# 调用审查 Agent
我:@code-reviewer 审查一下这个 PR
Code Reviewer:
- [PASS] 安全检查:无硬编码密钥,无 SQL 注入
- [PASS] 质量检查:函数 < 50 行,文件 < 800 行
- [PASS] 业务规则:customerName 处理正确
- [WARN] 测试覆盖:前端组件测试缺少 errorMessage 展示分支
- [INFO] 建议:Badge 组件可以添加 hover tooltip
我:@test-writer 补充 errorMessage 的测试
Test Writer:补充 LicenseStatusBadge.error.spec.ts
Step 5:代码合并(Git Worktree 物理验证)
powershell
# 创建验证工作树(Windows 路径)
git worktree add D:\workspace\dataManager\vupstack-verify -b verify/license-status
cd D:\workspace\dataManager\vupstack-verify
# 完整验证
npm run build # 前端构建
mvn test # 后端测试
npm run check:i18n # 国际化检查
# 全部通过后,合并到 master
cd D:\workspace\dataManager\vupstack
git checkout master
git merge verify/license-status
# 清理
git worktree remove D:\workspace\dataManager\vupstack-verify
git branch -d verify/license-status
五、总结:如何选择你的并行方案?
| 场景 | 推荐方案 | vupStack 实战案例 |
|---|---|---|
| 需要角色分工 | Subagents | 日常开发中切换 Frontend/Backend/Test 角色 |
| 需要多头脑协作 | Agent Teams | License 模块前后端同步开发 |
| 需要分支硬隔离 | Git Worktree | License 同步改异步的大规模重构 |
| 需要无人值守 | Routines | 每日自动代码审查(预览中) |
决策流程图
开始新任务
|
v
任务复杂度?
|
+-- 简单(单文件改动) --> 用 Subagents,一个实例切换角色
|
+-- 中等(前后端联动) --> 用 Agent Teams,多窗口并行
|
+-- 复杂(大规模重构) --> 用 Git Worktree,物理隔离
|
+-- 重复性(日常审查) --> 用 Routines,无人值守
分享金句(建议背诵,技术分享时假装不经意说出)
"Claude Code 的上限,取决于你把它当成一个只会排队的程序员,还是一个能同时调度的 AI 团队。"
"在工业级开发中,物理隔离(Worktree)比逻辑理解更可靠,任务调度(Routines)比手动干预更高效。"
"单实例 Claude 就像那个什么都会但一次只能做一件事的同事------你让他写前端,他就忘了后端的约定;你让他写测试,他就忘了业务的边界。多实例不是奢侈,是刚需。"
"Git Worktree 是我用过最像'平行宇宙'的 Git 功能。在这个宇宙里你正在重构 License 模块,在另一个宇宙里你正在热修复生产 Bug,两个宇宙互不干扰,直到你决定合并它们。"
"Plan 模式最大的价值不是让 Claude 更聪明,而是让它的'聪明'可验证。没有 Plan 的 Claude 是艺术家,有 Plan 的 Claude 是工程师。"
最后的自嘲
写到这里,我突然意识到一个问题:这篇文章本身就是用单实例 Claude 写的。一个鼓吹"多实例并行"的文章,却诞生于单实例的孤独敲击------这大概就是程序员的宿命吧。我们总是在用当下的工具,想象未来的工作流;就像用 Windows Terminal 的人给 iTerm2 写好评,用 PowerShell 的人给 zsh 写安利。
但无论如何,vupStack 的 License 模块现在确实跑在多实例并行开发模式上了。前端 Badge 组件和后端 Controller 是同时写的,测试是自动补的,审查是批量做的------虽然 setup 这些流程花了我整整两天时间,但之后的每个功能都省下了至少 30% 的"前后端对齐"时间。
算笔账:两天 setup,每次省 30%,第七个功能就回本了。而我们已经做到第十二个功能了。
所以,如果你还在用单实例 Claude 苦苦支撑大型项目------朋友,该升级了。不是 Claude 不够聪明,是你没有给它一个团队。
毕竟,简历上写的"精通团队协作",总不能只指人类同事吧?