# 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` 调用在函数内部局部 import(L442),虽不会 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 缺少单独测试 |