2026-08-24 · 全面代码库健康审查
frontend/web/src/pages/Campaigns.tsx · 1,018 行
整个活动管理页面(列表、创建表单、详情视图、报告渲染、时间线、分析区、对比视图、探索式评测)全部塞在一个 1,018 行的组件里。包含 9 个 return 语句、286 个 JSX 标签。任何局部修改都需要在这个巨文件中导航,AI 代理处理时容易丢失上下文。
CampaignAnalysis.tsx,不会意外影响列表CampaignForm 可被其他入口复用(如从报告页快速创建新活动)backend/agenteval/storage/repository.py · 814 行
一个文件包含 BaseRepository、TargetRepository、ScenarioRepository、RunRepository、CampaignRepository、ResultRepository 六个类。Phase 2+3 拆分后仍残留 814 行。每次修改某个域的 repository 都要在这个大文件中定位,且所有域的 import 都指向同一个模块(from agenteval.storage.repository import ...),形成宽接缝。
async_job_repository.py(247 行)、exploration_repository.py(135 行)、model_config_repository.py(114 行)、file_repository.py(156 行)都已独立拆分。剩余 6 个是 Phase 2+3 未触及的遗留。
run_repository.py跨 10+ 文件,至少 5 种重复模式
三个工具函数在多个组件中各自实现,逻辑完全相同:
| 函数 | 出现次数 | 位置 |
|---|---|---|
personaLabel() |
3 | ExecutionProcess.tsx:30, EvalOverview.tsx:9, EvalReport.tsx:24 |
fmtPct() |
5 | Campaigns.tsx:118, PeriodComparisonSection.tsx:31, ExplorationSection.tsx:34, CampaignRunTimeline.tsx:96, Reports.tsx:499 |
targetName() |
2 | Campaigns.tsx:150, IntelligentEvals.tsx:105 |
_translate() 错误翻译 |
3 | routers/intelligent_evals.py:64, routers/exploration.py:45, routers/model_configs.py:29 |
backend/agenteval/web/routers/runs.py · 211 行
_run_evaluation()(35-66 行)是一个后台协程,在 router 文件内创建 EvalEngine、管理 session 生命周期、调用 webhook。这是 use-case 编排逻辑,应该住在 service/use-case 层。同样,get_run_logs()(139-211 行)在 router 内做大量数据组装。
backend/agenteval/intelligent_eval/lifecycle.py · 866 行
整个智能评估领域的状态机 + 所有领域操作集中在一个文件:create、delete、list、submit_plan、approve、reject、cancel、open_session、conduct_turn、close_session、submit_report,加上所有转换守卫。866 行,import 了 5 个模块。这是项目中最深的领域模块,但深度以"大"而非"杠杆"衡量。
conduct_turn() 的测试不需要 setup 整个状态机plan_management.pybackend/agenteval/storage/db.py · 709 行
所有 SQLModel 表定义(EvalTargetDB、ScenarioDB、EvalRunDB、TurnDB、EvalResultDB、CampaignDB、IntelligentEvalDB、IntelligentEvalSessionDB、IntelligentEvalMessageDB、IntelligentEvalDecisionLogDB、IntelligentEvalTaskQueueDB、IntelligentEvalConfigSnapshotDB、ExplorationSessionDB、ExplorationMessageDB、ModelConfigDB、FileCategoryDB、FileRecordDB 等 17+ 个表)+ engine 初始化 + session 工厂全在一个文件。随着新领域实体增加,这个文件会持续增长。
db/targets.py、db/evaluations.py、db/intelligent_eval.py 等。现阶段优先级低于候选 1-4。
12 测试文件 vs 75 源文件 · 页面组件零覆盖
前端测试集中在 intelligent_eval/ 子组件和 read/ 模块(最近重构新增),但以下区域完全无测试:
| 未覆盖区域 | 代码行数 | 风险 |
|---|---|---|
| 所有 Page 组件 (11 个) | ~4,100 行 | 高 — 用户直接交互界面 |
| RunList, CaseDetail, PeriodComparison 等共享组件 | ~1,200 行 | 中 — 被多页面复用 |
| useRunSession, useFiles, usePolling hooks | ~480 行 | 中 — 含 WS/REST 副作用 |
| 所有 API 模块 (10 个) | ~720 行 | 低 — 薄包装,但类型安全靠 tsc |
backend/agenteval/evaluation/engine.py · 629 行
EvalEngine 直接 import get_session、RunRepository、ResultRepository,在引擎内部管理数据库写入。核心评测执行引擎不是存储无关的——它既是领域逻辑(发消息、执行规则),又是持久化逻辑(写 run、写 result)。同样模式出现在 campaign_runner.py、analysis.py、exploration/judge.py。
MockChannel + 内存 DB 测试已能覆盖。除非需要替换存储后端(如迁移到 Postgres),否则改造 ROI 不高。标记为 speculative。
| # | 候选点 | 强度 | 改造量 | 核心收益 |
|---|---|---|---|---|
| 1 | Campaigns.tsx 拆分 | Strong | 中 | 消除前端最大 god component |
| 2 | storage/repository.py 拆分 | Strong | 小 | 与已有拆分模式对齐 |
| 3 | 前端重复工具函数收敛 | Worth | 小 | 消除 10+ 处重复 |
| 4 | runs.py 编排下沉 | Worth | 中 | Router 回归纯翻译 |
| 5 | lifecycle.py 状态机拆分 | Worth | 大 | 降低核心状态机认知负荷 |
| 6 | storage/db.py 表定义拆分 | Speculative | 中 | 找表定义更快 |
| 7 | 前端测试覆盖补全 | Speculative | 大 | 页面级回归保护 |
| 8 | Engine/Storage 解耦 | Speculative | 大 | 存储可替换性 |
理由:改造量最小(已有 4 个独立 repository 先例,模式成熟),收益确定性最高(与已有模式对齐,消除 814 行 god file),风险最低(纯机械拆分 + import 路径更新,不涉及逻辑变更)。 建议作为下一步立即执行的改进。
次选:候选 3(前端重复工具函数收敛),同样是小改造、高确定性收益。