# 评测核心 (/zh/docs/maintainers/architecture/evaluation-core)



## 简介 [#简介]

本文说明 evaluation 包如何串联——不是文件索引，而是职责顺序。端到端 run 故事先看 [Workflow](/zh/docs/maintainers/architecture/workflow)；需要判断改动归属哪一层、哪些面必须跨版本保持稳定时再读本文。

包内数据流是单向的：**公开契约**定义 JSON-safe 形状，**执行 runner** 产生副作用与 artifact，**catalog loader** 把 YAML 转为契约，**reporting** 把 metrics 变成 scorecard。API 模块应保持 import-light；重型 runtime 不应反向泄漏进 `evaluation/api/`。

模块级查找见 [代码库地图](/zh/docs/maintainers/architecture/file-index)。

## 端到端流程 [#端到端流程]

无论是否加载模型，每次 evaluation run 都经过相同的高层阶段：

```python
# evaluation/tasks/execution/evaluate.py
result = run_evaluate(request)

# _mode() 选择 delegate runner：
if mode == "existing-results":
    runner = ExistingResultsRunner(...)
elif mode == "model" and uses_metric_objects:
    runner = ContractRunner(...)            # model + Metric objects
elif mode == "model" and uses_benchmark:
    runner = ModelBenchmarkRunner(...)      # model + benchmark
else:
    runner = ExistingResultsRunner(...)     # model + metric ids

# 各路径最终都汇聚到 metrics + reporting：
runner.generate(...)          # 仅 ContractRunner / ModelBenchmarkRunner
metrics = runner.compute_metrics(...)
report = runner.write_scorecard_and_report(metrics)
```

`evaluate.py` 中的 facade 保持薄：校验输入、选择 delegate、转换结果。所有文件写入、sample ledger 与 manifest 更新都在 delegate runner 内完成。

## 公开契约 [#公开契约]

`evaluation/api/` 模块定义 runner、CLI、tests、docs 导出与 validation 共用的形状。此处改动应视为 semver 敏感：下游假设 `to_dict()` / `from_dict()` 可往返且磁盘 field 名稳定。

样本级，&#x2A;*`GenerationRequest`*&#x2A; 携带 ids、task name、inputs、controls 与 expected output schema；对应的 &#x2A;*`GenerationResult`*&#x2A; 携带 artifacts、status、errors、timings 与 metadata。模型级，&#x2A;*`WorldModelRunner`** 是每个 backend 必须实现的最小接口：`from_config()`、`generate()`、`cleanup()&#x60;。Benchmark 级，&#x2A;*`BenchmarkSpec`*&#x2A; 聚合 tasks、metrics、splits、tags 与 dataset metadata。Metrics 通过 &#x2A;*`Metric`** 接口实现 `compute_sample()` 与 `aggregate()`。

这些类型刻意不包含 checkpoint 路径、subprocess 细节或 vendor-specific import。Runner 在 run time 把 catalog YAML 翻译成这些契约。

## 执行路径 [#执行路径]

三条 delegate runner 覆盖常见执行形态。匹配任务选路径——不要在 facade 里堆条件分支，新增 delegate 即可。

**ContractRunner**（`contract.py`）是 model 执行加 `Metric` 对象的 in-process 参考路径。它归一化 requests、写 execution plan、运行 generation（可选 SQLite cache 复用）、计算 per-sample metrics、聚合后产出 scorecard 与 report artifact。需要最严格 artifact 布局且 metric 对象同进程时使用。

**ExistingResultsRunner**（`existing_results.py`）评分磁盘上已有 artifact。从 path 或 inline list 加载 results、对齐 requests、运行 built-in metric id 或 artifact check，写出与完整 model run 相同的 summary 与 scorecard bundle。用于 hosted API 批处理、离线 demo，或 generation 发生在 WorldFoundry 外部的 workflow。

**ModelBenchmark runner**（`model_benchmark.py`）把 generation 与 benchmark-zoo runner 串联。解析 benchmark manifest、从 task registry 物化 requests、运行模型、为 external evaluator 物化生成 artifact，再把归一化 metrics 交给 reporting。用于端到端 model-plus-benchmark run。

Model mode 收到 string metric id 而非 `Metric` 对象时，即使 generation 已在进程内完成，scoring 也会走与 `ExistingResultsRunner` 相同的路径。见 [Workflow — Model Mode 细节](/zh/docs/maintainers/architecture/workflow#model-mode-细节)。

## 可复现 Planning [#可复现-planning]

Generation 开始前，task-driven run 通过 `plan.py&#x60; 中的 &#x2A;*`RunPlan`** 固定 sample id、split 与 input keys。Plan 连接 task registry、可选 dataset manifest 与 evaluate facade：registry lookup → 物化 requests → `EvaluateRunRequest`。Plan 上的 fingerprint 使 rerun 与 cache 复用跨机器可预期。

`materialize.py` 中的 materialization 把 dataset 行或 task sample 转为 `GenerationRequest` 行。耗 GPU 前用 `worldfoundry-eval task materialize` 证明此步——多数「本地可用、CI 失败」来自 sample id 不一致，而非 model loading。

## 模型解析 [#模型解析]

磁盘 YAML 经唯一 front door `resolver.py` 中的 `resolve_model_zoo_runner()` 变为可运行 model。CLI 的 `--model-id`、Python caller 与 Studio 预览都应在解释 checkpoint 路径前汇聚于此。

```python
# worldfoundry/data/models/catalog/*.yaml
entry = parse_model_zoo_yaml(path)          # schema.py → ModelZooEntry
entry = ModelZooRegistry().resolve(alias)   # alias lookup
manifest = WorldModelManifest.from_entry(entry)
runner = resolve_model_zoo_runner(manifest) # resolver.py
# → WorldModelRunner instance
```

Built-in runner 经 `builtins.py` 与 `registry.py` 注册；custom target 从 catalog `runner_target` 字符串解析。`manifest.py` 与 `schema.py` 中的 catalog metadata 是 provenance 与 readiness——不能替代可运行 runner。

## Benchmark 集成 [#benchmark-集成]

Benchmark metadata 走平行的 catalog 路径。Task YAML 描述 per-sample protocol；benchmark-zoo YAML 描述 integration status、external runner 与 metric id。

```python
# Benchmark-zoo YAML + task YAML registry
entry = parse_benchmark_zoo_yaml(path)      # → BenchmarkZooEntry
entry = BenchmarkZooRegistry().resolve(id)
spec = BenchmarkSpec.from_catalog(entry, task_registry)
raw = ManifestBenchmarkRunner(spec).run()   # external evaluator
metrics = official_normalizers.normalize(raw)
# → metrics/summary.json + scorecard.json
```

External benchmark 留在 runner 边界之后：vendor evaluator 产出 raw output，normalizer 转为稳定 metrics，共享 reporting 层写 `metrics/summary.json` 与 `scorecard.json`。

## Reporting 链路 [#reporting-链路]

Reporting 在 metrics 完成后运行。Scorecard 是机器可读的 eligibility 记录；Markdown report 由 scorecard 派生，非权威来源。

```python
per_sample = read_jsonl("metrics/per_sample.jsonl")
summary = aggregate_metrics(per_sample)     # → metrics/summary.json
scorecard = build_scorecard(summary)        # → scorecard.json
write_report_md(scorecard)                  # → report.md（派生，非权威来源）
```

Validation 脚本与 docs generator 会 import `reporting/validation.py`，并期望 scorecard field 稳定。在此重命名 field 会破坏 release gate。

## 改动规则 [#改动规则]

改 evaluation 内部代码前先看此表。它列出其他团队与自动化依赖的兼容面；破坏它们需同步更新 validation、docs export 与示例 scorecard。

| 如果改这里                                   | 必须保持                                                          |
| --------------------------------------- | ------------------------------------------------------------- |
| `api/*` dataclasses                     | `to_dict()` / `from_dict()` JSON-safe payloads。               |
| `evaluation/tasks/run_*` output writing | 文件名、JSONL row shape、`sample_id` 对齐、final manifest status。     |
| `models/resolver.py`                    | Error messages、runner resolution、model-zoo variant selection。 |
| `evaluation/tasks/official/*` schema    | Manifest parsing 和 alias lookup behavior。                     |
| `reporting*.py` and `scorecard.py`      | Validation、docs 和 release reports 使用的 scorecard fields。       |
