fischer-agentkit/docs/plans/2026-06-24-001-feat-agent-d...

501 lines
24 KiB
Markdown
Raw 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.

# feat: Agent 间结构化辩论协作
**日期**: 2026-06-24
**状态**: active
**范围**: Deep — feature
**Origin**: `docs/brainstorms/2026-06-24-agent-debate-collaboration-requirements.md`
---
## Summary
`@team` 多 Agent 协作模式中引入"Lead 主导的结构化辩论"能力。当前专家隔离执行、无互动,本计划让 Lead 能在关键决策点发起辩论(指定专家交锋→裁决),支持自动检测分歧触发 + 用户手动触发。同时修复 CLI 完全缺失多 Agent 入口的问题,并顺带补齐 `@team` 执行期间的用户干预通道(当前无 `/stop`)。
---
## Problem Frame
当前 `TeamOrchestrator``src/agentkit/experts/orchestrator.py`)是 hub-and-spoke 模式Lead 分解任务 → 专家隔离执行 → Lead 汇总。`HandoffTransport` 只做事件广播,专家间无通信通道。用户反馈"体现不出多 Agent 协同"——本质是"并行单 Agent"而非协作。
同时存在三个已知缺口:
1. `ExecutionMode.TEAM_COLLAB` 是死代码(`src/agentkit/chat/skill_routing.py:35`,全代码库无产生点)
2. CLI 完全没有多 Agent 入口(`src/agentkit/cli/chat.py` 不处理 `@team`/`@board` 前缀)
3. `@team` 执行期间无用户干预通道(`ExpertTeam.broadcast_user_message()` 方法存在但 `TeamOrchestrator.execute()` 从不检查)
---
## Requirements
源自 `docs/brainstorms/2026-06-24-agent-debate-collaboration-requirements.md`
- **R1**: 用户在 `@team` 任务执行中,能看到专家间就某个分歧点来回辩论(不是各自独立发言)
- **R2**: Lead 能自动检测专家产出间的冲突/分歧,并触发辩论
- **R3**: 用户能在执行期间手动请求就某个点发起辩论
- **R4**: 辩论有明确收敛Lead 裁决,产出喂给下一阶段
- **R5**: CLI 用户能使用 `@team`/`@board`,且能触发辩论
- **R6**: 简单任务可以跳过辩论,不强制增加延迟
---
## Key Technical Decisions
### KTD1: 辩论作为 `DEBATE` 阶段类型,而非独立编排器
`PlanPhase` 上新增 `phase_type` 字段(`EXECUTION` | `DEBATE`),而非创建独立的 `DebateOrchestrator`。辩论阶段复用现有流水线的拓扑排序、依赖管理、SharedWorkspace 机制。
**理由**:最小架构改动。辩论阶段与其他阶段一样有 `depends_on`,只是执行逻辑不同。避免引入第二套编排引擎导致状态管理分裂。
**代价**`TeamOrchestrator._execute_phase()` 需要按 `phase_type` 分派,增加一个分支。可接受。
### KTD2: 辩论执行逻辑借鉴 `BoardOrchestrator`,但不复用其类
`BoardOrchestrator``src/agentkit/experts/board_orchestrator.py`)已实现"成员并行发言→主持人小结"的多轮循环。辩论阶段借鉴这个模式Lead 开场→专家轮流发言→Lead 裁决),但作为 `TeamOrchestrator._execute_debate_phase()` 方法内联,不实例化 `BoardOrchestrator`
**理由**`BoardOrchestrator` 绑定 `BoardTeam`(独立容器、独立历史、独立状态机),强行复用会引入两套状态同步。内联一个方法比桥接两个编排器简单。
### KTD3: 用户干预通道复用 `ExpertTeam.broadcast_user_message()` + 新增 WS 消息类型
`ExpertTeam` 已有 `broadcast_user_message()` 方法(`src/agentkit/experts/team.py:253`),但 `TeamOrchestrator.execute()` 从不检查。方案:
- WS 新增 `team_intervention` 消息类型,`chat.py` 收到后调用 `team.broadcast_user_message()`
- `TeamOrchestrator` 在阶段边界检查干预队列(与 `BoardOrchestrator` 检查 `consume_user_interventions()` 一致)
- 干预消息可以是 `/stop`(停止团队)、`/debate <topic>`(触发辩论)、或普通文本(追加上下文)
**理由**:复用已有方法,不引入新队列。与 `BoardOrchestrator` 的干预检查模式一致,降低认知成本。
### KTD4: 分歧检测作为 Lead 的 LLM 判断,带"是否值得辩论"的明确标准
自动触发不依赖复杂的一致性算法,而是 Lead 在阶段完成后用 LLM 判断"该阶段产出是否与其他阶段/约束冲突,是否值得辩论"。Prompt 给出明确判断标准(见 U3
**理由**YAGNI——不引入冲突检测框架。LLM 判断够用,误报由"跳过辩论"逃生舱兜底。若不可靠,降级为纯手动触发(需求文档已记录此假设)。
### KTD5: CLI 复用 `ExpertTeamRouter`/`BoardRouter` + Rich 渲染
CLI 在 `chat.py` 的 chat loop 中,于 skill routing 之前拦截 `@team`/`@board` 前缀,复用 Web 侧的 `ExpertTeamRouter.resolve()``BoardRouter.resolve()`。辩论过程用 Rich 的 `Panel` + 不同颜色渲染专家发言。
**理由**路由逻辑已存在CLI 只需接入。不重复实现前缀解析。
---
## High-Level Technical Design
### 辩论阶段在流水线中的位置
```
Lead 分解任务 → phases[]
├── [可选] 方案评审辩论 (DEBATE phase, depends_on: 无, 在执行前)
│ Lead 开场 → 专家质疑方案 → Lead 修订 → 产出"确认的方案"
├── 执行阶段 A (EXECUTION phase)
├── 执行阶段 B (EXECUTION phase, depends_on: A)
├── [自动] 决策点辩论 (DEBATE phase, depends_on: B, Lead 检测分歧后动态插入)
│ Lead 陈述分歧 → 专家 A/B 交锋 → Lead 裁决 → 产出"辩论结论"
└── 执行阶段 C (EXECUTION phase, depends_on: 辩论结论)
```
### 辩论阶段执行流程(内联于 TeamOrchestrator
```
_execute_debate_phase(phase, plan):
1. 解析 phase.debate_config: {topic, participants, max_rounds}
2. Lead 开场:陈述分歧点 + 上下文 → broadcast debate_started
3. for round in 1..max_rounds:
a. 检查用户干预(/stop 则提前结束)
b. 参与专家并行发言(基于历史 + 角色)→ broadcast expert_argument
c. Lead 小结本轮 → broadcast debate_round_summary
4. Lead 裁决:采纳/折中/搁置 → broadcast debate_resolved
5. 结论写入 SharedWorkspace ({plan_id}/phase/{phase_id}/output)
6. phase.status = COMPLETED
```
### 用户干预通道数据流
```
Web 用户 → WS message {type: "team_intervention", content: "/debate 前端框架选型"}
→ chat.py _handle_chat_message 检测团队执行中
→ team.broadcast_user_message(content)
→ TeamOrchestrator 在阶段边界检查 team.consume_user_interventions()
→ 识别 /debate 命令 → 动态插入 DEBATE phase
CLI 用户 → 输入 /debate 前端框架选型
→ cli/chat.py 检测团队执行中
→ team.broadcast_user_message(content)
→ 同上
```
---
## Implementation Units
### U1. 数据模型PhaseType 枚举 + PlanPhase 扩展
**Goal**: 为 `PlanPhase` 增加 `phase_type` 字段和辩论配置,使流水线能区分执行阶段和辩论阶段。
**Requirements**: 支撑 R1, R4
**Dependencies**: 无
**Files**:
- `src/agentkit/experts/plan.py` (修改)
- `tests/unit/experts/test_plan.py` (新建或修改)
**Approach**:
- 新增 `PhaseType(str, enum.Enum)`: `EXECUTION = "execution"`, `DEBATE = "debate"`
- `PlanPhase` 新增字段:
- `phase_type: PhaseType = PhaseType.EXECUTION`(默认执行,向后兼容)
- `debate_config: dict[str, Any] | None = None`(辩论阶段专用:`topic`, `participants: list[str]`, `max_rounds: int = 2`
- `to_dict()` / `from_dict()` 序列化新字段
- `topological_sort()` 无需改动(辩论阶段也有 `depends_on`,与其他阶段一视同仁)
**Patterns to follow**: 现有 `PlanPhase` 的 dataclass + enum 模式(`src/agentkit/experts/plan.py`
**Test scenarios**:
- Happy path: 创建 `DEBATE` 类型 phase序列化/反序列化后字段保留
- 向后兼容: 不带 `phase_type` 的旧 dict 反序列化后默认为 `EXECUTION`
- 边界: `debate_config` 为 None 时不影响 EXECUTION 阶段
- 拓扑排序: 混合 EXECUTION + DEBATE 阶段的依赖图能正确分层
**Verification**: `pytest tests/unit/experts/test_plan.py -x -q` 通过
---
### U2. 辩论阶段执行器TeamOrchestrator
**Goal**: 在 `TeamOrchestrator` 中实现辩论阶段的执行逻辑,借鉴 `BoardOrchestrator` 的多轮发言模式。
**Requirements**: R1, R4, R6
**Dependencies**: U1
**Files**:
- `src/agentkit/experts/orchestrator.py` (修改)
- `tests/unit/experts/test_orchestrator_debate.py` (新建)
**Approach**:
- `_execute_phase()` 入口按 `phase.phase_type` 分派:
- `EXECUTION` → 现有 `_execute_phase()` 逻辑(重命名为 `_execute_execution_phase()`
- `DEBATE` → 新增 `_execute_debate_phase()`
- `_execute_debate_phase(phase, plan)`:
1.`phase.debate_config` 解析 topic/participants/max_rounds
2. Lead 开场LLM 生成,陈述分歧点)→ emit `debate_started`
3. 循环 max_rounds 轮:
- 检查 `team.consume_user_interventions()`/stop 提前结束)
- 参与专家并行发言LLM 生成,基于历史 + 角色 prompt→ emit `expert_argument`
- Lead 小结 → emit `debate_round_summary`
4. Lead 裁决LLM 生成JSON: `decision`, `rationale`, `conclusion`)→ emit `debate_resolved`
5. 结论写入 SharedWorkspace`phase.status = COMPLETED`
- 辩论 prompt 借鉴 `BoardOrchestrator._generate_expert_speech()` 的角色注入模式persona + thinking_style + speaking_style + history
- **逃生舱**: `debate_config` 可设 `skip: true`,或 Lead 判断"无分歧"时直接跳过(`phase.status = COMPLETED`, result = "无需辩论"
**Technical design** (directional):
```python
async def _execute_debate_phase(self, phase: PlanPhase, plan: TeamPlan) -> dict[str, Any]:
config = phase.debate_config or {}
topic = config.get("topic", phase.task_description)
participants = config.get("participants", [])
max_rounds = min(config.get("max_rounds", 2), 4) # 硬上限 4 轮
# Lead 开场
lead = self._team.lead_expert
opening = await self._generate_debate_opening(lead, topic, phase)
await self._broadcast_event("debate_started", {...})
history = [{"expert": lead.config.name, "content": opening, "round": 0}]
for round_num in range(1, max_rounds + 1):
# 检查用户干预
interventions = self._team.consume_user_interventions()
if self._has_stop_command(interventions):
break
# 参与专家并行发言
experts = [self._team.get_expert(name) for name in participants if self._team.get_expert(name)]
speeches = await asyncio.gather(
*[self._generate_debate_argument(e, topic, history, round_num) for e in experts],
return_exceptions=True,
)
for expert, speech in zip(experts, speeches):
if not isinstance(speech, Exception):
history.append({"expert": expert.config.name, "content": speech, "round": round_num})
await self._broadcast_event("expert_argument", {...})
# Lead 小结
summary = await self._generate_debate_summary(lead, topic, history, round_num)
history.append({"expert": lead.config.name, "content": summary, "round": round_num})
await self._broadcast_event("debate_round_summary", {...})
# Lead 裁决
verdict = await self._generate_debate_verdict(lead, topic, history)
await self._broadcast_event("debate_resolved", {...})
# 写入 SharedWorkspace
result = {"content": verdict.get("conclusion", ""), "verdict": verdict}
phase.status = PhaseStatus.COMPLETED
phase.result = result
return result
```
**Patterns to follow**:
- `BoardOrchestrator._generate_expert_speech()` 的角色 prompt 模式(`src/agentkit/experts/board_orchestrator.py:268`
- `BoardOrchestrator._has_stop_command()` 的停止命令检查(`src/agentkit/experts/board_orchestrator.py:486`
- `TeamOrchestrator._broadcast_event()` 的事件广播模式
**Test scenarios**:
- Happy path: 2 轮辩论2 个专家参与Lead 裁决产出结论phase 状态变为 COMPLETED
- 边界: max_rounds=1 时只辩论一轮就裁决
- 边界: participants 为空时Lead 直接给出结论(无辩论)
- 用户停止: 辩论中收到 /stop提前结束并裁决
- 逃生舱: `debate_config.skip=true` 时直接跳过phase 状态 COMPLETEDresult="无需辩论"
- 错误路径: LLM 不可用时Lead 用模板文本裁决,不抛异常
- 集成: 辩论结论写入 SharedWorkspace后续 EXECUTION 阶段能读取
**Verification**: `pytest tests/unit/experts/test_orchestrator_debate.py -x -q` 通过
---
### U3. 分歧检测 + 方案评审辩论(自动触发)
**Goal**: Lead 在阶段完成后自动检测分歧,动态插入辩论阶段;在分解任务后可选发起方案评审辩论。
**Requirements**: R2, R6
**Dependencies**: U1, U2
**Files**:
- `src/agentkit/experts/orchestrator.py` (修改)
- `tests/unit/experts/test_divergence_detection.py` (新建)
**Approach**:
- 新增 `_detect_divergence(lead, completed_phase, plan) -> bool`:
- Lead 用 LLM 判断该阶段产出是否与其他已完成阶段冲突,或是否存在多个可行方案
- Prompt 给出明确标准:"以下情况值得辩论1) 两个阶段产出矛盾 2) 阶段产出与任务约束冲突 3) 存在多个合理方案。其他情况返回 false。"
- LLM 不可用或判断失败时返回 false宁可漏报不误报
- `execute()` 主循环修改:每层执行完成后,对每个 completed phase 运行分歧检测,若 true 则动态插入一个 `DEBATE` phase`depends_on` 指向该 phase加入下一层
- 方案评审辩论(可选):`_decompose_task()` 返回 phases 后Lead 判断"该任务是否需要方案评审",若需要则在 phases 头部插入一个 `DEBATE` phasetopic="方案评审", participants=所有成员, depends_on=[]
- **跳过逻辑**: `MAX_DEBATES = 3` 限制单次执行最多插入 3 个辩论阶段防止成本失控简单任务phases <= 2默认跳过方案评审
**Patterns to follow**: `TeamOrchestrator._decompose_task()` 的 LLM prompt + JSON 解析模式
**Test scenarios**:
- Happy path: 两个阶段产出矛盾,分歧检测返回 true自动插入辩论阶段
- Happy path: 阶段产出一致,分歧检测返回 false不插入辩论
- 边界: phases <= 2 时跳过方案评审
- 边界: 已插入 3 个辩论后不再插入MAX_DEBATES 上限)
- 错误路径: LLM 不可用时分歧检测返回 false
- 集成: 插入的辩论阶段能被 `topological_sort()` 正确分层,后续阶段能依赖辩论结论
**Verification**: `pytest tests/unit/experts/test_divergence_detection.py -x -q` 通过
---
### U4. 用户干预通道 + 手动辩论触发WS + CLI 共用)
**Goal**: 建立 `@team` 执行期间的用户干预通道,支持 `/stop`、`/debate <topic>`、普通文本追加上下文。
**Requirements**: R3, R5
**Dependencies**: U1, U2
**Files**:
- `src/agentkit/experts/team.py` (修改:补齐干预队列,参考 BoardTeam 模式)
- `src/agentkit/server/routes/chat.py` (修改:`_execute_team_collab` 增加 WS 干预消息处理)
- `src/agentkit/cli/chat.py` (修改:团队执行期间拦截 `/debate`、`/stop` 命令)
- `tests/unit/experts/test_team_intervention.py` (新建)
**Approach**:
- `ExpertTeam` 补齐干预队列(参考 `BoardTeam``add_user_intervention()` / `consume_user_interventions()``src/agentkit/experts/board.py`
- `_interventions: asyncio.Queue` (bounded, maxsize=64)
- `add_user_intervention(msg: str)` / `consume_user_interventions() -> list[str]`
- `broadcast_user_message()` 已存在,改为同时入队干预队列
- WS 侧(`chat.py _execute_team_collab`
- 团队执行期间,`_handle_chat_message` 收到的消息若来自当前 session识别为干预
- 新增 WS 消息类型 `team_intervention`,或复用 `message` 类型 + session 匹配
- 调用 `team.add_user_intervention(content)`
- CLI 侧(`cli/chat.py`
- 团队执行期间,用户输入以 `/` 开头时识别为命令:`/stop`、`/debate <topic>`
- 调用 `team.add_user_intervention(content)`
- `TeamOrchestrator` 在阶段边界(每层执行前 + 辩论每轮前)检查 `consume_user_interventions()`
- `/stop` → 终止执行,走 fallback
- `/debate <topic>` → 动态插入 DEBATE phase
- 其他文本 → 追加到 Lead 上下文(影响后续分解/裁决)
**Patterns to follow**:
- `BoardTeam.add_user_intervention()` / `consume_user_interventions()``src/agentkit/experts/board.py`
- `BoardOrchestrator._has_stop_command()``src/agentkit/experts/board_orchestrator.py:486`
**Test scenarios**:
- Happy path: 用户发送 `/debate 前端框架选型`,团队在下一阶段边界插入辩论
- Happy path: 用户发送 `/stop`,团队终止执行并走 fallback
- Happy path: 用户发送普通文本Lead 在后续裁决中参考
- 边界: 干预队列为空时 `consume_user_interventions()` 返回空列表
- 边界: 多条干预消息累积,一次性消费
- 集成: WS 干预消息能从 `chat.py` 传到 `ExpertTeam` 再到 `TeamOrchestrator`
**Verification**: `pytest tests/unit/experts/test_team_intervention.py -x -q` 通过
---
### U5. 前端辩论可视化
**Goal**: 前端展示辩论过程,专家交锋有独立气泡样式,裁决结果清晰可见。
**Requirements**: R1
**Dependencies**: U1, U2, U4
**Files**:
- `src/agentkit/server/frontend/src/stores/chat.ts` (修改:处理新事件)
- `src/agentkit/server/frontend/src/components/chat/` (修改:辩论气泡组件)
- `src/agentkit/server/frontend/src/types/chat.ts` (修改:新增辩论事件类型)
**Approach**:
- 新增 WS 事件类型声明:`debate_started`、`expert_argument`、`debate_round_summary`、`debate_resolved`
- `chat.ts` 事件处理(参考现有 `expert_step`/`expert_result` 处理,约第 870-1200 行):
- `debate_started`: 显示"辩论开始"分隔线 + 分歧主题
- `expert_argument`: 专家发言气泡,带"辩论中"标签和轮次标记
- `debate_round_summary`: Lead 小结,缩进显示
- `debate_resolved`: 裁决结果,高亮显示(采纳/折中/搁置 + 理由)
- 辩论气泡与普通专家发言气泡视觉区分:边框颜色/图标不同
- 用户干预入口团队执行期间ChatInput 显示"辩论"按钮(发送 `/debate` 命令)
**Patterns to follow**:
- 现有 `expert_step`/`expert_result` 事件处理模式(`src/agentkit/server/frontend/src/stores/chat.ts`
- 现有专家气泡组件样式(`src/agentkit/server/frontend/src/components/chat/`
**Test scenarios**:
- Happy path: 收到 `debate_started` 后显示辩论分隔线和主题
- Happy path: 收到 `expert_argument` 后显示带轮次标记的专家辩论气泡
- Happy path: 收到 `debate_resolved` 后高亮显示裁决结果
- 边界: 辩论中 WebSocket 断开,已显示的辩论内容保留
- 集成: 团队执行期间点击"辩论"按钮,发送 `/debate` 命令
**Verification**: `npm run typecheck` 通过;手动验证辩论过程可视化
---
### U6. CLI 多 Agent 入口 + 辩论支持
**Goal**: CLI 支持 `@team`/`@board` 前缀触发多 Agent 协作,辩论过程用 Rich 渲染。
**Requirements**: R5
**Dependencies**: U1, U2, U4
**Files**:
- `src/agentkit/cli/chat.py` (修改)
- `tests/unit/cli/test_chat_multiagent.py` (新建)
**Approach**:
- chat loop 中,在 skill routing 之前拦截 `@team`/`@board` 前缀:
- 复用 `ExpertTeamRouter.resolve()` / `BoardRouter.resolve()` 解析前缀
- 构建 `ExpertTeam` / `BoardTeam`(复用 Web 侧逻辑,但不经过 WS
- 注册事件回调:用 Rich 渲染而非 WS 广播
- 事件渲染Rich
- `team_formed`: Panel 显示团队成员
- `phase_started`/`expert_step`: 带颜色的专家名 + 任务
- `expert_result`: Markdown 渲染专家产出
- `debate_started`: 分隔线 + "辩论: {topic}"
- `expert_argument`: 带轮次标记的专家发言 Panel不同专家不同颜色
- `debate_resolved`: 高亮裁决结果 Panel
- `team_synthesis`: 最终结果 Markdown 渲染
- 团队执行期间,用户输入 `/debate`/`/stop` 走干预通道U4
- 帮助文本(`_print_help`)补充 `@team`/`@board` 说明
**Patterns to follow**:
- 现有 CLI chat loop 的 Rich 渲染模式(`src/agentkit/cli/chat.py`
- `BoardOrchestrator` 的事件广播模式(改为回调而非 WS
**Test scenarios**:
- Happy path: 输入 `@team 开发登录功能`CLI 显示团队组建 + 阶段执行 + 最终结果
- Happy path: 输入 `@board 讨论微服务 vs 单体`CLI 显示多轮讨论 + 总结
- Happy path: 团队执行中输入 `/debate 前端框架`CLI 显示辩论过程
- Happy path: 团队执行中输入 `/stop`CLI 显示终止 + fallback 结果
- 边界: `@team` 无任务描述时提示用法
- 边界: 专家名称不存在时提示错误
- 集成: CLI `@team` 流程能触发自动分歧检测和辩论U3
**Verification**: `pytest tests/unit/cli/test_chat_multiagent.py -x -q` 通过
---
## Scope Boundaries
### 包含
- `DEBATE` 阶段类型及执行器
- Lead 分歧检测(自动触发)
- 用户干预通道(手动触发 + `/stop`
- 前端辩论可视化
- CLI `@team`/`@board` 入口 + 辩论支持
- "跳过辩论"逃生舱
### 不包含
- Agent 间点对点自由通信(保持 Lead 主导)
- `@board` 模式改造(它已是讨论模式)
- 团队状态持久化(独立问题)
- 辩论成本优化(缓存、早停等,先验证价值)
- `ExecutionMode.TEAM_COLLAB` 死代码清理(顺手可做,非核心交付)
### 延后到后续工作
- 方向 C 全量(辩论优先作为默认模式):先验证 A+C 混合价值
- 自定义团队模板保存:用户选的专家组合无法存为模板
- `orchestrator/` 子系统与团队流程打通
- 辩论成本预算阈值token 上限触发跳过)
---
## Risks & Dependencies
### 风险
1. **分歧检测质量**Lead LLM 判断失误(误报浪费 token漏报错过辩论。缓解明确判断标准 prompt + `MAX_DEBATES` 上限 + 用户可关闭自动触发。
2. **辩论不收敛**:专家反复争论。缓解:硬上限 4 轮 + Lead 强制裁决权。
3. **成本上升**:辩论增加 token 消耗。缓解:逃生舱 + `MAX_DEBATES=3` + 简单任务跳过方案评审。
4. **CLI 交互复杂度**:终端展示多 Agent 辩论不如 Web 直观。缓解Rich Panel + 颜色区分 + 轮次标记。
5. **WS 干预消息与正常消息混淆**团队执行期间用户消息可能被当新任务。缓解session 匹配 + `team_intervention` 消息类型显式区分。
### 依赖
- U1 是所有后续单元的基础(数据模型)
- U2 依赖 U1辩论执行器需要 DEBATE 阶段类型)
- U3 依赖 U1 + U2分歧检测需要插入 DEBATE phase
- U4 依赖 U1 + U2手动触发需要干预通道 + 辩论执行器)
- U5 依赖 U1 + U2 + U4前端需要新事件 + 干预入口)
- U6 依赖 U1 + U2 + U4CLI 需要路由 + 辩论 + 干预)
---
## Open Questions
以下问题留给实现阶段,不阻塞规划:
- `debate_config` 的确切 JSON schema`participants` 是专家名列表还是 Expert 对象?倾向名字列表,执行时解析)
- WS `team_intervention` 消息的确切格式(是复用 `message` 类型 + flag还是新类型倾向新类型显式优于隐式
- 前端辩论气泡的具体样式(边框颜色、轮次标记位置)——实现时对齐现有专家气泡风格
- CLI 辩论渲染是否用 `Live` 动态更新还是逐条打印——倾向逐条打印(辩论是离散事件,不需要流式)
---
## System-Wide Impact
- **后端**: `experts/` 模块plan.py, orchestrator.py, team.py+ `server/routes/chat.py` + `cli/chat.py`
- **前端**: `stores/chat.ts` + `components/chat/` + `types/chat.ts`
- **测试**: 新增 4 个测试文件
- **配置**: 无新配置项(辩论参数通过 `debate_config` 在运行时传递)
- **文档**: AGENTS.md 的 ExecutionMode 描述需更新TEAM_COLLAB 死代码清理可顺手做)
---
## Sources & Research
- 需求文档: `docs/brainstorms/2026-06-24-agent-debate-collaboration-requirements.md`
- 现有团队流水线: `src/agentkit/experts/orchestrator.py`
- 现有私董会讨论引擎(借鉴模式): `src/agentkit/experts/board_orchestrator.py`
- 现有阶段/计划模型: `src/agentkit/experts/plan.py`
- WS 拦截入口: `src/agentkit/server/routes/chat.py``_execute_team_collab` 第 321 行)
- CLI chat当前无多 Agent: `src/agentkit/cli/chat.py`
- 前端事件处理: `src/agentkit/server/frontend/src/stores/chat.ts`(第 870-1200 行)