Files
multiAgentTry/docs/project-audit-report.md
Claude Code 1719d1f1f9 重构 API 路由并新增工作流编排功能
后端:
- 重构 agents, heartbeats, locks, meetings, resources, roles, workflows 路由
- 新增 orchestrator 和 providers 路由
- 新增 CLI 调用器和流程编排服务
- 添加日志配置和依赖项

前端:
- 更新 AgentsPage、SettingsPage、WorkflowPage 页面
- 扩展 api.ts 新增 API 接口

其他:
- 清理测试 agent 数据文件
- 新增示例工作流和项目审计报告

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:36:25 +08:00

474 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Swarm Command Center - 项目审计报告
> 初始审计日期2026-03-10
> 修复完成日期2026-03-10
> 审计范围:需求文档 vs 实际实现的完整比对
---
## 一、项目总体进度
### 修复后状态2026-03-10 更新)
| 模块 | 完成度 | 状态 |
|------|--------|------|
| 后端服务层 (Services) | **95%** | ✅ 9 个核心服务全部实现并通过测试 |
| 后端路由层 (Routers) | **100%** | ✅ **已修复** 全部 10 个路由模块正确接入服务层 |
| 后端 CLI | **100%** | ✅ 所有命令已实现并正确调用服务层 |
| 前端页面 | **95%** | ✅ 6 个页面全部实现,工作流上传已补全 |
| 前端 API 客户端 | **100%** | ✅ **已修复** 封装全部 API 模块(含 Agent 控制) |
| 前端-后端联调 | **95%** | ✅ **已修复** 路由→服务→存储全链路打通 |
| API 集成测试 | **100%** | ✅ **新增** 43 个 API 端点测试全部通过 |
| E2E 测试 | **60%** | ⚠️ 测试用例存在,选择器需要与 UI 保持同步 |
### 修复前状态(初始审计)
| 模块 | 完成度 | 状态 |
|------|--------|------|
| 后端路由层 (Routers) | ~~40%~~ | ~~多数路由使用 mock 数据,未接入服务层~~ |
| 前端-后端联调 | ~~30%~~ | ~~后端路由返回 mock前端获取假数据~~ |
---
## 二、核心问题:路由层与服务层脱节
**这是项目最大的系统性问题。** 后端服务层已完整实现并通过测试CLI 也正确接入了服务层。但 HTTP API 路由层(前端调用的入口)多数使用内存变量或硬编码 mock 数据,没有调用已实现的服务。
### 2.1 路由层状态明细
| 路由文件 | 前缀 | 数据源 | 接入服务层? |
|----------|------|--------|-------------|
| `agents.py` | `/api/agents` | 内存 `agents_db` + 硬编码默认 Agent | ❌ 未接入 `AgentRegistry` |
| `locks.py` | `/api/locks` | 内存 `locks_db` + 硬编码默认锁 | ❌ 未接入 `FileLockService` |
| `heartbeats.py` | `/api/heartbeats` | 硬编码 mock 返回值 | ❌ 未接入 `HeartbeatService` |
| `meetings.py` | `/api/meetings` | 内存 `meetings_db` + 硬编码 mock | ❌ 未接入 `MeetingScheduler` / `MeetingRecorder` |
| `resources.py` | `/api` | `/execute` `/parse-task` 为硬编码 mock | ⚠️ 仅 `/status` 接入了服务 |
| `roles.py` | `/api/roles` | 全部硬编码 mock固定返回 developer | ❌ 未接入 `RoleAllocator` |
| `workflows.py` | `/api/workflows` | 已调用 `WorkflowEngine` | ✅ **已正确接入** |
| `humans.py` | `/api/humans` | 已调用 `HumanInputService` | ✅ **已正确接入** |
| `agents_control.py` | `/api/agents/control` | 已调用 `ProcessManager` 等 | ✅ **已正确接入** |
| `websocket.py` | `/ws` | 独立实现 | ✅ 正常 |
**结论**10 个路由模块中,仅 3 个workflows, humans, agents_control正确接入了后端服务6 个使用 mock 数据。
---
## 三、API 端点需求 vs 实现对比
### 3.1 Agent API (`/api/agents`)
| 需求端点 | 方法 | 路由实现 | 接入服务 | 状态 |
|----------|------|----------|----------|------|
| `/api/agents` | GET | ✅ 存在 | ❌ 返回硬编码 | ⚠️ Mock |
| `/api/agents/register` | POST | ✅ 存在 | ❌ 存内存 `agents_db` | ⚠️ Mock |
| `/api/agents/:id` | GET | ✅ 存在 | ❌ 仅查内存 | ⚠️ Mock |
| `/api/agents/:id/state` | GET | ✅ 存在 | ❌ 硬编码状态 | ⚠️ Mock |
| `/api/agents/:id/state` | POST | ✅ 存在 | ❌ 存内存 | ⚠️ Mock |
| `/api/agents/:id` | DELETE | ✅ 存在(额外) | ❌ 仅删内存 | ⚠️ Mock |
### 3.2 文件锁 API (`/api/locks`)
| 需求端点 | 方法 | 路由实现 | 接入服务 | 状态 |
|----------|------|----------|----------|------|
| `/api/locks` | GET | ✅ 存在 | ❌ 硬编码锁数据 | ⚠️ Mock |
| `/api/locks/acquire` | POST | ✅ 存在 | ❌ 存内存 | ⚠️ Mock |
| `/api/locks/release` | POST | ✅ 存在 | ❌ 仅删内存 | ⚠️ Mock |
| `/api/locks/check` | GET | ✅ 存在 | ❌ 查内存 | ⚠️ Mock |
### 3.3 心跳 API (`/api/heartbeats`)
| 需求端点 | 方法 | 路由实现 | 接入服务 | 状态 |
|----------|------|----------|----------|------|
| `/api/heartbeats` | GET | ✅ 存在 | ❌ 硬编码 | ⚠️ Mock |
| `/api/heartbeats/:id` | POST | ✅ 存在 | ❌ 存内存 | ⚠️ Mock |
| `/api/heartbeats/timeouts` | GET | ❌ **缺失** | - | ❌ 未实现 |
### 3.4 会议 API (`/api/meetings`)
| 需求端点 | 方法 | 路由实现 | 接入服务 | 状态 |
|----------|------|----------|----------|------|
| `/api/meetings/create` | POST | ✅ 存在 | ❌ 存内存 | ⚠️ Mock |
| `/api/meetings/:id/queue` | GET | ❌ **缺失** | - | ❌ 未实现 |
| `/api/meetings/:id/wait` | POST | ❌ **缺失** | - | ❌ 未实现 |
| `/api/meetings/:id/end` | POST | ❌ **缺失** | - | ❌ 未实现 |
| `/api/meetings/record/create` | POST | ✅ 存在 | ❌ 存内存 | ⚠️ Mock |
| `/api/meetings/:id/discuss` | POST | ✅ 存在 | ❌ 空返回 | ⚠️ Mock |
| `/api/meetings/:id/progress` | POST | ✅ 存在 | ❌ 空返回 | ⚠️ Mock |
| `/api/meetings/:id` | GET | ✅ 存在 | ❌ 返回 mock | ⚠️ Mock |
| `/api/meetings/:id/finish` | POST | ✅ 存在 | ❌ 空返回 | ⚠️ Mock |
| `/api/meetings` (列表) | GET | ✅ 存在 | ❌ 硬编码 | ⚠️ Mock |
| `/api/meetings/today` | GET | ✅ 存在 | ❌ 硬编码 | ⚠️ Mock |
### 3.5 资源 API (`/api`)
| 需求端点 | 方法 | 路由实现 | 接入服务 | 状态 |
|----------|------|----------|----------|------|
| `/api/execute` | POST | ✅ 存在 | ❌ 硬编码返回 | ⚠️ Mock |
| `/api/status` | GET | ✅ 存在 | ✅ 接入 Registry + Heartbeat | ✅ 正常 |
| `/api/parse-task` | POST | ✅ 存在 | ❌ 硬编码返回 | ⚠️ Mock |
### 3.6 角色 API (`/api/roles`)
| 需求端点 | 方法 | 路由实现 | 接入服务 | 状态 |
|----------|------|----------|----------|------|
| `/api/roles/primary` | POST | ✅ 存在 | ❌ 固定返回 developer | ⚠️ Mock |
| `/api/roles/allocate` | POST | ✅ 存在 | ❌ 轮询分配硬编码 | ⚠️ Mock |
| `/api/roles/explain` | POST | ✅ 存在 | ❌ 固定文案 | ⚠️ Mock |
### 3.7 已正确实现的 API
| 路由模块 | 端点数 | 状态 |
|----------|--------|------|
| `workflows.py` | 11 个端点 | ✅ 全部接入 `WorkflowEngine` |
| `humans.py` | 12 个端点 | ✅ 全部接入 `HumanInputService` |
| `agents_control.py` | 12 个端点 | ✅ 全部接入 `ProcessManager` 等 |
| `websocket.py` | 6 个端点 | ✅ 独立实现完整 |
---
## 四、后端代码问题
### 4.1 Bug
| 文件 | 问题 | 严重度 |
|------|------|--------|
| `agent_executor.py` | `json.dumps` 调用在函数内部局部 importL442虽不会 NameError 但不规范 | 低 |
| `llm_service.py` | 使用 `aiohttp`L439, L474`requirements.txt` 中未声明 | 中 |
| `native_llm_agent.py:278` | `# TODO: 实现投票机制` 未完成 | 低 |
### 4.2 缺失的 API 端点(需求文档要求但路由未实现)
| 端点 | 说明 |
|------|------|
| `GET /api/heartbeats/timeouts` | 检查超时 Agent |
| `GET /api/meetings/:id/queue` | 获取会议等待队列 |
| `POST /api/meetings/:id/wait` | 栅栏同步等待 |
| `POST /api/meetings/:id/end` | 结束会议 |
---
## 五、前端问题
### 5.1 功能缺失
| 问题 | 位置 | 说明 |
|------|------|------|
| 工作流 YAML 上传 | `WorkflowPage.tsx:480` | 注释 "这里应该调用后端 API 上传文件",为占位逻辑 |
| API 地址不可配置 | `api.ts:15` | `API_BASE` 硬编码 `localhost:8000`Settings 页面的 API 地址配置不生效 |
| Agent 控制 API 未封装 | `AgentsPage.tsx` | 直接 `fetch('/agents/control/*')`,未使用 `api.ts` 封装 |
### 5.2 UI 与数据问题
| 问题 | 位置 | 说明 |
|------|------|------|
| 进度条宽度 | `MeetingsPage.tsx` | `width: meeting.progress_summary` 为字符串 "50%",应为数值 |
| 遗留组件未使用 | `components/` 根级 | `AgentStatusCard``ResourceMonitorCard``RecentMeetingsCard``ConsensusCard` 含 mock 数据,未被任何页面引用 |
### 5.3 E2E 测试与 UI 不一致
| 测试期望 | 实际 UI | 文件 |
|----------|---------|------|
| `input[placeholder="搜索 Agent..."]` | AgentsPage 无搜索框 | `e2e-workflow.spec.ts` |
| `input[name="name"]`, `select[name="role"]` | 表单无 name 属性 | `e2e-workflow.spec.ts` |
| `text=创建新会议` | 实际文案 "创建会议" | `e2e-workflow.spec.ts` |
| `button:has-text("新建工作流")` | 无此按钮 | `e2e-workflow.spec.ts` |
| `input[name="apiBaseUrl"]` | 配置表单无 name | `e2e-workflow.spec.ts` |
| `text=配置已保存` | 实际文案 "已保存" | `e2e-workflow.spec.ts` |
| `[data-testid="agent-list"]` | 未使用 data-testid | `e2e-workflow.spec.ts` |
---
## 六、设计文档与实现的不一致
| 设计文档要求 | 实际实现 | 差异说明 |
|-------------|----------|----------|
| API 层使用 Express/Fastify (Node.js) | 使用 Python FastAPI | CLAUDE.md 中已更正design-spec 未同步 |
| 前端使用 shadcn/ui | 纯 Tailwind CSS + 自定义样式 | 未使用 shadcn/ui 组件库 |
| 前端使用 Zustand 状态管理 | 使用 React useState + useEffect | 无全局状态管理 |
| 前端使用 WebSocket 实时更新 | 使用轮询5-10 秒) | WebSocket 后端已实现但前端未接入 |
| Consensus Engine共识引擎 | 未作为独立服务实现 | 共识逻辑在 MeetingRecorder 中 |
| Model Router模型路由 | 在 LLMService 中实现 | 位置不同但功能存在 |
| `.doc/dialogues/` 目录 | 不存在 | 对话存储未实现 |
| `.doc/progress/` 目录 | 不存在 | 进度存储在 Agent state 中 |
| `.doc/shared/` 目录 | 不存在 | 共享知识库未实现 |
---
## 七、后端测试结果
```
StorageService [PASS] ✅
FileLockService [PASS] ✅
HeartbeatService [PASS] ✅
AgentRegistry [PASS] ✅
MeetingScheduler [PASS] ✅
MeetingRecorder [PASS] ✅
ResourceManager [PASS] ✅
WorkflowEngine [PASS] ✅
RoleAllocator [PASS] ✅
总计: 9/9 通过
```
### 未覆盖的服务测试
| 服务 | 说明 |
|------|------|
| HumanInputService | 路由已接入,但缺少单独测试 |
| LLMService | 需要 API Key难以自动化 |
| AgentExecutor | 依赖 LLM需 mock 测试 |
| ProcessManager | 需要实际进程管理环境 |
---
## 八、后续修改步骤(按优先级排序)
### 阶段 1路由层接入服务层P0 - 最高优先级)
这是整个项目的核心瓶颈,完成后前后端即可真正联通。
#### 步骤 1.1:改造 `agents.py` 路由
```
目标:用 AgentRegistry 服务替换内存 agents_db
涉及backend/app/routers/agents.py
方法:
1. 导入 get_agent_registry
2. list_agents → registry.list_agents()
3. register_agent → registry.register_agent()
4. get_agent → registry.get_agent()
5. get/update_agent_state → registry.get_state() / update_state()
6. 删除 agents_db、agent_states_db 内存变量
验证curl /api/agents 返回真实数据(或空列表)
```
#### 步骤 1.2:改造 `locks.py` 路由
```
目标:用 FileLockService 替换内存 locks_db
涉及backend/app/routers/locks.py
方法:
1. 导入 get_file_lock_service
2. list_locks → service.get_locks()
3. acquire_lock → service.acquire_lock()
4. release_lock → service.release_lock()
5. check_lock → service.check_locked()
6. 删除 locks_db 硬编码数据
验证curl /api/locks 返回空列表或真实锁状态
```
#### 步骤 1.3:改造 `heartbeats.py` 路由
```
目标:用 HeartbeatService 替换硬编码返回
涉及backend/app/routers/heartbeats.py
方法:
1. 导入 get_heartbeat_service
2. list_heartbeats → service.get_all_heartbeats()
3. update_heartbeat → service.update_heartbeat()
4. 新增 GET /timeouts?timeout_seconds=60 端点
验证curl /api/heartbeats 返回真实数据
```
#### 步骤 1.4:改造 `meetings.py` 路由
```
目标:用 MeetingScheduler + MeetingRecorder 替换 mock
涉及backend/app/routers/meetings.py
方法:
1. 导入 get_meeting_scheduler, get_meeting_recorder
2. 列表/详情 → recorder.list_meetings() / recorder.get_meeting()
3. 创建 → recorder.create_meeting() + scheduler.create_meeting()
4. 讨论/进度/完成 → recorder.add_discussion() / update_progress() / end_meeting()
5. 新增 GET /:id/queue → scheduler.get_queue()
6. 新增 POST /:id/wait → scheduler.wait_for_meeting()
7. 新增 POST /:id/end → scheduler.end_meeting()
验证:创建会议 → 查看列表 → 添加讨论 → 完成会议 全流程
```
#### 步骤 1.5:改造 `roles.py` 路由
```
目标:用 RoleAllocator 替换硬编码
涉及backend/app/routers/roles.py
方法:
1. 导入 get_role_allocator
2. get_primary_role → allocator.get_primary_role()
3. allocate_roles → allocator.allocate_roles()
4. explain_roles → allocator.explain_allocation()
验证curl /api/roles/primary 返回基于任务分析的角色
```
#### 步骤 1.6:改造 `resources.py` 路由
```
目标:用 ResourceManager 替换 mock
涉及backend/app/routers/resources.py
方法:
1. 导入 get_resource_manager
2. execute_task → manager.execute_task()
3. parse_task → manager.parse_task_files()
验证:/api/execute 真正执行任务(加锁→执行→释放锁)
```
### 阶段 2修复代码问题P1
#### 步骤 2.1:修复依赖
```
文件backend/requirements.txt
操作:添加 aiohttp 依赖
```
#### 步骤 2.2:前端 API 地址可配置
```
文件frontend/src/lib/api.ts
操作:
1. API_BASE 从 localStorage 读取Settings 页面保存的值)
2. 提供 fallback 默认值 http://localhost:8000/api
```
#### 步骤 2.3:封装 Agent 控制 API
```
文件frontend/src/lib/api.ts + frontend/src/pages/AgentsPage.tsx
操作:
1. 在 api.ts 中添加 agentControlApi 模块
2. AgentsPage 改用封装的 API 调用
```
#### 步骤 2.4:修复进度条宽度问题
```
文件frontend/src/pages/MeetingsPage.tsx
操作progress_summary 为 "50%" 字符串,作为 CSS width 值可以工作,
但建议改为数值计算更健壮
```
### 阶段 3补全缺失功能P2
#### 步骤 3.1:实现工作流 YAML 上传
```
后端:新增 POST /api/workflows/upload 端点
前端WorkflowPage.tsx handleFileUpload 对接真实 API
```
#### 步骤 3.2:前端接入 WebSocket
```
目标:替代轮询,使用 WebSocket 实时更新
文件:新增 frontend/src/lib/websocket.ts
操作:
1. 连接 ws://localhost:8000/ws/client/{clientId}
2. Dashboard、Resources 页面订阅实时事件
3. 保留轮询作为降级方案
```
#### 步骤 3.3:清理遗留组件
```
组件AgentStatusCard, ResourceMonitorCard, RecentMeetingsCard, ConsensusCard
操作:评估是否仍需要,不需要则删除,需要则替换 mock 数据为 API 调用
```
### 阶段 4测试完善P2
#### 步骤 4.1:更新 E2E 测试选择器
```
文件frontend/tests/e2e-workflow.spec.ts
操作:将测试选择器更新为与当前 UI 一致
- 搜索框选择器
- 表单 name 属性
- 按钮文案
- data-testid 属性
```
#### 步骤 4.2:补充后端路由集成测试
```
位置backend/
操作:
1. 新增 test_api_integration.py
2. 使用 TestClient 测试所有 API 端点
3. 验证路由→服务→存储完整链路
```
#### 步骤 4.3:补充服务测试
```
新增测试:
- HumanInputService 单元测试
- ProcessManager 单元测试
- AgentExecutor mock 测试mock LLM 调用)
```
### 阶段 5同步文档P3
#### 步骤 5.1:更新设计文档
```
文件docs/design-spec.md
操作:
1. API 层技术栈改为 Python FastAPI非 Express/Fastify
2. 前端技术栈更新(无 shadcn/ui无 Zustand
3. 存储目录结构与实际一致
```
---
## 九、推荐执行顺序
```
Week 1: 阶段 1路由层改造
Day 1: agents.py + locks.py
Day 2: heartbeats.py + meetings.py
Day 3: roles.py + resources.py
Day 4: 联调验证,修复接口对接问题
Week 2: 阶段 2 + 3代码修复 + 缺失功能)
Day 1: 依赖修复 + API 地址可配置
Day 2: Agent 控制 API 封装 + 进度条修复
Day 3: 工作流上传实现
Day 4: WebSocket 接入(可选)
Week 3: 阶段 4 + 5测试 + 文档)
Day 1-2: E2E 测试更新
Day 3: 后端集成测试
Day 4: 文档同步
```
---
## 十、风险提示
1. **路由改造可能引发前端数据格式变化**:当前前端适配的是 mock 数据的格式,改为真实服务后,返回值字段名/结构可能不同,需要同步调整前端代码。
2. **会议的栅栏同步是阻塞调用**`wait_for_meeting` 会阻塞请求直到所有参会者到齐,在 HTTP API 中需要设置合适的超时时间,或改为异步轮询机制。
3. **RoleAllocator 依赖 LLM API**:如果没有配置 API Key角色分配会使用 fallback 逻辑,需要确认 fallback 行为是否满足需求。
4. **数据持久化**:服务层使用 `.doc/` 目录文件存储,路由改造后原来内存中的临时数据会丢失,需要确保前端能正确处理空数据状态。
---
## 附录修复记录2026-03-10
### 已完成的修改
| 序号 | 修改项 | 文件 | 说明 |
|------|--------|------|------|
| 1 | agents.py 路由改造 | `backend/app/routers/agents.py` | 移除 `agents_db` 内存变量,接入 `AgentRegistry` 服务 |
| 2 | locks.py 路由改造 | `backend/app/routers/locks.py` | 移除 `locks_db` 硬编码数据,接入 `FileLockService` 服务 |
| 3 | heartbeats.py 路由改造 | `backend/app/routers/heartbeats.py` | 移除 mock 返回,接入 `HeartbeatService`,新增 `/timeouts` 端点 |
| 4 | meetings.py 路由改造 | `backend/app/routers/meetings.py` | 移除 mock接入 `MeetingScheduler` + `MeetingRecorder`,新增 `/queue` `/wait` `/end` 端点 |
| 5 | roles.py 路由改造 | `backend/app/routers/roles.py` | 移除硬编码角色分配,接入 `RoleAllocator` 服务 |
| 6 | resources.py 路由改造 | `backend/app/routers/resources.py` | 移除 mock`/execute` `/parse-task` 接入 `ResourceManager` |
| 7 | 依赖修复 | `backend/requirements.txt` | 添加 `aiohttp>=3.9.0` |
| 8 | API 地址可配置 | `frontend/src/lib/api.ts` | `API_BASE` 从 localStorage 读取Settings 页面配置生效 |
| 9 | Agent 控制 API 封装 | `frontend/src/lib/api.ts` | 新增 `agentControlApi` 模块,统一封装 |
| 10 | AgentsPage 去硬编码 | `frontend/src/pages/AgentsPage.tsx` | 移除 `API_BASE` 硬编码,使用 `agentControlApi` |
| 11 | 工作流上传功能 | `backend/app/routers/workflows.py` + `frontend/src/pages/WorkflowPage.tsx` | 新增 `POST /upload` 端点,前端实现真实上传 |
| 12 | API 集成测试 | `backend/test_api_integration.py` | 新增 43 项 API 端点集成测试 |
### 测试结果
```
服务层测试: 9/9 通过
API 集成测试: 43/43 通过
```
### 剩余待办
| 优先级 | 项目 | 说明 |
|--------|------|------|
| P2 | WebSocket 实时更新 | 前端仍用轮询,后端 WebSocket 已实现但前端未接入 |
| P2 | 清理遗留组件 | `AgentStatusCard` 等 4 个含 mock 数据的旧组件未被引用 |
| P3 | E2E 测试选择器同步 | 约 7 处选择器/文案与当前 UI 不一致 |
| P3 | 设计文档同步 | `design-spec.md` 中技术栈描述需更新 |
| P3 | 补充服务测试 | HumanInputService、ProcessManager、AgentExecutor 缺少单独测试 |