28 KiB
| title | date | type | depth | origin | deepened |
|---|---|---|---|---|---|
| refactor: 系统性技术债清理 | 2026-06-30 | refactor | deep | 综合评审报告(双 agent 评审 2026-06-30) | 2026-06-30 |
refactor: 系统性技术债清理
Summary
针对综合评审识别的 5 项系统性技术债制定分阶段重构 plan:ReActEngine 流式/非流式 ~800 行重复、TeamOrchestrator 2080 行上帝类、except Exception 345+ 处滥用(聚焦 core//experts/ 关键路径)、Any 类型残留(bitable/ 33 处等)、前端 chat.ts 2025 行巨型文件。通过 characterization-first 重构策略,在测试保障下消除架构契约脱节、恢复类型契约、拆分上帝类。
Problem Frame
综合评审(3.78/5)发现项目在安全性(4.5)和文档(4.5)表现优秀,但代码质量(3.0)和生产就绪度(3.5)存在系统性技术债。P0/P1 项(Dockerfile、jieba、OTel、验收降级标注、skill_routing Any)已修复,但以下 5 项属于大规模重构,需独立 plan 排期:
- ReActEngine 契约脱节:
execute()~130 行与execute_stream()~800 行约 80% 逻辑重复,_execute_loop已存在但execute_stream未复用,文档注释自认"Same logic as execute()"。stream 版有_drain_phase_violations而 execute 版无——行为漂移。 - TeamOrchestrator 上帝类:单文件 2080 行、37 个方法、8 项职责(任务分解/阶段执行/辩论/验收/分歧检测/回滚/综合/干预),
_execute_execution_phase单方法 ~290 行。 except Exception关键路径降级:全项目 345+ 处/100 文件,其中 core/ + experts/ 关键路径(react.py 23、rewoo.py 21、base.py 12、orchestrator.py 20 等)存在验收 LLM 失败静默降级为"自动通过",无声绕过质量门。已加[DEGRADED]标注,但需结构性整改。Any类型残留:bitable/(33 处/8 文件:service.py 6、db.py 6、repository.py 5、formula/functions.py 7、formula/parser.py 4、recalc_worker.py 2、ingestion/database.py 2、ingestion/excel.py 1)、pipeline_state.py(9 处)、tools/computer_use_session.py(8 处)等,违反 AGENTS.md "禁止 any 类型"。- 前端 chat.ts 巨型文件:2025 行、20+ 内部函数,
handleWsMessage单函数处理 10+ 事件类型,vitest 仅 3 个测试。
Requirements
- R1:ReActEngine
execute与execute_stream共用同一循环骨架,消除 80% 重复代码,行为等价(golden trajectory 验证) - R2:TeamOrchestrator 按职责拆分为 ≤7 个模块,主类 ≤600 行,单方法 ≤100 行
- R3:关键路径(
core/、experts/)的except Exception禁止静默降级为"自动通过",必须返回passed=False或degraded=True结构化标记 - R4:bitable/、pipeline_state.py、tools/computer_use_session.py 的
Any替换为具体类型或object - R5:前端 chat.ts 拆分为 chatSocket/chatStream/chatStore 三个模块,每个 ≤500 行,vitest 覆盖
handleWsMessagediscriminated union - R6:所有重构在现有测试(5989 单测)基础上不引入回归,关键路径补充 characterization/golden 测试
Scope Boundaries
In Scope
- ReActEngine
_execute_loop事件回调驱动重构 - TeamOrchestrator 按职责拆分为协作模块
except Exception在core/、experts/目录的关键路径整改Any在 bitable/、pipeline_state.py、tools/computer_use_session.py 的治理- 前端 chat.ts 拆分 + 关键路径 vitest 补充
Out of Scope
- 功能变更或新功能开发
except Exception在server/routes/(portal.py 19 处、chat.py 16 处)的全量整改——deferred to follow-upAny在其他模块(llm/、memory/ 等)的残留——deferred to follow-up- ReActEngine 流式路径的
_drain_phase_violations行为对齐到 execute——属 R1 行为等价验证范围,但修复本身 deferred - 前端 a11y 全量补齐(已修 AssistantText,其余 deferred)
- OTel exporter 实际启用(已加配置注释,启用 deferred)
Deferred to Follow-Up Work
server/routes/的except Exception整治(portal.py 19、chat.py 16)——独立 PRllm/、memory/、client/的Any残留治理——独立 PR- bitable/ 内部
Any残留(repository.py 5、recalc_worker.py 2、ingestion/database.py 2、ingestion/excel.py 1,共 10 处)——独立 PR - 前端 a11y 全量扫描与补齐——独立前端专项
- OTel exporter 启用 + Grafana dashboard 模板——独立运维任务
Key Technical Decisions
KTD1: ReActEngine 重构采用 async generator 统一骨架
决策:将 _execute_loop 改为 async generator,始终 yield ReActEvent;execute 收集所有事件并从最终事件提取 ReActResult;execute_stream 直接 async for 透传事件。
理由:_execute_loop 已是独立方法(529-1174),但 execute_stream 未复用。async generator 是 Python 原生模式,无需 callback/queue 桥接,最简洁。ReActEvent 已存在(line 130,event_type: str 字符串字段,无 EventType 枚举),在 event_type 字段新增 'final_result' 字符串值、在 data dict 中携带 ReActResult 即可——无需新建枚举类型。
替代方案:事件回调(event_sink: Callable | None)——需 queue 桥接 async generator 与 coroutine,复杂度高,违反 ponytail。
KTD2: TeamOrchestrator 拆分为 Mixin 而非独立类
决策:采用 mixin 模式拆分 TeamOrchestrator——PhaseExecutorMixin、DebateRunnerMixin、ReviewGateMixin、DivergenceDetectorMixin、RollbackHandlerMixin、SynthesizerMixin、InterventionHandlerMixin,主类组合这些 mixin。
理由:37 个方法大量访问 self._experts、self._workspace、self._broadcast_event 等共享状态,拆分为独立类需注入大量依赖或改用组合模式,改动面大、回归风险高。Mixin 保持 self 访问,改动最小,符合 ponytail"最小代码"原则。
替代方案:组合模式(独立类 + 依赖注入)——更解耦但改动面大,deferred to follow-up。
KTD3: except Exception 整改采用"分级降级"策略
决策:关键路径(验收/质量门)的 except Exception 改为捕获具体异常(LLMGatewayError、asyncio.TimeoutError 等),降级路径返回 passed=True, degraded=True 结构化标记(而非字符串前缀),让调用方可编程判断。
理由:已加 [DEGRADED] 字符串前缀,但字符串匹配脆弱。结构化 degraded 字段让 _execute_execution_phase 可在广播事件中体现降级状态,运维可监控。
KTD4: Any 治理采用 object + TYPE_CHECKING Protocol 模式
决策:对无法直接导入具体类型(循环依赖)的 Any,替换为 object + 在 TYPE_CHECKING 块中定义 Protocol 描述期望接口;对可直接导入的类型(bitable/ 内部模型),替换为具体 Pydantic 模型。
理由:object 是最严格的"任意类型",禁止属性访问,强制使用 getattr 或 cast。Protocol 在类型检查时提供接口契约,运行时零开销。
KTD5: 前端 chat.ts 按职责层拆分
决策:拆分为 chatSocket.ts(WebSocket 连接/心跳/重连)、chatStream.ts(流式步骤聚合/事件分发)、chatStore.ts(会话/消息状态/computed)。handleWsMessage 的事件分发逻辑提取到 chatStream.ts 的 dispatchWsEvent 函数。
理由:现有 20+ 函数可清晰按职责分组,拆分后每个文件 ≤500 行,可独立测试。
KTD6: Characterization-first 执行姿态
决策:U1(ReActEngine)和 U2(TeamOrchestrator)在重构前先补充 characterization/golden 测试,锁定现有行为,再执行重构。
理由:核心引擎重构高风险,现有测试虽多但 mock 密度高(评审报告),流式路径缺乏 golden trajectory 快照。先锁行为再重构是安全底线。
High-Level Technical Design
ReActEngine 事件回调驱动重构(U1)
flowchart TD
A[execute 入口] --> B[_execute_loop async generator]
C[execute_stream 入口] --> B
B --> D{每个步骤}
D --> E[yield ReActEvent]
E --> F[Think: LLM 调用]
F --> G[Act: 工具执行]
G --> H[Observe: 结果回灌]
H --> I{停止条件?}
I -->|否| D
I -->|是| J[yield 'final_result' event]
A --> K[收集所有 events\n提取 ReActResult]
C --> L[async for 透传 events]
TeamOrchestrator Mixin 拆分(U2)
graph TB
subgraph TeamOrchestrator[主类 ≤600 行]
EX[execute / _run_pipeline / resume]
DC[_decompose_task / _parse_phases]
UT[共享状态: _experts / _workspace / _broadcast_event]
end
subgraph Mixins
PE[PhaseExecutorMixin\n阶段执行 + 隔离 agent]
DR[DebateRunnerMixin\n辩论 5 阶段]
RG[ReviewGateMixin\n验收 + risk_flags]
DD[DivergenceDetectorMixin\n分歧检测 + 插入辩论]
RH[RollbackHandlerMixin\n依赖失败 + 回滚]
SY[SynthesizerMixin\n综合 + 单 agent 回退]
IH[InterventionHandlerMixin\n用户干预]
end
TeamOrchestrator -.组合.-> Mixins
Implementation Units
U1. ReActEngine 事件回调驱动重构
Goal: 将 _execute_loop 改为 async generator,execute 与 execute_stream 共用同一骨架,消除 80% 重复代码。
Requirements: R1, R6
Dependencies: 无(首个单元)
Files:
src/agentkit/core/react.py— 重构_execute_loop、execute、execute_stream;ReActEvent扩展'final_result'事件值tests/unit/test_react_engine.py— 补充 golden trajectory 测试tests/unit/test_react_token_streaming.py— 验证流式行为等价
Approach:
- 扩展
ReActEvent(line 130,event_type: str字符串字段)增加'final_result'字符串值,在datadict 中携带ReActResult(不新建 EventType 枚举) - 将
_execute_loop(529-1174)改为 async generator,在每个关键节点(think/act/observe/phase_violation/compress)yield ReActEvent,结束时yield ReActEvent(event_type='final_result', data={'result': final_result}) execute(396-527)改为[e async for e in self._execute_loop(...)],从最后一个 event 提取ReActResult返回execute_stream(1176-1989)改为async for event in self._execute_loop(...): yield event,删除 ~800 行重复逻辑- 合并
_drain_phase_violations差异:确认 stream 版有而 execute 版无的行为,在_execute_loop中统一处理
Execution note: Characterization-first。重构前先在 test_react_engine.py 补充 golden trajectory 测试(固定输入 → 期望事件序列快照),锁定现有行为。重构后验证快照不变。
Patterns to follow: 项目已有的 async generator 安全规则(return; yield 守卫,见 .trae/rules/project_rules.md)
Test scenarios:
- Happy path: 单步工具调用 → 期望事件序列 [thinking, tool_call, tool_result, final_result],execute 返回 ReActResult.status="success"
- Happy path 流式等价: 同一输入分别调用 execute 和 execute_stream,验证 execute 返回的 ReActResult 与 execute_stream 最后的
'final_result'event 内容一致 - 多步循环: 3 步工具调用后 LLM 不返回 tool_calls → 停止,事件序列长度正确
- Edge case: 空工具列表: 无工具时 LLM 直接返回文本 → 单个 final_result 事件
- Edge case: max_steps 达到: 循环达到 max_steps → final_result.status="timeout"
- Error path: 工具执行失败: 工具抛异常 → tool_result event 包含错误,循环继续
- Error path: LLM 调用失败: LLM gateway 抛异常 → final_result.status="empty_fallback" 或错误状态
- Phase violation: phase 不允许的工具调用 → phase_violation event,循环继续
- CancellationToken: 中途取消 → final_result.status="cancelled"
- 压缩触发: 上下文超阈值 → compress event,循环继续
- Golden trajectory: 固定 mock LLM 响应序列 → 完整事件序列快照比对(重构前后一致)
Verification: execute 与 execute_stream 对同一输入产生等价结果;现有 5 个 react 测试文件全部通过(tests/unit/test_react_engine.py、tests/unit/test_react_token_streaming.py、tests/unit/test_react_phase_enforcement.py、tests/unit/test_react_skill_mcp_integration.py、tests/unit/test_react_compression.py);新增 golden trajectory 测试通过;_execute_loop 是唯一的循环实现。
U2. TeamOrchestrator Mixin 拆分
Goal: 将 2080 行上帝类按职责拆分为 7 个 mixin,主类 ≤600 行,单方法 ≤100 行。
Requirements: R2, R6
Dependencies: U1(ReActEngine 重构完成后,减少 TeamOrchestrator 测试耦合)
Files:
src/agentkit/experts/orchestrator.py— 主类瘦身,组合 mixinsrc/agentkit/experts/_phase_executor.py— 新建,PhaseExecutorMixinsrc/agentkit/experts/_debate_runner.py— 新建,DebateRunnerMixinsrc/agentkit/experts/_review_gate.py— 新建,ReviewGateMixinsrc/agentkit/experts/_divergence_detector.py— 新建,DivergenceDetectorMixinsrc/agentkit/experts/_rollback_handler.py— 新建,RollbackHandlerMixinsrc/agentkit/experts/_synthesizer.py— 新建,SynthesizerMixinsrc/agentkit/experts/_intervention_handler.py— 新建,InterventionHandlerMixintests/unit/experts/test_team_orchestrator.py— 验证拆分后行为等价
Approach:
- 按职责将 37 个方法分组到 7 个 mixin(见 HTD 图):
PhaseExecutorMixin:_execute_phase,_execute_execution_phase,_get_isolated_agent,_cleanup_isolated_agent,_build_dependency_context,_read_dependency_output,_offload_result,_notify_collaboratorsDebateRunnerMixin:_execute_debate_phase,_generate_debate_*(4 个),_format_debate_historyReviewGateMixin:_review_phase_output,_parse_risk_flagsDivergenceDetectorMixin:_detect_divergence,_insert_debate_phase,_check_divergence_and_insert_debates,_maybe_add_plan_review_debateRollbackHandlerMixin:_mark_dependents_failed,_run_phase_rollbackSynthesizerMixin:_synthesize_results,_fallback_to_single_agentInterventionHandlerMixin:_consume_team_interventions,_has_stop_command,_process_interventions
- 主类保留:
execute,_run_pipeline,resume,_decompose_task,_parse_phases,_get_model,_get_llm_gateway,_broadcast_event+ 共享状态字段 - 每个 mixin 文件顶部注明
# TYPE_CHECKING: 由 TeamOrchestrator 组合,访问 self 共享状态 _execute_execution_phase(~290 行)拆分为_prepare_phase_context、_run_agent_steps、_finalize_phase三个子方法
Execution note: Characterization-first。拆分前先运行现有 test_team_orchestrator.py 确认绿色,拆分后验证不变。如现有测试覆盖不足,补充关键路径测试(阶段执行/辩论/回滚/综合)。
Patterns to follow: Python mixin 模式,TYPE_CHECKING 块声明共享状态 Protocol
Test scenarios:
- Happy path 拆分等价: 现有
test_team_orchestrator.py全部通过(拆分前后行为不变) - 阶段执行: 单阶段计划 → COMPLETED 状态,广播事件序列正确
- 多阶段并行: 3 阶段计划(2 个同层并行) → 阶段并行执行,依赖正确
- 辩论阶段: debate 类型阶段 → 辩论 5 步执行(opening/argument/summary/verdict)
- 验收降级: LLM gateway 不可用 →
passed=True, degraded=True(U3 联动) - 回滚: 阶段失败 → 依赖阶段标记 FAILED,回滚执行
- 分歧检测: 多轮交互超阈值 → 插入辩论阶段
- 用户干预: stop 命令 → 计划暂停
- 综合: 所有阶段完成 → Lead 综合,广播 team_synthesis
- 单 agent 回退: 所有阶段失败 → 回退到单 agent 模式
Verification: 主类 ≤600 行;每个 mixin 文件 ≤400 行;现有 test_team_orchestrator.py 全部通过;ruff check 通过。
U3. except Exception 关键路径治理
Goal: core/、experts/ 目录的 except Exception 整改为捕获具体异常 + 结构化降级标记。
Requirements: R3, R6
Dependencies: U2(TeamOrchestrator 拆分后,验收逻辑在 ReviewGateMixin 中)
Files:
src/agentkit/experts/_review_gate.py— 验收降级改结构化degraded字段(联动 U2)src/agentkit/core/react.py—_execute_loop内的except Exception分类src/agentkit/core/base.py—execute()的except Exception分类src/agentkit/orchestrator/pipeline_engine.py— 关键路径except Exception分类tests/unit/experts/test_team_orchestrator.py— 验收降级测试tests/unit/test_react_engine.py— 错误路径测试
Approach:
- 验收路径(
_review_phase_output):except Exception改为except (LLMGatewayError, asyncio.TimeoutError, ConnectionError),降级返回(True, ReviewResult(degraded=True, reason="..."))而非字符串前缀 - 定义
ReviewResultdataclass:passed: bool, degraded: bool = False, feedback: str = "",替换裸 tuple 返回 - 广播层联动(AE3):
_review_phase_output在广播review_result事件时,payload 必须包含degraded: bool字段(从ReviewResult.degraded取值),让前端/运维可编程判断降级状态——而非依赖[DEGRADED]字符串前缀匹配 core/react.py_execute_loop内:except Exception按 LLM 错误/工具错误/超时分类,保留"日志 + 继续"但记录结构化错误码core/base.pyexecute():except Exception改为except (AgentError, asyncio.TimeoutError, CancelledError),其余 re-raise- 非 LLM 不可用类的降级(如工具执行失败)保持现有"日志 + 继续"行为,但用
logger.warning替代logger.error避免告警疲劳 - 调用方迁移:搜索
_review_phase_output的所有调用点(_execute_execution_phase等),将解构passed, feedback = ...改为review = ...; passed, feedback, degraded = review.passed, review.feedback, review.degraded,确保degraded字段向后兼容(默认False)
Patterns to follow: 项目已有的 ToolValidationError 类型化错误码模式(react.py:2269-2277)
Test scenarios:
- 验收 LLM 不可用: gateway 为 None →
ReviewResult(passed=True, degraded=True) - 验收 LLM 超时: gateway 抛 TimeoutError →
ReviewResult(passed=True, degraded=True) - 验收 LLM 返回无效: gateway 返回非 JSON → 解析失败,
ReviewResult(passed=False, feedback="...") - 验收正常通过: gateway 返回 "passed" →
ReviewResult(passed=True, degraded=False) - 工具执行失败: 工具抛 ValueError →
_execute_loop记录错误码,循环继续 - LLM 调用失败: gateway 抛 ConnectionError → final_result 携带结构化错误码
- CancellationToken: 中途取消 → CancelledError 正确传播,不被 except Exception 吞掉
- 调用方迁移回归:
_review_phase_output所有调用点(_execute_execution_phase等)正确解构ReviewResult,degraded字段向后兼容(旧调用点未迁移时不报错,默认False) - review_result WS 事件 payload(AE3): 验收降级时广播的
review_result事件 payload 含degraded: true字段;正常通过时degraded: false
Verification: 基线 core/ + experts/ 共 84 处 except Exception(react.py 23 + rewoo.py 21 + base.py 12 + orchestrator.py 20 + board_orchestrator.py 6 + 其余 2);整改后减少 ≥50%;验收降级返回结构化 ReviewResult 且 review_result WS 事件含 degraded 字段;现有测试通过。
U4. Any 类型残留治理
Goal: bitable/、pipeline_state.py、tools/computer_use_session.py 的 Any 替换为具体类型或 object + Protocol。
Requirements: R4, R6
Dependencies: 无(可与 U1-U3 并行)
Files:
src/agentkit/bitable/service.py— 6 处Anysrc/agentkit/bitable/db.py— 6 处Anysrc/agentkit/bitable/formula/functions.py— 7 处Anysrc/agentkit/bitable/formula/parser.py— 4 处Anysrc/agentkit/orchestrator/pipeline_state.py— 9 处Any(self._redis: Any等)src/agentkit/tools/computer_use_session.py— 8 处Any- 对应测试文件
Deferred(独立 PR,本 U 不处理):
src/agentkit/bitable/repository.py— 5 处src/agentkit/bitable/recalc_worker.py— 2 处src/agentkit/bitable/ingestion/database.py— 2 处src/agentkit/bitable/ingestion/excel.py— 1 处- 注:
bitable/formula/engine.py经核实: Any数量为 0,无需处理;bitable/formula.py文件不存在(实际为formula/目录下的functions.py+parser.py+engine.py)
Approach:
- bitable/ in-scope(23 处:service.py 6 + db.py 6 + formula/functions.py 7 + formula/parser.py 4;deferred 10 处见上):定义
BitableRecord = dict[str, str | int | float | None]TypeAlias 替换dict[str, Any];公式求值结果用FormulaResult = str | int | float | None - pipeline_state.py(9 处):
self._redis: Any→object | None(运行时用isinstance检查);Callable[..., Coroutine[Any, Any, Any]]保留(Coroutine 类型参数合理);session_factory: Any→object | None - tools/computer_use_session.py(8 处):定义
SessionState = dict[str, str | int | bool | None]TypeAlias;截图数据用bytes而非Any - 每个模块顶部用
TYPE_CHECKING块定义 Protocol(如_RedisLike),描述期望接口 - 对无法静态推断的动态字段,用
dict[str, object]+ 显式访问器方法
Patterns to follow: U0 已修的 skill_routing.py 模式(Any → object + getattr)
Test scenarios:
- 类型检查:
ruff check通过,无: Any残留(除Coroutine[Any, Any, Any]) - bitable service 行为等价: 现有 bitable 测试全部通过
- pipeline_state Redis 降级: Redis 不可用 → 降级到 InMemory,行为不变
- computer_use_session: 现有测试通过,截图数据类型正确
Verification: 目标文件 Any 数量降至 ≤5(保留 Coroutine[Any, Any, Any]);ruff check 通过;现有测试通过。
U5. 前端 chat.ts 拆分 + vitest 补充
Goal: 将 2025 行 chat.ts 拆分为 chatSocket/chatStream/chatStore 三个模块,补充关键路径 vitest 测试。
Requirements: R5, R6
Dependencies: 无(前端独立,可与后端并行)
Files:
src/agentkit/server/frontend/src/stores/chat.ts— 瘦身为 chatStore.ts(会话/消息状态/computed)src/agentkit/server/frontend/src/stores/chatSocket.ts— 新建,WebSocket 连接/心跳/重连src/agentkit/server/frontend/src/stores/chatStream.ts— 新建,流式步骤聚合/事件分发src/agentkit/server/frontend/src/stores/__tests__/chatStream.test.ts— 新建,dispatchWsEvent 测试src/agentkit/server/frontend/src/stores/__tests__/chatSocket.test.ts— 新建,重连/心跳测试src/agentkit/server/frontend/src/stores/index.ts— 如有,更新 re-export
Approach:
- chatSocket.ts(~200 行):提取
connectWebSocket,disconnectWebSocket,_heartbeatTimer,_reconnectTimer,resolveIncomingConvId,_intentionalDisconnect;导出useChatSocket()composable - chatStream.ts(~300 行):提取
getConvSteps,appendStep,updateLastStep,clearConvSteps,handleWsMessage的事件分发逻辑(重命名为dispatchWsEvent);导出useChatStream()composable - chatStore.ts(≤500 行):保留
loadConversations,selectConversation,createConversation,deleteConversation,sendMessage,sendWsMessage, computed;组合useChatSocket和useChatStream handleWsMessage的 discriminated union 分发改为chatStream.ts中的dispatchWsEvent(event, streamState)纯函数,便于单元测试- vitest 测试覆盖:
dispatchWsEvent的 10+ 事件类型、resolveIncomingConvId启发式、心跳/重连时序
Patterns to follow: Vue 3 Composition API composable 模式;现有 useChatStore = defineStore 结构
Test scenarios:
- dispatchWsEvent token: token 事件 → streamingStepsByConv 更新
- dispatchWsEvent thinking: thinking 事件 → appendStep(type=thinking)
- dispatchWsEvent step: step 事件 → appendStep(type=tool_call)
- dispatchWsEvent final_answer: final_answer 事件 → 标记完成,清除 pending
- dispatchWsEvent team_formed: team_formed 事件 → planExecState 更新
- dispatchWsEvent expert_step: expert_step 事件 → appendStep(type=expert)
- dispatchWsEvent error: error 事件 → 错误状态设置
- resolveIncomingConvId: 多会话 pending → 返回最近使用的 convId
- 心跳: 30s 间隔 → 发送 ping
- 重连: 断连后 3s → 重连,
_intentionalDisconnect防级联
Verification: 三个文件每个 ≤500 行;vitest 测试 ≥10 个;npm run typecheck 通过;npm run build:frontend 成功。
Risks & Dependencies
Risk Analysis
| 风险 | 概率 | 影响 | 缓解 |
|---|---|---|---|
| U1 ReActEngine 重构引入流式路径回归 | 高 | 高 | Characterization-first:重构前补 golden trajectory 测试,锁定事件序列 |
| U2 TeamOrchestrator mixin 拆分后共享状态访问混乱 | 中 | 中 | TYPE_CHECKING Protocol 声明共享状态接口;mixin 文件顶部注明依赖 |
| U3 验收降级结构化改动破坏调用方 | 中 | 中 | ReviewResult dataclass 保持 passed 字段向后兼容;逐步迁移调用方 |
| U4 bitable formula 动态类型治理过度 | 中 | 低 | 保留 Coroutine[Any, Any, Any];动态字段用 dict[str, object] 而非强类型 |
| U5 前端拆分后 composable 间状态同步问题 | 中 | 中 | 保持 useChatStore 作为单一状态源,socket/stream 作为内部 composable |
| 跨 U 回归(U1+U2 同时改 core/experts) | 中 | 高 | U1 完成并验证后再启动 U2;U4/U5 可并行 |
Dependencies
- U1 → U2:U2 的 ReviewGateMixin 依赖 U1 的 ReActEngine 稳定(减少测试耦合)
- U2 → U3:U3 的验收降级整改在 U2 拆分后的
ReviewGateMixin中进行 - U4 独立:可与 U1-U3 并行
- U5 独立:前端独立,可与后端并行
- 测试基础:5989 单测 + 5 个 react 测试文件 + test_team_orchestrator.py 必须在重构前绿色
Acceptance Examples
- AE1:
execute()与execute_stream()对同一 mock 输入产生等价结果(ReActResult 字段一致),事件序列长度一致 - AE2:
TeamOrchestrator主类 ≤600 行,7 个 mixin 文件各自独立,test_team_orchestrator.py全部通过 - AE3: 验收 LLM 不可用时,
ReviewResult(passed=True, degraded=True)返回,review_resultWS 事件包含degraded: true字段 - AE4: in-scope 文件(bitable/ service.py + db.py + formula/functions.py + formula/parser.py、pipeline_state.py、tools/computer_use_session.py,共 40 处
Any)中Any数量降至 ≤5(保留Coroutine[Any, Any, Any]) - AE5: 前端 chat.ts 拆分为 3 个文件,每个 ≤500 行,vitest ≥10 个测试通过
Documentation Plan
- 更新
AGENTS.md:TeamOrchestrator 模块映射表补充 mixin 文件列表 - 更新
CONCEPTS.md:如需,补充ReviewResult、ReActEvent的'final_result'事件值术语 - 不新增独立文档(重构不改变外部 API)
Operational / Rollout Notes
- 每个 U 作为独立 PR,按依赖顺序合并(U1 → U2 → U3,U4/U5 可并行)
- 每个 PR 必须通过
pytest tests/unit/ -x -q+ruff check src/+ 前端npm run typecheck(如涉及) - U1 PR 需额外验证:流式路径 golden trajectory 快照比对
- 回滚策略:任意 PR 引入回归,revert 该 PR(重构不涉及数据迁移,回滚零成本)
Future Considerations
- U2 升级:mixin 拆分稳定后,可进一步迁移到组合模式(独立类 + 依赖注入),完全消除共享状态耦合
except Exception全量整治:U3 完成后,可排期server/routes/的 35 处整治Any全量治理:U4 完成后,可排期llm/、memory/、client/残留治理- 前端 vitest 覆盖率:U5 完成后,逐步提升到 60% 行覆盖
Sources & Research
- 综合评审报告(双 agent 评审,2026-06-30):架构与工程 3.63/5、产品与运维 4.0/5
- 代码取证:
core/react.py方法结构(Grep 32 方法)、experts/orchestrator.py(37 方法)、chat.ts(20+ 函数) - 项目规则:
.trae/rules/project_rules.md(async generator 安全)、AGENTS.md(禁止 any、禁止 except Exception 滥用)