# 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 `(触发辩论)、或普通文本(追加上下文) **理由**:复用已有方法,不引入新队列。与 `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 状态 COMPLETED,result="无需辩论" - 错误路径: 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` phase(topic="方案评审", 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 `、普通文本追加上下文。 **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 ` - 调用 `team.add_user_intervention(content)` - `TeamOrchestrator` 在阶段边界(每层执行前 + 辩论每轮前)检查 `consume_user_interventions()`: - `/stop` → 终止执行,走 fallback - `/debate ` → 动态插入 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 + U4(CLI 需要路由 + 辩论 + 干预) --- ## 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 行)