fischer-agentkit/docs/plans/2026-06-17-003-feat-team-pi...

797 lines
37 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.

---
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-111U6 只需调用 `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 propertyU5 可直接使用 `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 dependenciesR1 恢复)"
- "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**: U4PlanPhase 已实现)
**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 propertyV3 验证通过)
**移除硬编码 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**: U5TeamOrchestrator 已重写), 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**: U4PlanPhase 已实现), U6WebSocket 事件已定义)
**Files**:
- `src/agentkit/server/frontend/src/api/types.ts` — 更新 `ITeamPlanPhase``WsServerMessage` 类型F1, F2
- `src/agentkit/server/frontend/src/stores/chat.ts` — 新增 phase 事件 handlerF3
- `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**: U4PlanPhase, U5TeamOrchestrator, U6chat.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 依赖 AA 失败时 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 无需修改 frozensetV1
- **`ExpertTeam.create_team()` 签名**: 确认为 `(lead_config, member_configs)`U6 需拆分 configsV2
- **`ExpertTeam.workspace`/`handoff_transport` 可见性**: 均为 public propertyU5 可直接使用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 事件 handlerF3 |
| `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不修改
- 记忆系统(不修改)
- 自进化系统(不修改)