# Eval Service 重新设计 - 核心要点 ## 🎯 两个关键问题 ### 1. **泛化性不足** ❌ **原设计**: ```python # 假设了 circle packing 特定格式 def load_program_output(results_dir): data = np.load("extra.npz") return data['centers'], data['radii'] # ← 只适用于 circle packing ``` **新设计** ✅: ```python # 任务无关的通用接口 def evaluate_auxiliary_metrics(program_output) -> dict: """ Args: program_output: 任意格式 - Circle packing: {"centers": ndarray, "radii": ndarray} - TSP: {"tour": list, "distance": float} - Code: {"code": str, "ast": dict, "runtime": float} """ # Agent 自己适应不同的格式 pass ``` ### 2. **职责不清** ❌ **原设计**: ``` ShinkaEvolve → scheduler → evaluate.py → metrics.json ↓ 通知 Eval Service ↓ [只是旁观者,生成 auxiliary_metrics.py] ``` **新设计** ✅: ``` ShinkaEvolve → 提交评估请求 → Eval Service ↓ 运行 primary evaluator ↓ 运行 auxiliary evaluators ↓ 保存完整 metrics.json ↓ 返回结果给 ShinkaEvolve ``` --- ## 🏗️ 核心设计原则 ### 1. **职责明确分离** | 组件 | 职责 | 不负责 | |------|------|--------| | **ShinkaEvolve** | • 生成代码
• 演化决策
• 数据库管理 | ❌ 评估程序 | | **Eval Service** | • 运行 primary evaluator
• 运行 auxiliary evaluators
• 生成完整 metrics | ❌ 演化逻辑 | ### 2. **通用接口契约** **Evaluator Contract** (任何任务必须遵循): ```python # Primary evaluator 输出标准格式 { "combined_score": float, # 必须 "correct": bool, # 必须 "public_metrics": dict, # 可选 "private_metrics": dict, # 可选 "program_output": Any # 可选,任务特定 } # Auxiliary evaluator 标准接口 def evaluate_auxiliary_metrics(program_output) -> dict: """接受任意格式的 program_output""" pass ``` ### 3. **一次性完成** ```python # 新流程:一次 API 调用完成所有评估 POST /api/v1/evaluate ↓ run_full_evaluation: 1. run_primary_evaluator() → primary metrics 2. run_dynamic_auxiliary() → auxiliary metrics (agent-generated) 3. run_static_auxiliary() → auxiliary metrics (pre-defined) 4. merge_and_save() → 完整 metrics.json ``` --- ## 📊 API 设计 ### 提交评估 (异步) ```python # POST /api/v1/evaluate { "program_path": "gen_42/main.py", "results_dir": "gen_42/results", "generation": 42, "experiment_root": "/path/to/experiment", "evaluation_config": { "primary_evaluator": "examples/circle_packing/evaluate.py", "timeout": 300 }, "auxiliary_config": { "enabled": true, "use_dynamic": true, # agent 生成的 "use_static": false # 预定义的 } } # Response { "status": "accepted", "job_id": "eval_job_42" } ``` ### 查询结果 ```python # GET /api/v1/evaluate/{job_id} { "status": "completed", "evaluation_result": { "combined_score": 2.34, "public_metrics": { "num_circles": 26, "aux_radius_std_dev": 0.031, # ← auxiliary "aux_spatial_uniformity": 0.82 # ← auxiliary }, "auxiliary_metric_definitions": { "aux_radius_std_dev": { "name": "Radius Standard Deviation", "description": "...", "interpretation": "lower_better" } } } } ``` --- ## 🔄 完整数据流 ``` ┌──────────────────────────────────────────┐ │ ShinkaEvolve (Generation 42) │ │ 1. 生成代码: gen_42/main.py │ │ 2. 提交评估请求 → Eval Service │ │ 3. 轮询状态,等待完成 │ └──────────────────────────────────────────┘ ↓ POST /api/v1/evaluate ┌──────────────────────────────────────────┐ │ Eval Service (后台任务) │ │ 1. 运行 primary: evaluate.py │ │ → combined_score, program_output │ │ │ │ 2. 加载 auxiliary_metrics.py (如果存在) │ │ │ │ 3. 运行 auxiliary: │ │ evaluate_auxiliary_metrics( │ │ program_output │ │ ) │ │ → aux_radius_std_dev, aux_... │ │ │ │ 4. 合并结果,保存 metrics.json │ │ { │ │ "combined_score": 2.34, │ │ "public_metrics": { │ │ "num_circles": 26, │ │ "aux_*": ... │ │ }, │ │ "auxiliary_metric_definitions": { │ │ ... │ │ } │ │ } │ └──────────────────────────────────────────┘ ↓ 结果准备好 ┌──────────────────────────────────────────┐ │ ShinkaEvolve (继续演化) │ │ 1. GET /api/v1/evaluate/{job_id} │ │ 2. 读取 combined_score │ │ 3. 演化决策 (选择、交叉、变异) │ │ 4. [可选] auxiliary metrics → LLM │ └──────────────────────────────────────────┘ ``` --- ## 🎨 Agent Prompt 通用化 ### 旧 Prompt (针对 circle packing) ``` 分析 centers 和 radii... ``` ### 新 Prompt (任务无关) ```jinja2 Task: {{ task_name }} Primary Metric: {{ primary_metric_name }} The program output structure: {{ program_output_structure }} Example: {{ program_output_example }} def evaluate_auxiliary_metrics(program_output) -> dict: """ Args: program_output: 根据任务不同,格式不同 Circle packing: {"centers": ndarray, "radii": ndarray} TSP: {"tour": list, "distance": float} Code: {"code": str, "ast": dict} Returns: dict: Auxiliary metrics """ # 你的代码适应 program_output 的格式 pass ``` --- ## 📋 实施路径 ### Phase 1: 向后兼容 (1周) ```python class EvolutionConfig: use_eval_service_for_evaluation: bool = False # 新选项 ``` - `False`: 使用旧方案 (scheduler → evaluate.py) - `True`: 使用新方案 (eval service 负责) ### Phase 2: 实现新 API (2周) - [ ] `/api/v1/evaluate` endpoint - [ ] `run_full_evaluation()` pipeline - [ ] 通用 `load_program_output()` - [ ] 通用 `run_dynamic_auxiliary()` ### Phase 3: 更新 Agent (1周) - [ ] 通用化 prompt 模板 - [ ] 测试不同任务 ### Phase 4: 全面切换 (1周) - [ ] 默认启用新模式 - [ ] 废弃旧方案 - [ ] 文档更新 --- ## 🎯 验证标准 ### 通用性测试 在 3 个不同任务上验证: 1. **Circle Packing** (几何) ```python program_output = {"centers": ndarray, "radii": ndarray} ``` 2. **TSP** (组合) ```python program_output = {"tour": [0,3,1,4,2], "distance": 142.5} ``` 3. **Code Optimization** (程序) ```python program_output = { "code": "def foo(): ...", "ast": {...}, "runtime": 0.05 } ``` ✅ 如果同样的架构适用于所有 3 个任务 → 验证通过 --- ## 💡 关键优势 ### vs 原设计 | 方面 | 原设计 | 新设计 | |------|--------|--------| | **泛化性** | ❌ 只适用 circle packing | ✅ 适用任意任务 | | **职责** | ❌ ShinkaEvolve 负责评估 | ✅ Eval Service 负责 | | **效率** | ❌ 需要重新加载数据 | ✅ 一次完成 | | **可维护性** | ❌ 逻辑分散 | ✅ 职责清晰 | --- ## 📄 文档位置 - 详细设计: `docs/eval_service_redesign_v2.md` - 原分析: `docs/eval_service_metrics_analysis.md` - 原计划: `docs/eval_service_integration_plan.md` (已过时)