Review Architecture
对 HolyEval 项目进行结构化架构审查,输出检查报告并标注违规项。
审查范围
根据 $ARGUMENTS 决定审查范围(默认 all):
| 参数 | 审查内容 |
|---|---|
gitops |
仅检查 GitOps 合规 |
plugin |
仅检查 Plugin 可插拔性 |
reuse |
仅检查 CLI/Web 复用 |
all |
全部检查 |
Check 1: GitOps 合规
原则: 所有代码、benchmark 数据、评测报告都在 Git 仓库中管理,便于版本追踪和协作维护。
检查项
benchmark 数据目录结构
benchmark/data/<name>/每个 benchmark 包含metadata.json+*.jsonl- 运行:
ls benchmark/data/*/,确认无游离文件
report 输出在仓库内
benchmark/report/目录存在且镜像data/子目录结构- 报告文件名遵循
{dataset}_{target_label}_{YYYYMMDD_HHmmss}.json格式 - 运行:
ls benchmark/report/*/检查
.gitignore 合理性
.env被忽略(含 API Key)__pycache__、.venv被忽略benchmark/report/不被忽略(报告需入库)- 运行:
cat .gitignore,检查以上规则
无硬编码路径或环境依赖
- 搜索
evaluator/和web/中是否有硬编码绝对路径 - 运行:
rg '/Users/|/home/|C:' evaluator/ web/ benchmark/ - 配置通过
.env+evaluator/utils/config.py读取,不散落在代码中
- 搜索
依赖管理
pyproject.toml存在且包含完整依赖声明uv.lock存在且已提交(锁定版本)- 运行:
git ls-files pyproject.toml uv.lock
输出模板
## GitOps 合规检查
- [x] benchmark 数据目录结构规范
- [x] report 输出在仓库内
- [ ] ⚠️ .gitignore 缺少 xxx 规则
- [x] 无硬编码路径
- [x] 依赖管理完整
Check 2: Plugin 可插拔性
原则: Plugin 通过 __init_subclass__ 注册,core/ 层仅依赖抽象接口,新增/删除 plugin 不影响框架核心。
检查项
core/ 不导入具体 plugin 类
- 在
evaluator/core/中搜索是否直接 import 了 plugin 实现类名 - 运行:
rg 'from evaluator\.plugin\.' evaluator/core/ - 允许:
import evaluator.plugin.xxx(触发注册的 side-effect import) - 禁止:
from evaluator.plugin.xxx import XxxAgent(直接引用具体类)
- 在
web/ 不直接导入 plugin 实现
- 运行:
rg 'from evaluator\.plugin\.\w+\.\w+ import' web/ - 允许:
import evaluator.plugin.xxx(注册触发) - 禁止: 直接导入具体实现类
- 运行:
Schema 集中定义
EvalInfo/TargetInfo在evaluator/core/schema.py里是Annotated[Any, BeforeValidator(...)],按注册表动态分发- 每个插件的
*Info配置类与实现同文件,用params_model=注册 - EvalAgent / TargetAgent 必须传
params_model=:rg 'Abstract(Eval|Target)Agent,' -A3 evaluator/plugin/ | rg -c params_model - TestAgent 不收
params_model(abstract_test_agent.py:43的__init_subclass__只接受name),它用类属性_config_model的字符串名。给 TestAgent 传params_model=会直接TypeError
Registry 反射使用
evaluator/utils/agent_inspector.py通过get_all()反射发现 plugin- 不硬编码 plugin 名称列表
- 运行:
rg 'get_all\(\)|get\(' evaluator/utils/agent_inspector.py
Plugin 间无交叉依赖
- 一个 plugin 不 import 另一个 plugin
- 运行:
rg 'from evaluator\.plugin\.' evaluator/plugin/ --glob '*.py' - 每个匹配应只在自己的
__init__.py中(注册用)
自动派生检查
bench_schema.py的_get_target_type_map()从AbstractTargetAgent._params_registry派生agent_inspector.py的 config map 同样从各插件的params_model派生- 不存在手动维护的 type→class 映射表
输出模板
## Plugin 可插拔性检查
- [x] core/ 不直接导入 plugin 实现
- [x] web/ 不直接导入 plugin 实现
- [x] Schema 集中定义在 schema.py
- [x] Registry 反射使用
- [ ] ⚠️ plugin A 导入了 plugin B: xxx
- [x] 自动派生无硬编码映射
Check 3: CLI/Web 复用
原则: CLI 和 Web 共享同一套底层能力(evaluator/utils/ + evaluator/core/),不重复实现。
检查项
共享层位置正确
- 以下功能在
evaluator/utils/或evaluator/core/中:
能力 期望位置 benchmark 读取 (list/load/detail/filter) evaluator/utils/benchmark_reader.pyreport 读写 evaluator/utils/report_reader.pyagent 元数据 evaluator/utils/agent_inspector.pytarget 解析 evaluator/core/bench_schema.py批量执行 evaluator/core/orchestrator.pyBenchItem→TestCase evaluator/core/bench_schema.py- 以下功能在
Web services 层是纯 re-export
web/app/services/benchmark_reader.py应为from evaluator.utils.benchmark_reader import *web/app/services/report_reader.py应为from evaluator.utils.report_reader import *web/app/services/agent_inspector.py应为from evaluator.utils.agent_inspector import *- 不应包含额外业务逻辑
- 运行:
wc -l web/app/services/benchmark_reader.py web/app/services/report_reader.py web/app/services/agent_inspector.py
无跨包逆向依赖
web/不导入benchmark/(benchmark 是 CLI runner,不是共享层)evaluator/不导入web/或benchmark/- 运行:
rg 'from benchmark\.' web/ rg 'from web\.' evaluator/ rg 'from benchmark\.' evaluator/
CLI 和 Web 调用同一入口
benchmark/basic_runner.py和web/app/services/task_manager.py都调用:bench_item_to_test_case()resolve_runtime_target()build_bench_report()BatchSession/do_batch_test()
- 不应各自实现解析/转换逻辑
输出模板
## CLI/Web 复用检查
- [x] 共享层位置正确
- [x] Web services 层纯 re-export
- [ ] ⚠️ web/ 导入了 benchmark/: xxx
- [x] CLI 和 Web 调用同一入口
依赖方向图(合规基准)
evaluator/core/ ← 核心接口 + schema(不依赖 plugin/utils 以外的任何包)
evaluator/utils/ ← 共享工具层(仅依赖 core/)
evaluator/plugin/ ← 可插拔实现(依赖 core/ + utils/)
benchmark/ ← CLI runner(依赖 core/ + utils/,不被 web/ 依赖)
web/ ← Web UI(依赖 core/ + utils/,不依赖 benchmark/)
generator/ ← 数据转换工具(独立,仅依赖 core/schema)
违反此图的导入方向即为架构问题。
执行流程
- 根据 $ARGUMENTS 确定审查范围
- 对每个 Check,逐项执行检查命令
- 收集结果,输出完整报告
- 对每个 ⚠️ 项给出修复建议(文件路径 + 具体改法)
- 如无违规,输出 "✅ 架构审查通过"