--- title: "feat: @team 流水线模式集成与基线修复" type: feat status: completed created: 2026-06-17 completed: 2026-06-18 origin: docs/brainstorms/2026-06-17-expert-team-evolution-roadmap-requirements.md requirements: [R0, R1] --- # feat: @team 流水线模式集成与基线修复 ## Summary 将 `@team` 任务分解模式从死代码状态集成到 WebSocket 流程,并修复基线问题。工作分两个阶段:**R0 基线修复**(修复 ExpertTeamRouter 模板引用 bug、损坏的集成测试、过时的 AGENTS.md 文档),**R1 流水线集成**(重写 TeamPlan 支持阶段依赖图、重写 TeamOrchestrator 为流水线模式、新增 `_execute_team_collab` 到 chat.py、新增 5 个编程专家模板、适配前端)。 完成后用户可通过 `@team 开发用户登录功能` 触发流水线执行(规划 → 前端 → 后端 → QA → 评审),与 `@board` 群聊讨论模式形成"决策→执行"互补闭环。 --- ## Problem Frame ### 当前状态 `@team` 路由的 `ExpertTeamRouter`、`TeamOrchestrator`、`ExpertTeam` 代码完整但**从未被调用**(死代码)。`chat.py` 中 `TEAM_COLLAB` 执行模式仅记录 warning 并回退到 REACT。此外存在多个基线问题: 1. **ExpertTeamRouter 模板引用 bug** — `resolve_expert_configs` 中 `template.config` 是引用(非 deepcopy),`is_lead` 赋值会污染共享模板(与 BoardRouter 修复前的 P1 bug 相同) 2. **集成测试损坏** — `tests/integration/test_expert_team.py` 导入 6 个已移除的类(`CollaborationPlan, MergeStrategy, ParallelType, PhaseStatus, PlanPhase`),会 ImportError 3. **前后端数据模型不一致** — 后端 `TeamPlan.subtasks`(扁平)vs 前端 `team.ts` 的 `plan_phases`(阶段概念) 4. **AGENTS.md 文档过时** — 描述的"CostAwareRouter 三层路由"、"serial/parallel/competitive + merge"已与代码不符 5. **TeamOrchestrator 仅 hub-and-spoke** — 并行子任务无依赖,不支持流水线串行阶段 6. **硬编码 model="default"** — 两处 LLM 调用不读取 `ExpertConfig.llm` ### 核心问题 `@team` 代码完整但不可用,且现有 hub-and-spoke 编排不支持用户选择的流水线模式(对标 Qoder 的 Team Lead + 阶段依赖)。需要重写编排引擎和计划模型,然后集成到 WebSocket。 --- ## Requirements Traceability | 需求 ID | 描述 | 实现单元 | |---------|------|---------| | R0 | 修复死代码与前后端不一致 | U1, U2, U3 | | R1.1 | 流水线编排引擎(阶段依赖图) | U4, U5 | | R1.2 | 上下文隔离 | U5(内嵌) | | R1.3 | WebSocket 集成 | U6 | | R1.4 | 路由支持(@team / @team:experts / @team:dev_team) | U6, U7 | | R2(部分) | 5 个核心编程专家模板 | U7 | **Origin 文档**:`docs/brainstorms/2026-06-17-expert-team-evolution-roadmap-requirements.md`(R0 和 R1 章节) --- ## Key Technical Decisions ### KTD1: 恢复阶段依赖图(PlanPhase),与前端 plan_phases 对齐 **决策**:后端恢复 `PlanPhase` 和 `PhaseStatus` 类,支持阶段依赖图(`depends_on`),与前端 `team.ts` 的 `plan_phases` 概念自然对齐。 **理由**: - 前端已有 `plan_phases` 和 `ITeamPlanPhase` 类型,恢复后端阶段概念可避免前端大改 - 流水线模式天然需要"阶段"概念(规划→前端→后端→QA→评审) - 恢复 `PlanPhase` 比扩展现有 `SubTask` 语义更清晰 **约束**: - 不恢复 VOTE/FUSION 合并策略(仅保留 BEST) - 不恢复 `ParallelType` 枚举(阶段内并行通过 `asyncio.gather` 隐式实现) - `PlanPhase` 包含:`id`, `name`, `assigned_expert`, `task_description`, `depends_on: list[str]`, `status`, `result` ### KTD2: 流水线编排逻辑 — Lead 分解为阶段而非子任务 **决策**:`TeamOrchestrator._decompose_task` 改为让 Lead Expert 分解任务为**阶段**(phases),每个阶段有 `assigned_expert` 和 `depends_on`。执行时按依赖拓扑排序,无依赖的阶段并行,有依赖的串行。 **理由**: - 对标 Qoder 的 Team Lead + 流水线协作 - Lead Expert 用 LLM 生成阶段 JSON(包含 `name`, `assigned_expert`, `task_description`, `depends_on`) - 阶段间数据通过 `SharedWorkspace` 传递(`{task_id}/phase/{phase_id}/output`) **流程**: 1. Lead 分解任务为阶段(LLM 生成 JSON) 2. 拓扑排序阶段(按 `depends_on`) 3. 按拓扑序执行:同层无依赖阶段并行(`asyncio.gather`),层间串行 4. 每个阶段完成后,输出写入 `SharedWorkspace` 5. Lead 汇总所有阶段结果(BEST 策略) ### KTD3: 上下文隔离 — 独立 ConfigDrivenAgent 实例 **决策**:每个阶段执行时创建独立的 `ConfigDrivenAgent` 实例(通过 `AgentPool.create_agent`),不共享对话历史。阶段间通过 `SharedWorkspace` 传递中间产物。 **理由**: - 对标 Trae Solo 的独立上下文环境和 Claude Code Subagent 的上下文隔离 - `ExpertTeam` 中每个 `Expert` 包装一个 `ConfigDrivenAgent`,但多个阶段可能分配给同一专家类型 - 为每个阶段创建新实例确保上下文完全隔离 - 阶段输出通过 `SharedWorkspace` 约定 key 传递:`{task_id}/phase/{phase_id}/output` ### KTD4: WebSocket 事件流扩展 **决策**:在现有 6 个 team 事件基础上新增 3 个阶段事件。 **事件流**: ``` team_formed → plan_update(阶段计划) → phase_started → expert_step → expert_result → phase_completed → phase_started → expert_step → expert_result → phase_completed → ...(按拓扑序) → team_synthesis → team_dissolved ``` **新增事件**: - `phase_started`:`{phase_id, phase_name, assigned_expert, depends_on}` - `phase_completed`:`{phase_id, phase_name, result_summary}` - `phase_failed`:`{phase_id, phase_name, error}` ### KTD5: ExpertTeamRouter 模板引用修复 — deepcopy **决策**:`resolve_expert_configs` 中使用 `copy.deepcopy(template.config)` 替代 `template.config`,与 BoardRouter 的 P1 修复保持一致。 **理由**:`ExpertConfig` 是普通 Python 类(非 Pydantic),`model_copy()` 不可用,使用 `copy.deepcopy()`。 ### KTD6: TeamStatus 新增 PLANNING 状态(深化审查发现) **决策**:后端 `TeamStatus` 枚举新增 `PLANNING = "planning"`,在 Lead Expert 分解任务阶段设置。 **理由**: - 前端 `IExpertTeamState.status` 已包含 `'planning'`(`types.ts:141`),但后端 `TeamStatus`(`team.py:31-38`)缺少此状态 - 流水线模式下,Lead 分解任务为阶段是一个明确的生命周期阶段(FORMING → PLANNING → EXECUTING → SYNTHESIZING → COMPLETED) - 现有 hub-and-spoke 模式直接从 FORMING 跳到 EXECUTING,流水线模式需要 PLANNING 中间态 **约束**: - `ExpertTeam.create_team()` 后设置 `PLANNING` - `TeamOrchestrator._decompose_task` 完成后、开始执行阶段前设置 `EXECUTING` --- ## Deepening Review Findings(深化审查发现) ### 已确认的差距(需更新实现单元) | # | 发现 | 位置 | 影响单元 | 处理方式 | |---|------|------|---------|---------| | F1 | `ITeamPlanPhase` 缺少 `depends_on`、`task_description`、`result` 字段;`parallel_type` 和 `milestone` 应改为可选 | `types.ts:129-136` | U8 | 显式更新前端类型定义 | | F2 | `WsServerMessage` 联合类型缺少 `phase_started`/`phase_completed`/`phase_failed` 事件 | `types.ts:103-108` | U8 | 新增 3 个事件类型到联合类型 | | F3 | 前端 `chat.ts` 的 WebSocket 事件 handler 缺少 phase 事件处理(`case 'phase_started'` 等) | `chat.ts:570-665` | U8 | 新增 3 个 case 分支,更新 `teamStore` 中对应 phase 的 status | | F4 | 后端 `TeamStatus` 枚举缺少 `PLANNING` 状态,与前端 `IExpertTeamState.status` 不一致 | `team.py:31-38` vs `types.ts:141` | U5 | 新增 `PLANNING` 枚举值(KTD6) | ### 已确认无需修改(验证通过) | # | 验证项 | 位置 | 结论 | |---|--------|------|------| | V1 | `_VALID_TEAM_EVENT_TYPES` 是否包含 phase 事件 | `chat.py:100-120` | ✅ 已包含 `phase_started`/`phase_completed`/`phase_failed`(line 109-111),U6 只需调用 `emit_team_event` 使用它们 | | V2 | `ExpertTeam.create_team()` 签名 | `team.py:119-123` | ✅ 确认为 `create_team(lead_config, member_configs)`,U6 需拆分 configs:首个为 lead,其余为 members | | V3 | `ExpertTeam.workspace` 和 `handoff_transport` 可见性 | `team.py:88-109` | ✅ 均为 public property,U5 可直接使用 `team.workspace` 和 `team.handoff_transport` | | V4 | `ExpertConfig.llm` 字段结构 | `config.py` | ✅ 为 `dict[str, Any] | None`,U5 的 `_get_model` 应读 `expert.config.llm.get("model", "default")` if `llm` else `"default"` | ### 新增测试场景(补充到 U5、U9) - **LLM 分解失败容错**:LLM 返回无效 JSON → fallback 到单阶段(`[PlanPhase(task=原任务, assigned_expert=lead)]`) - **循环依赖检测**:A→B→A 的循环依赖 → `topological_sort()` 抛出 `ValueError` - **无效专家引用**:阶段 `assigned_expert` 引用不存在的专家 → fallback 到 lead 专家 - **`TeamStatus.PLANNING` 状态流转**:`create_team` 后为 `PLANNING`,分解完成后为 `EXECUTING` --- ## High-Level Technical Design ### 流水线编排架构 ``` 用户输入: @team 开发用户登录功能 │ ▼ ExpertTeamRouter.resolve() → 解析专家列表 + 任务 │ ▼ ExpertTeam 创建 → 注册 handoff handler │ ▼ TeamOrchestrator.execute(task) │ ├─ 1. 广播 team_formed │ ├─ 2. Lead Expert 分解任务为阶段(LLM) │ 输出: [ │ {name: "规划", assigned_expert: "tech_lead", depends_on: []}, │ {name: "前端", assigned_expert: "frontend_engineer", depends_on: ["规划"]}, │ {name: "后端", assigned_expert: "backend_engineer", depends_on: ["规划"]}, │ {name: "QA", assigned_expert: "qa_engineer", depends_on: ["前端", "后端"]}, │ {name: "评审", assigned_expert: "code_reviewer", depends_on: ["QA"]}, │ ] │ ├─ 3. 广播 plan_update(阶段计划) │ ├─ 4. 拓扑排序执行: │ Layer 0: [规划] (并行) │ Layer 1: [前端, 后端] (并行) │ Layer 2: [QA] │ Layer 3: [评审] │ │ 每个阶段: │ → phase_started 事件 │ → 创建独立 ConfigDrivenAgent 实例(上下文隔离) │ → 读取前置阶段输出 from SharedWorkspace │ → expert_step 事件 │ → 执行阶段任务 │ → 写入阶段输出 to SharedWorkspace │ → expert_result 事件 │ → phase_completed 事件 │ ├─ 5. Lead Expert 汇总(BEST 策略) │ ├─ 6. 广播 team_synthesis │ └─ 7. 广播 team_dissolved ``` ### 阶段依赖图数据模型 ``` TeamPlan ├── id: str ├── task: str ├── lead_expert: str ├── status: PlanStatus └── phases: list[PlanPhase] ├── id: str ├── name: str ├── assigned_expert: str ├── task_description: str ├── depends_on: list[str] # 前置阶段 ID ├── status: PhaseStatus └── result: dict | None ``` --- ## Implementation Units ### U1. 修复 ExpertTeamRouter 模板引用 bug **Goal**: 修复 `resolve_expert_configs` 中 `template.config` 引用导致的模板污染问题,与 BoardRouter 的 P1 修复保持一致。 **Requirements**: R0 **Dependencies**: 无 **Files**: - `src/agentkit/experts/router.py` — 修改 `resolve_expert_configs` 方法 **Approach**: - 在 `router.py` 顶部新增 `import copy` - `resolve_expert_configs` 中将 `configs.append(template.config)` 改为 `config = copy.deepcopy(template.config)` 然后 `configs.append(config)` - 确保 `is_lead` 赋值不会污染共享模板 **Patterns to follow**: `src/agentkit/experts/board_router.py` 的 `resolve_expert_configs`(已修复相同 bug) **Test scenarios**: - **模板不污染**: 连续两次调用 `resolve_expert_configs(["a", "b"])` 和 `resolve_expert_configs(["b", "a"])`,第一次的 `is_lead` 不被第二次修改 - **动态生成不受影响**: 不存在的专家名仍创建动态 `ExpertConfig` - **Lead 正确设置**: 首个专家 `is_lead=True`,其余 `False` **Verification**: `pytest tests/unit/experts/ -k "router"` 通过,无模板污染 --- ### U2. 临时修复集成测试导入 **Goal**: 修复 `tests/integration/test_expert_team.py` 的 ImportError,使其能导入并运行(测试内容会在 U9 重写为流水线模式)。 **Requirements**: R0 **Dependencies**: U1 **Files**: - `tests/integration/test_expert_team.py` — 修复导入和引用已移除类的测试 **Approach**: - 移除对 `CollaborationPlan, MergeStrategy, ParallelType, PhaseStatus, PlanPhase` 的导入 - 改为导入 `TeamPlan, SubTask, SubTaskStatus, PlanStatus` - 将使用 `CollaborationPlan` 的测试(`test_manual_team_subtask_parallel`, `test_auto_team_competitive_parallel`, `test_plan_modification_by_user`, `test_vote_strategy_with_tie_break`, `test_fusion_strategy`, `test_plan_failure_triggers_retry`, `test_fallback_after_retry_failure`)改为使用 `TeamPlan` 或标记为 `pytest.mark.skip`(U9 会重写) - 保留不依赖已移除类的测试(`TestManualTeamFormation.test_manual_team_with_templates`, `TestDecentralizedCollaboration`, `TestUserIntervention.test_user_intervention_broadcast`, `TestTeamDissolution`, `TestDynamicExpertManagement`) **Test scenarios**: - **导入成功**: `from agentkit.experts.plan import TeamPlan, SubTask, SubTaskStatus, PlanStatus` 不报错 - **保留测试通过**: 不依赖已移除类的测试仍通过 - **跳过测试标记**: 依赖已移除类的测试标记为 `skip` 并注明"U9 将重写为流水线模式" **Verification**: `pytest tests/integration/test_expert_team.py` 不再 ImportError,保留测试通过 --- ### U3. 更新 AGENTS.md 文档 **Goal**: 更新 AGENTS.md 中与代码不符的描述,确保文档与实际状态一致。 **Requirements**: R0 **Dependencies**: 无 **Files**: - `AGENTS.md` — 更新过时描述 **Approach**: - "CostAwareRouter 三层路由" → "RequestPreprocessor(@skill 前缀 + 正则快路径 + REACT)" - "serial/parallel/competitive + merge" → "hub-and-spoke(即将升级为流水线模式)" - "CollaborationPlan: phases with dependencies, parallel types, merge strategies" → "TeamPlan: phases with dependencies(R1 恢复)" - "TEAM_COLLAB" 状态更新为"R1 集成后可用" **Test expectation**: none — 文档更新无行为变化 **Verification**: AGENTS.md 中无与代码矛盾的描述 --- ### U4. 重写 plan.py 恢复阶段依赖图 **Goal**: 重写 `plan.py`,恢复 `PlanPhase` 和 `PhaseStatus` 类,支持阶段依赖图(`depends_on`),与前端 `plan_phases` 概念对齐。 **Requirements**: R1.1 **Dependencies**: U2(测试已临时修复) **Files**: - `src/agentkit/experts/plan.py` — 重写 - `tests/unit/experts/test_plan.py` — 新增单元测试 **Approach**: - 保留现有 `MergeStrategy.BEST`、`PlanStatus`、`SubTaskStatus`、`SubTask` - 新增 `PhaseStatus` 枚举:`PENDING`, `RUNNING`, `COMPLETED`, `FAILED` - 新增 `PlanPhase` dataclass: - `id`, `name`, `assigned_expert`, `task_description`, `depends_on: list[str]`, `status`, `result` - `to_dict()` / `from_dict()` 序列化 - 重写 `TeamPlan`: - 新增 `phases: list[PlanPhase]` 字段(保留 `subtasks` 用于向后兼容,但新代码用 `phases`) - 新增 `topological_sort()` 方法:返回按依赖排序的执行层 `list[list[PlanPhase]]` - 新增 `get_ready_phases()` 方法:返回当前可执行的阶段(依赖已完成) - 新增 `update_phase_status()` 方法 - 新增 `completed_phases` / `failed_phases` 属性 **Patterns to follow**: 现有 `SubTask` dataclass 的序列化模式 **Test scenarios**: - **阶段创建**: `PlanPhase(name="前端", assigned_expert="frontend", depends_on=["规划"])` 正确创建 - **拓扑排序**: 3 层依赖(规划→前端+后端→QA)正确排序为 `[[规划], [前端, 后端], [QA]]` - **就绪阶段**: 初始时只有 `规划` 就绪;`规划` 完成后 `前端` 和 `后端` 就绪 - **序列化**: `TeamPlan.to_dict()` / `from_dict()` 往返一致 - **循环依赖检测**: A→B→A 的循环依赖抛出 `ValueError` **Verification**: `pytest tests/unit/experts/test_plan.py` 通过 --- ### U5. 重写 TeamOrchestrator 为流水线模式 **Goal**: 重写 `TeamOrchestrator`,从 hub-and-spoke(并行无依赖)升级为流水线模式(阶段依赖 + 拓扑排序 + 上下文隔离)。 **Requirements**: R1.1, R1.2 **Dependencies**: U4(PlanPhase 已实现) **Files**: - `src/agentkit/experts/team.py` — 新增 `TeamStatus.PLANNING` 枚举值(KTD6, F4) - `src/agentkit/experts/orchestrator.py` — 重写 - `tests/unit/experts/test_orchestrator.py` — 新增单元测试 **Approach**: **`team.py` 修改(KTD6)**: - `TeamStatus` 枚举新增 `PLANNING = "planning"` - `create_team()` 完成后设置 `PLANNING`(而非直接 `EXECUTING`) - 现有 hub-and-spoke 模式不受影响(PLANNING 状态短暂存在) **`_decompose_task` 改为分解阶段**: - Lead Expert 用 LLM 生成阶段 JSON(`name`, `assigned_expert`, `task_description`, `depends_on`) - 解析为 `list[PlanPhase]` - 阶段数上限 `MAX_PHASES = 10` - LLM 失败/返回无效 JSON 时 fallback 到单阶段(`[PlanPhase(task=原任务, assigned_expert=lead)]`) **`execute` 改为流水线驱动**: 1. 广播 `team_formed` 2. 设置 `TeamStatus.PLANNING`,Lead 分解任务为阶段 3. 广播 `plan_update`(含阶段列表) 4. 设置 `TeamStatus.EXECUTING`,拓扑排序,按层执行: - 同层阶段并行(`asyncio.gather`) - 层间串行(等待上一层完成) - 每个阶段:广播 `phase_started` → 创建独立 Agent 实例 → 读取前置输出 → 执行 → 写入输出 → 广播 `expert_step`/`expert_result`/`phase_completed` 5. Lead 汇总(BEST 策略) 6. 广播 `team_synthesis` 和 `team_dissolved` **上下文隔离实现**: - `_execute_phase` 中通过 `AgentPool.create_agent` 创建独立 `ConfigDrivenAgent` - 上下文仅包含:任务描述 + 专家 persona + 前置阶段输出(从 `SharedWorkspace` 读取) - 阶段完成后写入 `SharedWorkspace`:`{task_id}/phase/{phase_id}/output` - 使用 `team.workspace` 和 `team.handoff_transport`(均为 public property,V3 验证通过) **移除硬编码 model="default"**: - `_get_model(expert)` 方法:读取 `expert.config.llm`(V4 验证为 `dict[str, Any] | None`) - 逻辑:`expert.config.llm.get("model", "default") if expert.config.llm else "default"` **新增事件广播**(V1 验证:`_VALID_TEAM_EVENT_TYPES` 已包含这些事件类型,无需修改 chat.py 的 frozenset): - `phase_started`: `{phase_id, phase_name, assigned_expert, depends_on}` - `phase_completed`: `{phase_id, phase_name, result_summary}` - `phase_failed`: `{phase_id, phase_name, error}` **Fallback 保留**: - 所有阶段失败时 fallback 到单 Agent(现有 `_fallback_to_single_agent` 逻辑) **Patterns to follow**: 现有 `TeamOrchestrator._execute_subtask` 的事件广播模式 **Test scenarios**: - **流水线执行**: 3 阶段(A→B→C)按序执行,B 在 A 完成后启动 - **并行阶段**: 2 个无依赖阶段并行执行(`asyncio.gather`) - **上下文隔离**: 阶段 B 的 Agent 实例不包含阶段 A 的对话历史 - **SharedWorkspace 传递**: 阶段 A 的输出写入 workspace,阶段 B 能读取 - **阶段失败**: 阶段 B 失败时,依赖 B 的阶段 C 标记为 `FAILED` - **全失败 fallback**: 所有阶段失败时 fallback 到单 Agent - **事件广播**: `phase_started`/`phase_completed` 事件正确发送 - **模型路由**: `expert.config.llm` 配置的模型被使用(非 `"default"`) - **LLM 分解失败容错**: LLM 返回无效 JSON → fallback 到单阶段(深化审查新增) - **循环依赖检测**: A→B→A 的循环依赖 → `topological_sort()` 抛出 `ValueError`(深化审查新增) - **无效专家引用**: 阶段 `assigned_expert` 引用不存在的专家 → fallback 到 lead 专家(深化审查新增) - **`TeamStatus.PLANNING` 状态流转**: `create_team` 后为 `PLANNING`,分解完成后为 `EXECUTING`(深化审查新增) **Verification**: `pytest tests/unit/experts/test_orchestrator.py` 通过 --- ### U6. 新增 `_execute_team_collab` 到 chat.py **Goal**: 在 `chat.py` 中新增 `_execute_team_collab` 函数,将 `@team` 路由集成到 WebSocket 流程,参照 `_execute_board_meeting` 的集成模式。 **Requirements**: R1.3, R1.4 **Dependencies**: U5(TeamOrchestrator 已重写), U7(编程专家模板已创建) **Files**: - `src/agentkit/server/routes/chat.py` — 新增 `_execute_team_collab` 函数 + 集成到 WebSocket handler - `tests/unit/server/routes/test_chat_team.py` — 新增单元测试 **Approach**: **`_execute_team_collab` 函数**(参照 `_execute_board_meeting` 模式): 1. 从 `app.state` 获取 `ExpertTemplateRegistry` 2. 创建 `ExpertTeamRouter`,调用 `resolve(content)` 3. 若 `not routing_result.matched`:返回 `False`(继续正常管线) 4. 若 `not routing_result.task_content`:发送错误"团队任务需要一个描述" 5. 调用 `resolve_expert_configs` 解析专家配置 6. 若无专家配置:发送错误"无法解析团队成员" 7. 创建 `ExpertTeam`(使用 `app.state.agent_pool`) 8. **拆分专家配置**(V2 验证):首个为 `lead_config`,其余为 `member_configs`,调用 `team.create_team(lead_config=..., member_configs=...)` 9. 注册 handoff handler 中继事件到 WebSocket(`_relay_team_event`)— 使用 `emit_team_event`(V1 验证:`_VALID_TEAM_EVENT_TYPES` 已包含 phase 事件,无需修改 frozenset) 10. 追加用户消息到会话历史 11. 执行 `TeamOrchestrator.execute(task)` 12. 发送 `final_answer` 13. 持久化最终结果到会话历史 14. 清理团队 **WebSocket handler 集成**: - 在 WebSocket message handler 中,`@board` 检查之后、`@skill:` 检查之前,新增 `@team` 检查 - `if await _execute_team_collab(websocket, session_id, content, sm): return` **`TEAM_COLLAB` 执行模式**: - 移除 `chat.py:752-758` 的 fallback 到 REACT 逻辑 - `TEAM_COLLAB` 现在由 `_execute_team_collab` 处理 **Patterns to follow**: `src/agentkit/server/routes/chat.py` 的 `_execute_board_meeting`(line 155-307) **Test scenarios**: - **@team 触发**: `@team 开发登录功能` 调用 `_execute_team_collab`,返回 `True` - **非 @team 输入**: 普通消息不触发,返回 `False` - **无任务描述**: `@team` 无任务内容时发送错误 - **无专家配置**: 所有专家名无效时发送错误 - **事件中继**: `team_formed`/`phase_started`/`expert_step` 等事件正确转发到 WebSocket - **final_answer 发送**: 执行完成后发送 `final_answer` 事件 - **会话持久化**: 用户消息和最终结果持久化到会话历史 - **团队清理**: 执行后 `team.dissolve()` 被调用 - **与 @board 互不干扰**: `@board` 和 `@team` 各自独立路由 **Verification**: `pytest tests/unit/server/routes/test_chat_team.py` 通过;`@team 开发登录功能` 在 WebSocket 中端到端可用 --- ### U7. 新增 5 个核心编程专家模板 **Goal**: 新增 5 个编程领域专家模板 + 1 个 `dev_team.yaml` 组合模板,为 `@team` 流水线提供默认编程团队。 **Requirements**: R1.4, R2(部分) **Dependencies**: 无(可与 U4-U6 并行) **Files**: - `configs/experts/tech_lead.yaml` — 技术负责人 - `configs/experts/frontend_engineer.yaml` — 前端工程师 - `configs/experts/backend_engineer.yaml` — 后端工程师 - `configs/experts/qa_engineer.yaml` — QA 工程师 - `configs/experts/code_reviewer.yaml` — 代码审查员 - `configs/experts/dev_team.yaml` — 默认编程团队组合模板 **Approach**: - 每个专家 YAML 包含:`name`, `persona`, `thinking_style`, `speaking_style`, `bound_skills`, `avatar`, `color` - `tech_lead`: 第一性原理思维,架构决策,任务分解,`is_lead: true` - `frontend_engineer`: 组件化思维,UI/UX 敏感,前端测试 - `backend_engineer`: 系统思维,API 设计,数据库操作 - `qa_engineer`: 边界思维,测试用例设计,缺陷验证 - `code_reviewer`: 批判性思维,代码规范,安全漏洞 - `dev_team.yaml`: 包含 5 个成员列表(`tech_lead, frontend_engineer, backend_engineer, qa_engineer, code_reviewer`) **Patterns to follow**: `configs/experts/elon_musk.yaml` 的字段结构 **Test scenarios**: - **模板加载**: 5 个 YAML 文件能被 `ExpertTemplateRegistry.load_from_directory` 加载 - **专家配置正确**: 每个 `ExpertConfig` 的 `persona`/`thinking_style`/`bound_skills` 非空 - **dev_team 组合**: `dev_team.yaml` 包含 5 个成员名 - **@team:dev_team 路由**: `@team:dev_team 开发功能` 能解析为 5 个专家 **Verification**: `agentkit skill list` 显示新增专家;`@team:dev_team 任务` 能调用默认团队 --- ### U8. 适配前端 ExpertTeamView.vue 和 team.ts **Goal**: 适配前端组件和 store,确保与后端流水线模式的数据模型一致,正确显示阶段计划、当前阶段、专家步骤。 **Requirements**: R1.3 **Dependencies**: U4(PlanPhase 已实现), U6(WebSocket 事件已定义) **Files**: - `src/agentkit/server/frontend/src/api/types.ts` — 更新 `ITeamPlanPhase` 和 `WsServerMessage` 类型(F1, F2) - `src/agentkit/server/frontend/src/stores/chat.ts` — 新增 phase 事件 handler(F3) - `src/agentkit/server/frontend/src/stores/team.ts` — 适配数据模型(新增 phase 状态更新方法) - `src/agentkit/server/frontend/src/components/chat/ExpertTeamView.vue` — 适配阶段展示 **Approach**: **`types.ts` 修改(F1, F2 — 深化审查发现)**: `ITeamPlanPhase` 更新(F1): ```typescript export interface ITeamPlanPhase { id: string name: string assigned_expert: string task_description?: string // 新增 depends_on: string[] // 新增(核心字段,支持流水线依赖图) status: 'pending' | 'in_progress' | 'completed' | 'failed' result?: string // 新增(阶段执行结果摘要) parallel_type?: 'serial' | 'subtask_parallel' | 'competitive_parallel' // 改为可选(KTD1 不恢复 ParallelType 枚举) milestone?: string // 改为可选 } ``` `WsServerMessage` 新增 3 个事件类型(F2): ```typescript | { type: 'phase_started'; data: { phase_id: string; phase_name: string; assigned_expert: string; depends_on: string[] } } | { type: 'phase_completed'; data: { phase_id: string; phase_name: string; result_summary: string } } | { type: 'phase_failed'; data: { phase_id: string; phase_name: string; error: string } } ``` **`chat.ts` 修改(F3 — 深化审查发现)**: 在 `team_dissolved` case 之前(约 line 655),新增 3 个 case 分支: ```typescript case 'phase_started': { const teamStore = _getTeamStore() if (teamStore?.teamState) { teamStore.updatePhaseStatus(payload.phase_id, 'in_progress') } break } case 'phase_completed': { const teamStore = _getTeamStore() if (teamStore?.teamState) { teamStore.updatePhaseStatus(payload.phase_id, 'completed', payload.result_summary) } break } case 'phase_failed': { const teamStore = _getTeamStore() if (teamStore?.teamState) { teamStore.updatePhaseStatus(payload.phase_id, 'failed', payload.error) } break } ``` **`team.ts` 修改**: - 新增 `updatePhaseStatus(phaseId: string, status: ITeamPlanPhase['status'], result?: string)` 方法 - `currentPhase` 和 `completedPhases` 逻辑保持不变(已用 `plan_phases`) - 现有 `updatePhases(phases)` 保持不变(用于 `plan_update` 事件) **`ExpertTeamView.vue` 修改**: - 新增阶段状态展示: - 当前阶段(`status === 'in_progress'`)高亮 - 已完成阶段(`status === 'completed'`)标记 - 失败阶段(`status === 'failed'`)红色标记 - 阶段间依赖关系可视化(简单的箭头或缩进,基于 `depends_on`) - 确认 `plan_update` 事件正确更新 `plan_phases` **Patterns to follow**: `src/agentkit/server/frontend/src/components/chat/BoardStatusView.vue` 的状态展示模式 **Test scenarios**: - **阶段计划展示**: `plan_update` 事件后,前端显示所有阶段 - **当前阶段高亮**: `phase_started` 事件后,对应阶段高亮 - **阶段完成标记**: `phase_completed` 事件后,对应阶段标记为完成 - **阶段失败标记**: `phase_failed` 事件后,对应阶段标记为失败 - **专家步骤展示**: `expert_step`/`expert_result` 事件正确关联到阶段 - **类型检查通过**: `npm run typecheck` 无错误(F1, F2 类型更新后) **Verification**: `npm run typecheck` 通过;前端正确展示流水线阶段 --- ### U9. 重写集成测试覆盖流水线模式 **Goal**: 重写 `tests/integration/test_expert_team.py`,覆盖流水线模式的完整功能,替换 U2 中临时跳过的测试。 **Requirements**: R0, R1 **Dependencies**: U4(PlanPhase), U5(TeamOrchestrator), U6(chat.py 集成), U7(专家模板) **Files**: - `tests/integration/test_expert_team.py` — 重写 **Approach**: - 移除 U2 中的 `pytest.mark.skip` 标记 - 重写测试为流水线模式: - `test_pipeline_execution`: 3 阶段(A→B→C)按序执行 - `test_parallel_phases`: 2 个无依赖阶段并行 - `test_phase_dependency`: 阶段 B 依赖 A,A 失败时 B 标记为 FAILED - `test_shared_workspace_passing`: 阶段 A 输出通过 SharedWorkspace 传递给 B - `test_context_isolation`: 阶段 B 的 Agent 不包含 A 的对话历史 - `test_fallback_on_all_failure`: 所有阶段失败时 fallback 到单 Agent - `test_dev_team_template`: `@team:dev_team 任务` 调用 5 个编程专家 - `test_explicit_experts`: `@team:frontend_engineer,backend_engineer 任务` 调用指定专家 - `test_event_sequence`: 事件顺序正确(team_formed → plan_update → phase_started → ... → team_synthesis → team_dissolved) - `test_llm_decomposition_failure`: LLM 返回无效 JSON → fallback 到单阶段(深化审查新增) - `test_circular_dependency`: A→B→A 循环依赖 → `topological_sort()` 抛出 `ValueError`(深化审查新增) - `test_invalid_expert_reference`: 阶段引用不存在的专家 → fallback 到 lead(深化审查新增) - `test_team_status_planning`: `create_team` 后状态为 `PLANNING`,分解完成后为 `EXECUTING`(深化审查新增) - 保留不依赖已移除类的现有测试 **Test scenarios**: - **流水线端到端**: `@team 开发登录功能` 触发完整流水线 - **阶段依赖**: 依赖阶段在前置完成后才执行 - **并行阶段**: 无依赖阶段并行执行 - **上下文隔离**: 子任务上下文不污染 - **Fallback**: 全失败时降级 - **事件序列**: 事件顺序正确 **Verification**: `pytest tests/integration/test_expert_team.py` 全部通过 --- ### U10. 端到端验证与文档更新 **Goal**: 端到端验证 `@team` 流水线模式可用,更新相关文档。 **Requirements**: R1 **Dependencies**: U1-U9 全部完成 **Files**: - `docs/plans/2026-06-17-003-feat-team-pipeline-integration-plan.md` — 更新 status - `AGENTS.md` — 更新 `@team` 状态为"可用" **Approach**: - 启动 `agentkit gui --port 8002` - WebSocket 连接,发送 `@team 开发用户登录功能` - 验证:`team_formed` → `plan_update` → `phase_started`/`phase_completed` 序列 → `team_synthesis` → `team_dissolved` - 验证:`@board` 仍正常工作 - 验证:`@team:dev_team 任务` 调用默认团队 - 验证:`@team:frontend_engineer,backend_engineer 任务` 调用指定专家 - 运行 `ruff check src/ && ruff format src/` - 运行 `pytest -m "not integration"` 确保单元测试通过 - 运行 `pytest tests/integration/test_expert_team.py` 确保集成测试通过 - 运行 `npm run typecheck` 确保前端类型正确 **Test expectation**: none — 验证单元 **Verification**: `@team` 端到端可用;`@board` 不受影响;所有测试通过;ruff 清洁 --- ## Scope Boundaries ### 本次范围内 - R0: 修复 ExpertTeamRouter 模板引用 bug、集成测试导入、AGENTS.md 文档 - R1: 重写 TeamPlan/TeamOrchestrator 为流水线模式、WebSocket 集成、5 个编程专家模板、前端适配 - 上下文隔离(独立 ConfigDrivenAgent 实例 + SharedWorkspace 传递) ### 延后到后续工作 - **R2 完整版**: 额外 3 个可选专家(devops, security, database) - **R3 完整版**: 上下文隔离的配置化(`agentkit.yaml` 中 `isolation: context|none`) - **R4**: 多模型智能路由(消费 `ExpertConfig.llm`)— 本次仅移除硬编码,完整路由逻辑延后 - **R5**: 仓库级代码理解 - **R6**: VS Code 扩展 - **git worktree 隔离**: v2 路线图已决定延后 - **VOTE/FUSION 合并策略**: 不恢复,仅保留 BEST ### 不在产品身份内 - 纯代码补全 - 模型训练/微调 - 100+ 专家模板 --- ## Risks & Dependencies ### 风险 1. **TeamOrchestrator 重写复杂度高** — 从 hub-and-spoke 到流水线是架构级变更 - 缓解:U4 先建立数据模型,U5 基于模型重写,分步验证 2. **上下文隔离可能影响 AgentPool** — 每个阶段创建新 Agent 实例可能增加资源消耗 - 缓解:阶段完成后立即销毁 Agent 实例;`MAX_PHASES = 10` 限制 3. ~~**前端数据模型可能仍有不一致** — `ITeamPlanPhase` 类型需确认与后端 `PlanPhase.to_dict()` 完全对齐~~ - **已解决(深化审查 F1-F3)**:明确 `ITeamPlanPhase` 需新增 `depends_on`/`task_description`/`result`,`WsServerMessage` 需新增 3 个 phase 事件,`chat.ts` 需新增 3 个 case 分支。U8 已显式列出所有前端修改。 4. **Lead Expert 分解质量依赖 LLM** — 阶段划分可能不合理 - 缓解:`_parse_phases` 中验证 `depends_on` 引用的阶段存在;无效时 fallback 到单阶段(U5 新增 LLM 分解失败容错测试) ### 依赖 - `ExpertTeamRouter` 代码已完整(仅需 U1 修复 bug) - `ExpertTeam` 代码已完整(无需修改) - `SharedWorkspace` 代码已完整(仅需约定 key) - `HandoffTransport` 代码已完整(无需修改) - `_execute_board_meeting` 提供集成模式参考 --- ## Open Questions ### 计划时已解决 - **阶段依赖图设计**: 恢复 `PlanPhase`(KTD1) - **编排逻辑**: Lead 分解为阶段,拓扑排序执行(KTD2) - **上下文隔离**: 独立 `ConfigDrivenAgent` 实例(KTD3) - **前后端数据模型**: 后端恢复 `phases`,与前端 `plan_phases` 对齐(KTD1) - **`TeamStatus.PLANNING` 状态**: 新增枚举值,对齐前端(KTD6, 深化审查 F4) ### 深化审查已解决 - **`_VALID_TEAM_EVENT_TYPES` 是否包含 phase 事件**: 已包含,U6 无需修改 frozenset(V1) - **`ExpertTeam.create_team()` 签名**: 确认为 `(lead_config, member_configs)`,U6 需拆分 configs(V2) - **`ExpertTeam.workspace`/`handoff_transport` 可见性**: 均为 public property,U5 可直接使用(V3) - **`ExpertConfig.llm` 字段结构**: 为 `dict[str, Any] | None`,U5 的 `_get_model` 逻辑已明确(V4) - **`ITeamPlanPhase` 缺少 `depends_on`**: U8 显式新增字段(F1) - **`WsServerMessage` 缺少 phase 事件**: U8 显式新增 3 个事件类型(F2) - **前端 `chat.ts` 缺少 phase 事件 handler**: U8 显式新增 3 个 case 分支(F3) ### 延后到实现时 - `PlanPhase` 的精确字段名和类型(U4 实现时确定) - `_parse_phases` 的 JSON 解析容错策略(U5 实现时确定) - `AgentPool.create_agent` 的资源清理时机(U5 实现时确定) - `ExpertTeamView.vue` 的依赖关系可视化样式(U8 实现时确定) --- ## System-Wide Impact ### 受影响组件 | 组件 | 影响 | 说明 | |------|------|------| | `src/agentkit/experts/router.py` | 修改 | U1 修复模板引用 bug | | `src/agentkit/experts/plan.py` | 重写 | U4 恢复阶段依赖图 | | `src/agentkit/experts/team.py` | 修改 | U5 新增 `TeamStatus.PLANNING` 枚举值(KTD6, F4) | | `src/agentkit/experts/orchestrator.py` | 重写 | U5 流水线模式 | | `src/agentkit/server/routes/chat.py` | 修改 | U6 新增 `_execute_team_collab` | | `configs/experts/` | 新增 | U7 新增 5 个编程专家模板 | | `src/agentkit/server/frontend/src/api/types.ts` | 修改 | U8 更新 `ITeamPlanPhase` 和 `WsServerMessage`(F1, F2) | | `src/agentkit/server/frontend/src/stores/chat.ts` | 修改 | U8 新增 phase 事件 handler(F3) | | `src/agentkit/server/frontend/src/stores/team.ts` | 修改 | U8 新增 `updatePhaseStatus` 方法 | | `src/agentkit/server/frontend/src/components/chat/ExpertTeamView.vue` | 修改 | U8 阶段展示 | | `tests/integration/test_expert_team.py` | 重写 | U9 流水线测试 | | `tests/unit/experts/test_plan.py` | 新增 | U4 单元测试 | | `tests/unit/experts/test_orchestrator.py` | 新增 | U5 单元测试 | | `tests/unit/server/routes/test_chat_team.py` | 新增 | U6 单元测试 | | `AGENTS.md` | 修改 | U3 文档更新 | ### 不受影响 - `@board` 群聊讨论模式(完全独立) - `@skill:` 路由(独立) - `BoardOrchestrator` / `BoardTeam` / `BoardRouter`(不修改) - `RequestPreprocessor`(不修改) - LLM Gateway(不修改) - 记忆系统(不修改) - 自进化系统(不修改)