From 0d0f275134148f3d1628aa777bd5932f3a559d90 Mon Sep 17 00:00:00 2001 From: iomgaa Date: Sun, 12 Jul 2026 22:33:49 -0400 Subject: [PATCH] feat(core): add PoolConfig dataclass for pool strategy configuration --- core/types.py | 34 +++++++++++++++++++++++++ tests/unit/test_core_types.py | 47 ++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/core/types.py b/core/types.py index 54908b3..5bed83e 100644 --- a/core/types.py +++ b/core/types.py @@ -3,6 +3,7 @@ from __future__ import annotations from dataclasses import dataclass, field +from pathlib import Path as _Path @dataclass(frozen=True) @@ -55,3 +56,36 @@ class GeneratedQuestion: difficulty: str skill_target: str | None = field(default=None) difficulty_steps: int | None = field(default=None) + + +@dataclass(frozen=True) +class PoolConfig: + """池构建策略的统一配置。 + + 两组字段由两个具体策略各取所需,未使用的字段被忽略。 + + 属性: + task_types: 限定题型元组;None 表示全部类别。 + seed: 随机种子,保证可复现。 + baseline_run_id: 基线 run 标识。 + diag_size: 诊断池大小(GlobalStrategy 用)。 + diag_correct_ratio: 诊断池中对题占比(GlobalStrategy 用)。 + val_size: 验证池大小(GlobalStrategy 用)。 + val_correct_ratio: 验证池中对题占比(GlobalStrategy 用)。 + test_size: held-out 测试池大小(GlobalStrategy 用)。 + eval_min_per_class: 验证池中每类保底样本数(GlobalStrategy 用)。 + train_ratio: train/(train+val) 比例(PerCategoryStrategy 用)。 + test_questions_dir: 外部 test 题源路径(PerCategoryStrategy 用)。 + """ + + task_types: tuple[str, ...] | None + seed: int + baseline_run_id: str + diag_size: int + diag_correct_ratio: float + val_size: int + val_correct_ratio: float + test_size: int + eval_min_per_class: int + train_ratio: float + test_questions_dir: _Path | None diff --git a/tests/unit/test_core_types.py b/tests/unit/test_core_types.py index 0439f02..ee2aa3f 100644 --- a/tests/unit/test_core_types.py +++ b/tests/unit/test_core_types.py @@ -2,9 +2,11 @@ from __future__ import annotations +from pathlib import Path + import pytest -from core.types import GeneratedQuestion, LLMResponse +from core.types import GeneratedQuestion, LLMResponse, PoolConfig class TestLLMResponse: @@ -98,3 +100,46 @@ class TestGeneratedQuestion: def test_source_nodes_is_tuple(self, sample_question: GeneratedQuestion) -> None: assert isinstance(sample_question.source_nodes, tuple) + + +class TestPoolConfig: + """PoolConfig frozen dataclass 基本行为。""" + + def test_pool_config_frozen(self) -> None: + """PoolConfig 创建后不可变。""" + cfg = PoolConfig( + task_types=("Action Reasoning",), + seed=42, + baseline_run_id="baseline_v2", + diag_size=200, + diag_correct_ratio=0.5, + val_size=30, + val_correct_ratio=0.5, + test_size=60, + eval_min_per_class=2, + train_ratio=0.667, + test_questions_dir=Path("store/questions/benchmarks/Video-MME"), + ) + assert cfg.task_types == ("Action Reasoning",) + assert cfg.baseline_run_id == "baseline_v2" + assert cfg.train_ratio == 0.667 + with pytest.raises(AttributeError): + cfg.seed = 1 + + def test_pool_config_task_types_none(self) -> None: + """task_types=None 表示全部类别。""" + cfg = PoolConfig( + task_types=None, + seed=0, + baseline_run_id="run_1", + diag_size=200, + diag_correct_ratio=0.5, + val_size=30, + val_correct_ratio=0.5, + test_size=60, + eval_min_per_class=2, + train_ratio=0.667, + test_questions_dir=None, + ) + assert cfg.task_types is None + assert cfg.test_questions_dir is None