shinka-backup / docs /eval_service_redesign_summary.md
JustinTX's picture
Add files using upload-large-folder tool
1556404 verified

Eval Service 重新设计 - 核心要点

🎯 两个关键问题

1. 泛化性不足

原设计:

# 假设了 circle packing 特定格式
def load_program_output(results_dir):
    data = np.load("extra.npz")
    return data['centers'], data['radii']  # ← 只适用于 circle packing

新设计 ✅:

# 任务无关的通用接口
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 (任何任务必须遵循):

# 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. 一次性完成

# 新流程:一次 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 设计

提交评估 (异步)

# 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"
}

查询结果

# 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 (任务无关)

<TASK_CONTEXT>
Task: {{ task_name }}
Primary Metric: {{ primary_metric_name }}
</TASK_CONTEXT>

<PROGRAM_OUTPUT_FORMAT>
The program output structure:
{{ program_output_structure }}

Example:
{{ program_output_example }}
</PROGRAM_OUTPUT_FORMAT>

<REQUIRED_INTERFACE>
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
</REQUIRED_INTERFACE>

📋 实施路径

Phase 1: 向后兼容 (1周)

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 (几何)

    program_output = {"centers": ndarray, "radii": ndarray}
    
  2. TSP (组合)

    program_output = {"tour": [0,3,1,4,2], "distance": 142.5}
    
  3. Code Optimization (程序)

    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 (已过时)