多 Agent 协同工作流与管控平台完整指南
本系统是基于 OpenClaw 多 Agent 框架 与 Claude Code AI 编程助手 构建的端到端研发自动化平台,实现从需求分析到生产部署的全流程自动化。系统支持各研发角色的岗位 Agents 协同工作,并在关键节点提供人机协同能力。
| 组件 | 技术选型 | 作用 |
|---|---|---|
| 多 Agent 框架 | OpenClaw v2026.3+ | Agent 编排与通信 |
| AI 编程核心 | Claude Code + Claude Sonnet 4.6 | 代码生成与理解 |
| 持续集成 | Jenkins / GitHub Actions | CI/CD流水线 |
| 容器化 | Docker + K8S (KubeSphere) | 应用部署与管理 |
| 自动化测试 | Playwright + Jest + Pytest | 全栈测试覆盖 |
| API 管理 | OpenAPI 3.0 + Swagger | 接口规范与文档 |
系统定义了以下专业 Agent 角色,每个角色都有独立的 workspace、人设和职责边界:
{
"agents": {
"defaults": {
"workspace": "~/.openclaw/workspace"
},
"list": [
{
"id": "orchestrator",
"name": "Orchestrator-Agent",
"default": true,
"workspace": "~/.openclaw/workspace-orchestrator",
"model": "deepv-easyclaw/claude-opus-4"
},
{
"id": "product-agent",
"name": "Product-Agent",
"workspace": "~/.openclaw/workspace-product",
"model": "deepv-easyclaw/claude-sonnet-4-6"
},
{
"id": "backend-architect",
"name": "Backend-Architect-Agent",
"workspace": "~/.openclaw/workspace-backend",
"model": "deepv-easyclaw/claude-sonnet-4-6"
},
{
"id": "frontend-architect",
"name": "Frontend-Architect-Agent",
"workspace": "~/.openclaw/workspace-frontend",
"model": "deepv-easyclaw/claude-sonnet-4-6"
},
{
"id": "api-designer",
"name": "API-Designer-Agent",
"workspace": "~/.openclaw/workspace-api",
"model": "deepv-easyclaw/claude-haiku-4-5"
},
{
"id": "fullstack-dev",
"name": "Fullstack-Developer-Agent",
"workspace": "~/.openclaw/workspace-dev",
"model": "deepv-easyclaw/claude-sonnet-4-6"
},
{
"id": "qa-test",
"name": "QA-Test-Agent",
"workspace": "~/.openclaw/workspace-qa",
"model": "deepv-easyclaw/claude-haiku-4-5"
},
{
"id": "devops",
"name": "DevOps-Agent",
"workspace": "~/.openclaw/workspace-devops",
"model": "deepv-easyclaw/claude-haiku-4-5"
},
{
"id": "ui-automation",
"name": "UI-Automation-Agent",
"workspace": "~/.openclaw/workspace-ui-test",
"model": "deepv-easyclaw/claude-sonnet-4-6"
}
]
},
"session": {
"dmScope": "per-account-channel-peer"
},
"bindings": [
{
"agentId": "orchestrator",
"match": { "channel": "feishu", "accountId": "main" }
},
{
"agentId": "product-agent",
"match": { "channel": "feishu", "accountId": "product" }
}
],
"channels": {
"feishu": {
"defaultAccount": "main",
"accounts": {
"main": {
"appId": "cli_xxx",
"appSecret": "xxx",
"botName": "研发协调机器人"
},
"product": {
"appId": "cli_yyy",
"appSecret": "yyy",
"botName": "产品助手"
}
}
}
}
}
# 添加子 Agent
openclaw agents add product-agent --workspace ~/.openclaw/workspace-product
# 配置主 Agent 调度权限
openclaw config set agents.list[0].subagents.allowAgents '["product-agent","backend-architect","frontend-architect"]' --json
# 为子 Agent 指定轻量模型(节省成本)
openclaw config set agents.list[5].model 'deepv-easyclaw/claude-haiku-4-5' --json
# 验证配置
openclaw agents list
openclaw channels status
# SOUL.md - Product-Agent
# SOUL.md - 产品助手
## 角色
我是产品助手,专注需求分析、PRD 文档撰写和用户故事地图创建。
## 职责
- 根据用户需求生成完整的 PRD 文档
- 创建用户故事地图和功能优先级
- 输出竞品分析报告
- 协助进行需求评审
## 风格
- 结构化输出,逻辑清晰
- 使用标准 PRD 模板
- 包含验收标准和成功指标
- 不确定的信息主动标注待确认
---
# AGENTS.md - Product-Agent
# AGENTS.md - 产品助手
## 我是谁
我是主 Agent 的产品助手,不是主 Agent。
## 行为规范
### ✅ 收到任务直接执行
- 不反问,不问确认,直接干
- 模糊需求先做假设,做完再补充说明
- 主动使用 openclaw_spawn 调用其他 Agent
### ✅ 输出格式
- 使用 Markdown 标准格式
- 包含版本历史和变更记录
- 标注信息来源和假设条件
### ❌ 禁止
- 不说"我是主 Agent"
- 不问"需要我创建子 Agent 吗"
- 不模仿主 Agent 的交互风格
需求可以通过以下方式输入系统:
# 产品需求文档 (PRD)
## 1. 文档信息
- **项目名称**: [项目名称]
- **版本号**: v1.0
- **创建日期**: 2026-03-14
- **最后更新**: 2026-03-14
- **负责人**: [产品经理]
## 2. 项目背景
### 2.1 业务背景
[描述项目的业务背景和要解决的问题]
### 2.2 目标用户
[描述目标用户群体和用户画像]
### 2.3 竞品分析
[主要竞品对比分析]
## 3. 产品目标
### 3.1 核心目标
- [目标 1]
- [目标 2]
### 3.2 成功指标
- [指标 1]: [具体数值]
- [指标 2]: [具体数值]
## 4. 功能需求
### 4.1 功能列表
| 优先级 | 功能模块 | 功能描述 | 用户价值 |
|--------|----------|----------|----------|
| P0 | [功能 1] | [描述] | [价值] |
| P1 | [功能 2] | [描述] | [价值] |
### 4.2 详细功能说明
#### 4.2.1 [功能 1]
**用户故事**: 作为 [用户角色], 我希望 [做什么], 以便 [达到什么目的]
**功能描述**:
[详细功能描述]
**验收标准**:
- [ ] 标准 1
- [ ] 标准 2
**原型图**:
[原型图链接]
## 5. 非功能需求
### 5.1 性能要求
- 响应时间: < 200ms
- 并发用户数:> 10000
### 5.2 安全要求
- [安全要求 1]
- [安全要求 2]
## 6. 里程碑计划
| 阶段 | 开始日期 | 结束日期 | 交付物 |
|------|----------|----------|--------|
| 需求评审 | 2026-03-14 | 2026-03-16 | PRD 终稿 |
| 技术开发 | 2026-03-17 | 2026-03-31 | 可运行版本 |
| 测试验收 | 2026-04-01 | 2026-04-07 | 测试报告 |
| 上线发布 | 2026-04-08 | 2026-04-10 | 生产环境 |
## 7. 风险评估
| 风险项 | 可能性 | 影响程度 | 应对措施 |
|--------|--------|----------|----------|
| [风险 1] | 中 | 高 | [措施] |
## 8. 附录
### 8.1 术语表
[专业术语解释]
### 8.2 参考资料
[相关文档链接]
Agent 完成工作:
人工介入工作:
反馈循环:
# 用户故事地图示例
## 用户活动地图
### 用户旅程:注册 → 登录 → 浏览 → 下单 → 支付
| 阶段 | 活动 | 任务 | 用户故事 |
|----------|----------------|-------------------------------|-----------------------------------------------|
| 注册 | 账号创建 | 填写手机号 | 作为新用户,我希望用手机号注册,以便快速开始 |
| | | 获取验证码 | 作为用户,我希望收到短信验证码,以确保安全 |
| | 账号验证 | 输入验证码 | 作为用户,我希望验证我的手机号 |
| 登录 | 身份验证 | 手机号 + 密码登录 | 作为老用户,我希望快速登录 |
| | | 短信验证码登录 | 作为用户,我希望免密登录 |
| 浏览 | 商品搜索 | 关键词搜索 | 作为用户,我希望搜索想要的商品 |
| | 商品筛选 | 按价格/销量/评价筛选 | 作为用户,我希望快速找到优质商品 |
| 下单 | 加入购物车 | 选择规格数量 | 作为用户,我希望批量购买商品 |
| | 提交订单 | 确认收货地址 | 作为用户,我希望选择默认地址 |
| 支付 | 选择支付方式 | 微信/支付宝/银行卡 | 作为用户,我希望多种支付方式 |
| | 完成支付 | 跳转第三方支付 | 作为用户,我希望安全支付 |
# 后端技术架构设计文档
## 1. 系统架构概览
### 1.1 架构图
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Client │────▶│ Gateway │────▶│ Service │
│ (Web/Mobile)│ │ (Nginx) │ │ Layer │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼
┌─────────────┐
│ Data │
│ Layer │
└─────────────┘
```
### 1.2 技术栈选型
| 层级 | 技术选型 | 选型理由 |
|------------|-----------------------|------------------------------|
| Web 框架 | Spring Boot 3.x | 生态完善,性能优秀 |
| ORM | MyBatis Plus | 灵活高效 |
| 缓存 | Redis 7.x | 高性能 KV 存储 |
| 消息队列 | RabbitMQ / Kafka | 异步解耦 |
| 数据库 | MySQL 8.0 / PostgreSQL| 稳定可靠 |
| 搜索引擎 | Elasticsearch 8.x | 全文检索 |
## 2. 微服务拆分
### 2.1 服务划分
| 服务名称 | 职责描述 | 端口 | 依赖服务 |
|------------------|------------------------|-------|--------------------|
| user-service | 用户管理 | 8081 | - |
| order-service | 订单管理 | 8082 | user, product |
| product-service | 商品管理 | 8083 | - |
| payment-service | 支付处理 | 8084 | order |
| notification-svc | 通知服务 | 8085 | user |
### 2.2 服务间通信
- 同步调用:RESTful API + Feign
- 异步消息:RabbitMQ / Kafka
- 服务发现:Nacos / Consul
## 3. 数据库设计
### 3.1 ER 图
[ER 图描述]
### 3.2 核心表结构
```sql
-- 用户表
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE,
phone VARCHAR(20),
password_hash VARCHAR(255) NOT NULL,
status TINYINT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_username (username),
INDEX idx_phone (phone)
);
-- 订单表
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(50) UNIQUE NOT NULL,
user_id BIGINT NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status TINYINT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user_id (user_id),
INDEX idx_status (status)
);
```
## 4. API 设计规范
### 4.1 RESTful 规范
- 资源命名:复数名词,小写,连字符
- HTTP 方法:GET/POST/PUT/DELETE
- 状态码:标准 HTTP 状态码
- 版本控制:URL 路径版本 /api/v1/
### 4.2 统一响应格式
```json
{
"code": 200,
"message": "success",
"data": {},
"timestamp": 1710403200000
}
```
## 5. 安全设计
### 5.1 认证授权
- JWT Token 认证
- OAuth2.0 第三方登录
- RBAC 权限模型
### 5.2 数据安全
- 敏感数据加密存储
- SQL 注入防护
- XSS 攻击防护
## 6. 性能优化
### 6.1 缓存策略
- 多级缓存:本地缓存 + Redis
- 缓存穿透/击穿/雪崩解决方案
### 6.2 数据库优化
- 读写分离
- 分库分表策略
- 慢查询优化
## 7. 监控与日志
### 7.1 监控指标
- 应用性能监控 (APM)
- JVM 监控
- 业务指标监控
### 7.2 日志方案
- ELK 日志收集
- 结构化日志
- 链路追踪 (SkyWalking)
# 前端技术架构设计文档
## 1. 技术栈选型
### 1.1 核心框架
| 技术 | 版本 | 用途 |
|--------------|---------|--------------------|
| React | 18.x | UI 框架 |
| TypeScript | 5.x | 类型系统 |
| Next.js | 14.x | SSR/SSG框架 |
| TailwindCSS | 3.x | CSS 框架 |
### 1.2 状态管理
- Zustand: 轻量级全局状态
- React Query: 服务端状态管理
- Formik + Yup: 表单处理
### 1.3 UI 组件库
- Ant Design / Material-UI
- 自定义业务组件库
## 2. 项目结构
```
src/
├── components/ # 通用组件
│ ├── common/ # 基础组件
│ ├── business/ # 业务组件
│ └── layouts/ # 布局组件
├── pages/ # 页面组件
├── hooks/ # 自定义 Hooks
├── stores/ # 状态管理
├── services/ # API 服务
├── utils/ # 工具函数
├── types/ # TypeScript 类型
├── styles/ # 全局样式
└── config/ # 配置文件
```
## 3. 组件设计规范
### 3.1 组件分类
- **基础组件**: Button, Input, Modal 等
- **业务组件**: ProductCard, OrderForm 等
- **页面组件**: HomePage, DetailPage 等
### 3.2 组件开发规范
```typescript
// 组件示例
interface ProductCardProps {
id: string;
title: string;
price: number;
image: string;
onAddToCart?: (id: string) => void;
}
export const ProductCard: React.FC = ({
id,
title,
price,
image,
onAddToCart
}) => {
return (
{title}
¥{price}
);
};
```
## 4. API 集成方案
### 4.1 Axios 封装
```typescript
// services/request.ts
import axios from 'axios';
const request = axios.create({
baseURL: '/api/v1',
timeout: 10000,
});
request.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
export default request;
```
### 4.2 React Query 配置
```typescript
// hooks/useProducts.ts
import { useQuery } from '@tanstack/react-query';
export const useProducts = (categoryId?: string) => {
return useQuery({
queryKey: ['products', categoryId],
queryFn: () => fetchProducts(categoryId),
staleTime: 5 * 60 * 1000, // 5 分钟
});
};
```
## 5. 性能优化
### 5.1 代码分割
- 路由级别懒加载
- 组件级别动态导入
- 图片懒加载
### 5.2 渲染优化
- React.memo 记忆化
- useMemo/useCallback 缓存
- 虚拟列表
### 5.3 构建优化
- Tree Shaking
- 代码压缩
- CDN 加速
## 6. 测试策略
- 单元测试:Jest + React Testing Library
- E2E 测试:Playwright
- 视觉回归测试:Chromatic
Agent 完成工作:
人工介入工作:
# API 接口设计文档 (OpenAPI 3.0)
openapi: 3.0.3
info:
title: 电商平台 API
description: 电商平台后端 API 接口文档
version: 1.0.0
contact:
name: API Support
email: api@example.com
servers:
- url: https://api.example.com/v1
description: 生产环境
- url: https://staging-api.example.com/v1
description: 预发环境
tags:
- name: 用户
description: 用户相关接口
- name: 商品
description: 商品相关接口
- name: 订单
description: 订单相关接口
paths:
/users/register:
post:
tags:
- 用户
summary: 用户注册
operationId: registerUser
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- username
- password
- phone
properties:
username:
type: string
minLength: 3
maxLength: 50
password:
type: string
minLength: 8
format: password
phone:
type: string
pattern: '^1[3-9]\\d{9}$'
responses:
'201':
description: 注册成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'400':
description: 请求参数错误
'409':
description: 用户名已存在
/products:
get:
tags:
- 商品
summary: 商品列表
operationId: listProducts
parameters:
- name: categoryId
in: query
schema:
type: string
- name: page
in: query
schema:
type: integer
default: 1
- name: pageSize
in: query
schema:
type: integer
default: 20
responses:
'200':
description: 成功
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Product'
total:
type: integer
page:
type: integer
pageSize:
type: integer
components:
schemas:
UserResponse:
type: object
properties:
id:
type: integer
username:
type: string
email:
type: string
createdAt:
type: string
format: date-time
Product:
type: object
properties:
id:
type: integer
title:
type: string
price:
type: number
format: float
image:
type: string
stock:
type: integer
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
# Mock 数据生成配置 (Prism Mock Server)
# 启动 Mock 服务器
prism mock openapi.yaml --host 0.0.0.0 --port 4010
# Mock 数据示例 (MSW)
import { rest } from 'msw';
import { setupServer } from 'msw/node';
export const handlers = [
rest.get('/api/v1/products', (req, res, ctx) => {
return res(
ctx.json({
data: [
{
id: 1,
title: 'iPhone 15 Pro',
price: 7999,
image: '/images/iphone15.jpg',
stock: 100
}
],
total: 1,
page: 1,
pageSize: 20
})
);
}),
rest.post('/api/v1/users/register', (req, res, ctx) => {
return res(
ctx.status(201),
ctx.json({
id: 1,
username: req.body.username,
email: req.body.email,
createdAt: new Date().toISOString()
})
);
})
];
export const server = setupServer(...handlers);
# CLAUDE.md - 项目开发规范
## 项目约定
- **语言**: TypeScript 5.x + Python 3.12
- **后端框架**: Spring Boot 3.x / FastAPI
- **前端框架**: React 18 + Next.js 14
- **数据库**: MySQL 8.0 + Redis 7.x
- **代码规范**: ESLint + Prettier + Black
## 代码生成规则
1. 所有代码必须包含类型注解
2. 遵循 SOLID 原则
3. 函数长度不超过 50 行
4. 必须编写 JSDoc/Docstring
5. 错误处理必须完整
## 文件命名规范
- TypeScript: PascalCase for components, camelCase for utils
- Python: snake_case for modules, PascalCase for classes
- 测试文件:*.test.ts / test_*.py
## Git 提交规范
feat: 新功能
fix: 修复 bug
docs: 文档更新
style: 代码格式
refactor: 重构
test: 测试用例
chore: 构建/工具
# 后端代码生成示例 (Spring Boot)
// UserController.java
package com.example.ecommerce.controller;
import com.example.ecommerce.dto.UserRegisterRequest;
import com.example.ecommerce.dto.UserResponse;
import com.example.ecommerce.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
/**
* 用户注册接口
* @param request 注册请求体
* @return 用户信息
*/
@PostMapping("/register")
public ResponseEntity register(
@Valid @RequestBody UserRegisterRequest request) {
UserResponse response = userService.register(request);
return ResponseEntity.status(HttpStatus.CREATED).body(response);
}
@GetMapping("/{id}")
public ResponseEntity getUser(@PathVariable Long id) {
UserResponse response = userService.getById(id);
return ResponseEntity.ok(response);
}
}
---
# 前端代码生成示例 (React + TypeScript)
// ProductList.tsx
'use client';
import React from 'react';
import { useProducts } from '@/hooks/useProducts';
import { ProductCard } from '@/components/business/ProductCard';
import { LoadingSpinner } from '@/components/common/LoadingSpinner';
import { ErrorBoundary } from '@/components/common/ErrorBoundary';
interface ProductListProps {
categoryId?: string;
}
export const ProductList: React.FC = ({ categoryId }) => {
const { data, isLoading, error } = useProducts(categoryId);
if (isLoading) {
return ;
}
if (error) {
return ;
}
return (
{data?.map((product) => (
))}
);
};
# 代码审查检查清单
## 代码质量检查
- [ ] 代码符合命名规范
- [ ] 函数职责单一
- [ ] 无重复代码 (DRY)
- [ ] 错误处理完整
- [ ] 日志记录适当
## 安全检查
- [ ] 无 SQL 注入风险
- [ ] 无 XSS 漏洞
- [ ] 敏感数据加密
- [ ] 认证授权正确
- [ ] 输入验证完整
## 性能检查
- [ ] 无 N+1 查询
- [ ] 缓存使用合理
- [ ] 资源正确释放
- [ ] 异步处理适当
- [ ] 大数据量分页
## 测试覆盖
- [ ] 单元测试覆盖核心逻辑
- [ ] 边界条件测试
- [ ] 异常场景测试
- [ ] 集成测试完整
// 后端单元测试示例 (JUnit 5)
@Test
@DisplayName("用户注册 - 成功场景")
void registerUser_Success() {
// Given
UserRegisterRequest request = new UserRegisterRequest(
"testuser",
"password123",
"13800138000"
);
when(userRepository.existsByUsername(request.getUsername())).thenReturn(false);
when(passwordEncoder.encode(request.getPassword())).thenReturn("hashed");
// When
UserResponse response = userService.register(request);
// Then
assertNotNull(response.getId());
assertEquals(request.getUsername(), response.getUsername());
verify(userRepository).save(any(User.class));
}
@Test
@DisplayName("用户注册 - 用户名已存在")
void registerUser_UsernameExists() {
// Given
UserRegisterRequest request = new UserRegisterRequest(
"existinguser",
"password123",
"13800138000"
);
when(userRepository.existsByUsername(request.getUsername())).thenReturn(true);
// When & Then
assertThrows(DuplicateResourceException.class, () -> {
userService.register(request);
});
}
---
// 前端单元测试示例 (Jest + React Testing Library)
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { ProductList } from './ProductList';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const createWrapper = () => {
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } }
});
return ({ children }) => (
{children}
);
};
describe('ProductList', () => {
it('渲染商品列表', async () => {
render( , { wrapper: createWrapper() });
await waitFor(() => {
expect(screen.getByText('iPhone 15 Pro')).toBeInTheDocument();
});
});
it('加载状态显示 Spinner', () => {
render( , { wrapper: createWrapper() });
expect(screen.getByTestId('loading-spinner')).toBeInTheDocument();
});
it('错误状态显示错误信息', async () => {
render( , { wrapper: createWrapper() });
await waitFor(() => {
expect(screen.getByText(/加载失败/i)).toBeInTheDocument();
});
});
});
# 集成测试示例 (TestContainers + Spring Boot)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
class OrderIntegrationTest {
@Container
static MySQLContainer> mysql = new MySQLContainer<>("mysql:8.0")
.withDatabaseName("ecommerce_test")
.withUsername("test")
.withPassword("test");
@Container
static RedisContainer> redis = new RedisContainer<>("redis:7");
@DynamicPropertySource
static void properties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", mysql::getJdbcUrl);
registry.add("spring.redis.host", redis::getHost);
registry.add("spring.redis.port", () -> redis.getMappedPort(6379).toString());
}
@Autowired
private TestRestTemplate restTemplate;
@Test
@DisplayName("创建订单 - 完整流程")
void createOrder_FullFlow() {
// Given
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + getValidToken());
OrderCreateRequest request = new OrderCreateRequest(
List.of(new OrderItem(1L, 2)),
"北京市朝阳区 xxx"
);
// When
ResponseEntity response = restTemplate.postForEntity(
"/api/v1/orders",
new HttpEntity<>(request, headers),
OrderResponse.class
);
// Then
assertEquals(HttpStatus.CREATED, response.getStatusCode());
assertNotNull(response.getBody().getOrderNo());
}
}
| 检查项 | 阈值 | 检查工具 |
|---|---|---|
| 单元测试覆盖率 | ≥ 80% | Jacoco / Coverage.py |
| 代码重复率 | ≤ 5% | SonarQube |
| 圈复杂度 | ≤ 10 | SonarQube |
| 安全漏洞数 | 0 | Snyk / Dependabot |
| Lint 错误数 | 0 | ESLint / Pylint |
| 性能测试通过率 | 100% | JMeter / k6 |
# 后端 Dockerfile (Spring Boot)
FROM eclipse-temurin:17-jre-alpine AS builder
WORKDIR /app
COPY target/*.jar app.jar
RUN java -Djarmode=layertools -jar app.jar extract
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/dependencies/ ./
COPY --from=builder /app/spring-boot-loader/ ./
COPY --from=builder /app/snapshot-dependencies/ ./
COPY --from=builder /app/application/ ./
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD wget -qO- http://localhost:8080/actuator/health || exit 1
---
# 前端 Dockerfile (Next.js)
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
CMD ["node", "server.js"]
# Kubernetes Deployment (backend)
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
namespace: ecommerce
labels:
app: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: registry.example.com/ecommerce/user-service:v1.0.0
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: host
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: user-service
namespace: ecommerce
spec:
selector:
app: user-service
ports:
- port: 80
targetPort: 8080
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: user-service-ingress
namespace: ecommerce
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: api.example.com
http:
paths:
- path: /api/v1/users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 80
// Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
environment {
REGISTRY = 'registry.example.com'
IMAGE_NAME = 'ecommerce/user-service'
KUBECONFIG = credentials('kubeconfig')
}
stages {
stage('Checkout') {
steps {
git branch: 'main', url: 'https://github.com/example/ecommerce.git'
}
}
stage('Code Quality') {
steps {
sh 'mvn checkstyle:check'
sh 'mvn spotbugs:check'
}
}
stage('Unit Test') {
steps {
sh 'mvn test'
}
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
}
stage('Build Image') {
steps {
script {
docker.build("${REGISTRY}/${IMAGE_NAME}:${BUILD_ID}")
}
}
}
stage('Integration Test') {
steps {
sh 'mvn verify -Pintegration-test'
}
}
stage('Push Image') {
steps {
script {
docker.withRegistry("https://${REGISTRY}", credentials('docker-registry')) {
docker.image("${REGISTRY}/${IMAGE_NAME}:${BUILD_ID}").push()
docker.image("${REGISTRY}/${IMAGE_NAME}:${BUILD_ID}").push('latest')
}
}
}
}
stage('Deploy to K8S') {
steps {
sh '''
kubectl set image deployment/user-service \
user-service=${REGISTRY}/${IMAGE_NAME}:${BUILD_ID} \
-n ecommerce
kubectl rollout status deployment/user-service -n ecommerce
'''
}
}
stage('Smoke Test') {
steps {
sh '''
curl -f https://api.example.com/api/v1/users/health || exit 1
'''
}
}
}
post {
success {
echo '部署成功!'
}
failure {
echo '部署失败,执行回滚!'
sh '''
kubectl rollout undo deployment/user-service -n ecommerce
'''
}
}
}
// E2E 测试示例 (Playwright + TypeScript)
import { test, expect } from '@playwright/test';
test.describe('电商平台的用户购物流程', () => {
test.beforeEach(async ({ page }) => {
await page.goto('https://example.com');
});
test('完整购物流程:浏览→加购→下单→支付', async ({ page }) => {
// 1. 搜索商品
await page.fill('[data-testid="search-input"]', 'iPhone 15');
await page.click('[data-testid="search-button"]');
await expect(page).toHaveURL(/.*search.*q=iPhone/);
// 2. 浏览商品列表
const productList = page.locator('[data-testid="product-list"]');
await expect(productList).toBeVisible();
// 3. 添加到购物车
const firstProduct = productList.locator('[data-testid="product-card"]').first();
await firstProduct.hover();
await firstProduct.click('[data-testid="add-to-cart-btn"]');
// 4. 验证购物车
const cartBadge = page.locator('[data-testid="cart-badge"]');
await expect(cartBadge).toContainText('1');
// 5. 进入购物车
await page.click('[data-testid="cart-icon"]');
await expect(page).toHaveURL(/.*cart/);
// 6. 结算下单
await page.click('[data-testid="checkout-btn"]');
await page.fill('[data-testid="address-input"]', '北京市朝阳区 xxx');
await page.click('[data-testid="submit-order-btn"]');
// 7. 支付
await expect(page).toHaveURL(/.*payment/);
await page.click('[data-testid="pay-now-btn"]');
// 8. 验证订单成功
await expect(page.locator('[data-testid="order-success"]')).toBeVisible();
const orderNo = await page.locator('[data-testid="order-no"]').textContent();
expect(orderNo).toMatch(/^ORD\d+/);
});
test('用户登录流程', async ({ page }) => {
await page.click('[data-testid="login-btn"]');
await expect(page).toHaveURL(/.*login/);
await page.fill('[data-testid="username-input"]', 'testuser');
await page.fill('[data-testid="password-input"]', 'password123');
await page.click('[data-testid="submit-login-btn"]');
await expect(page.locator('[data-testid="user-avatar"]')).toBeVisible();
});
test('响应式布局测试 - 移动端', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
// 验证移动端菜单
const mobileMenu = page.locator('[data-testid="mobile-menu"]');
await expect(mobileMenu).toBeVisible();
// 验证商品卡片单列显示
const productCards = page.locator('[data-testid="product-card"]');
await expect(productCards.first()).toBeInViewport();
});
});
---
// 视觉回归测试
import { test, expect } from '@playwright/test';
test('首页视觉回归', async ({ page }) => {
await page.goto('https://example.com');
// 截取首页截图并与基线对比
await expect(page).toHaveScreenshot('homepage.png', {
fullPage: true,
maxDiffPixels: 100, // 允许的最大差异像素数
});
});
// 可访问性测试
import AxeBuilder from '@axe-core/playwright';
test('首页可访问性检查', async ({ page }) => {
await page.goto('https://example.com');
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
# Allure 测试报告配置
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
reporter: [
['html', { outputFolder: 'playwright-report' }],
['allure-playwright'],
['junit', { outputFile: 'test-results/junit.xml' }],
],
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
});
Agent 完成工作:
人工介入工作:
# 飞书机器人配置
{
"app_id": "cli_xxx",
"app_secret": "xxx",
"verification_token": "xxx",
"encrypt_key": "xxx",
"event_subscriptions": {
"im.message.receive_v1": true
}
}
# 消息路由配置
{
"bindings": [
{
"agentId": "orchestrator",
"match": {
"channel": "feishu",
"accountId": "main"
}
}
]
}
# 审批节点配置示例
approval_workflows:
prd_review:
name: "PRD 评审"
approvers:
- role: product_manager
- role: tech_lead
timeout_hours: 24
escalation: auto_skip # 超时自动跳过或升级
technical_design_review:
name: "技术方案评审"
approvers:
- role: architect
- role: security_team
timeout_hours: 48
code_review:
name: "代码审查"
approvers:
- role: senior_developer
auto_approve_threshold: 95 # 质量评分≥95 自动通过
uat_acceptance:
name: "UAT 验收"
approvers:
- role: product_owner
- role: business_stakeholder
required: true # 必须人工审批
# 任务状态查询命令
/orchestrator status [project-id]
# 返回示例
{
"project_id": "PROJ-2026-001",
"current_phase": "development",
"progress": {
"requirements": { "status": "completed", "approved_by": "张三" },
"design": { "status": "completed", "approved_by": "李四" },
"development": {
"status": "in_progress",
"completion": "65%",
"active_agents": ["fullstack-dev", "qa-test"]
},
"testing": { "status": "pending" },
"deployment": { "status": "pending" }
},
"blockers": [],
"next_milestone": "完成单元测试 (预计 2 小时)"
}
# 研发效能指标
metrics_dashboard:
velocity:
- 需求交付周期:3.5 天 (行业平均 7 天)
- 代码生成率:78%
- 自动化测试覆盖率:85%
quality:
- 缺陷密度:0.5 defects/KLOC
- 代码复用率:65%
- 技术债务指数:低
efficiency:
- 人工介入次数:2.3 次/项目
- Agent 任务成功率:94%
- 自动化部署成功率:98%
# 通过 IM 机器人启动项目
用户:创建一个电商平台项目,包含用户管理、商品管理、订单管理、支付功能
Orchestrator-Agent:
🎯 已接收项目需求,开始启动研发工作流...
📋 Phase 1: 需求分析 (Product-Agent)
✓ 正在分析需求...
✓ 生成用户故事地图...
✓ 创建 PRD 文档...
⏳ 等待人工评审...
[人工评审通过后]
🏗️ Phase 2: 技术方案设计 (Backend/Frontend-Architect-Agent)
✓ 后端架构设计完成
✓ 前端架构设计完成
✓ API 接口规范生成中...
🔌 Phase 3: API 协议设计 (API-Designer-Agent)
✓ OpenAPI 3.0 文档已生成
✓ Mock 服务器已启动
🔗 查看文档:http://localhost:4010/docs
💻 Phase 4: 代码开发 (Fullstack-Developer-Agent)
✓ 后端代码生成中... (预计 45 分钟)
✓ 前端代码生成中... (预计 30 分钟)
✅ Phase 5: 测试 (QA-Test-Agent)
⏳ 等待代码完成后启动...
🚀 Phase 6: 部署 (DevOps-Agent)
⏳ 等待测试通过后启动...
🎭 Phase 7: UI 验收 (UI-Automation-Agent)
⏳ 等待部署完成后启动...
A: 这是复制了主 Agent 的 AGENTS.md 导致的。必须为子 Agent 编写专属 AGENTS.md,明确说明"我是主 Agent 的 XX 助手,不是主 Agent"。
A: 检查是否误删了 channels.feishu 中的 allowFrom、dmPolicy、groupPolicy 字段。这些字段必须保留,否则健康监控会 stuck。
A: 为简单任务的子 Agent 配置轻量模型 (Haiku/Flash/mini),可以节省 3-5 倍成本。例如 API 设计、单元测试等任务可以用 Haiku。
A: 在审批配置中设置 timeout_hours 和 escalation 策略。可以选择超时自动跳过、升级到上级审批人或发送紧急通知。
A: 提高质量门禁阈值,启用自动修复机制。对于复杂业务逻辑,可以让人工先编写伪代码或详细注释,再让 Agent 实现。