Files
multiAgentTry/docs/project-audit-report.md

474 lines
19 KiB
Markdown
Raw Normal View History

# 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 缺少单独测试 |