为什么需要标准化评估框架

大语言模型能力飞速迭代,但"模型到底好不好"这个问题却越来越难回答。手工测试覆盖面有限, ad-hoc 脚本难以复现,不同模型之间的对比缺乏统一基准。OpenAI Evals 框架正是为解决这一痛点而生——它提供了一套标准化的评估流程,让模型评估变得可复现、可对比、可扩展。

Evals 框架核心架构

三层设计

┌─────────────────────────────────┐
│         Eval Runner             │  ← 评估运行器
├─────────────────────────────────┤
│    Template / Custom Eval       │  ← 评估模板/自定义逻辑
├─────────────────────────────────┤
│   Dataset (JSONL / JSON)        │  ← 评估数据集
└─────────────────────────────────┘
组件职责说明
Eval Runner执行评估驱动模型推理、收集输出、触发评估器
Template评估逻辑定义 Prompt 模板和评估方法
Dataset评估数据JSONL/JSON 格式的测试样本
Evaluator判定结果判断模型输出是否正确

评估模板类型

OpenAI Evals 内置了多种评估模板:

  • basic:单轮问答,对比模型输出与参考答案
  • matching:精确匹配评估
  • includes:包含匹配(输出包含期望字符串)
  • factuality:基于另一个 LLM 判断事实准确性
  • model-graded-closedbook:模型作为裁判,无参考资料
  • model-graded-closedbook-cf:模型裁判 + 反转选项防止位置偏见

快速开始

安装

pip install openai-evals
# 或从源码安装
git clone https://github.com/openai/evals.git
cd evals && pip install -e .

使用内置评估模板

# 使用 basic 模板评估
oaieval gpt-4o basic --max_samples 100

# 使用 model-graded 模板
oaieval gpt-4o model-graded-closedbook \
  --max_samples 50 \
  --eval.evaluator gpt-4o

数据集格式

评估数据集采用 JSONL 格式,每行一个样本:

{"input": [{"role": "user", "content": "法国的首都是哪里?"}], "ideal": "巴黎"}
{"input": [{"role": "user", "content": "水的化学式是什么?"}], "ideal": "H₂O"}
{"input": [{"role": "user", "content": "地球到太阳的平均距离是多少?"}], "ideal": "约1.5亿千米"}

对于多轮对话:

{"input": [{"role": "user", "content": "你好"}, {"role": "assistant", "content": "你好!"}, {"role": "user", "content": "1+1=?"}], "ideal": "2"}

自定义评估

创建自定义 Eval 类

from evals.elsuite.modelgraded.classify import ModelGradedSpec
from evals.record import record_match
import evals

class CodeQualityEval(evals.Eval):
    def __init__(self, model_specs, eval_name, seed, max_samples, **kwargs):
        super().__init__(model_specs, eval_name, seed, max_samples, **kwargs)
        self.mc_model_spec = model_specs["evaluator"]

    def eval_sample(self, test_sample, rng):
        prompt = f"""
        评估以下代码的质量(1-5分):
        
        代码:{test_sample['code']}
        评分标准:{test_sample['criteria']}
        
        只返回一个数字(1-5)。
        """
        
        result = self.mc_model_spec.completion_fn(prompt=prompt)
        score = int(result.get_completions()[0].strip())
        expected = test_sample['expected_score']
        
        record_match(
            correct=score == expected,
            expected=expected,
            picked=score,
        )

    def run(self, recorder):
        samples = self.get_dataset()
        self.eval_all_samples(recorder, samples)
        return {"accuracy": self.get_accuracy()}

注册评估

eval-registry/evals/ 下创建 YAML 文件:

# eval-registry/evals/code-quality.yaml
code-quality:
  id: code-quality.v0
  metrics: [accuracy]
  description: "评估代码质量评分能力"
  eval_class: evals.elsuite.code_quality.CodeQualityEval
  modelgraded_spec: ModelGradedSpec
  args:
    max_samples: 200

运行自定义评估

oaieval gpt-4o code-quality --max_samples 200

模型裁判(Model-Graded Evaluation)

模型裁判是 Evals 的核心能力之一——用一个 LLM 来评判另一个 LLM 的输出质量。

防偏见设计

# model-graded-closedbook-cf 模板会自动生成两个版本:
# 版本A:(A) 正确答案 (B) 错误答案
# 版本B:(A) 错误答案 (B) 正确答案
# 通过比较两个版本的判断来消除位置偏见

裁判 Prompt 示例:

你是一个评估专家。请比较以下两个回答的质量。

问题:{question}
回答A:{answer_a}
回答B:{answer_b}

请选择更好的回答,只输出 "A" 或 "B"。

多裁判投票

# 使用多个模型作为裁判,取多数票
oaieval gpt-4o my-eval \
  --eval.evaluator gpt-4o \
  --eval.jury_size 3 \
  --eval.jury_model gpt-4o,claude-3-opus,gemini-pro

结果分析

输出结构

评估完成后,结果保存在 tmp/eval_results/ 下:

tmp/eval_results/
├── gpt-4o_code-quality_20260624_160000.jsonl  # 原始记录
└── gpt-4o_code-quality_20260624_160000_summary.json  # 汇总

汇总报告:

{
  "eval_id": "gpt-4o_code-quality_20260624",
  "accuracy": 0.82,
  "total_samples": 200,
  "correct": 164,
  "incorrect": 36,
  "duration_seconds": 342
}

分析脚本

import json
import pandas as pd

records = []
with open("tmp/eval_results/gpt-4o_code-quality_20260624_160000.jsonl") as f:
    for line in f:
        records.append(json.loads(line))

df = pd.DataFrame(records)

# 按类别分析准确率
print(df.groupby("category")["correct"].mean())

# 查看错误案例
errors = df[~df["correct"]]
print(errors[["input", "expected", "picked"]].head(20))

OpenAI Evals vs lm-eval-harness

维度OpenAI Evalslm-eval-harness (EleutherAI)
维护方OpenAIEleutherAI
内置基准较少,侧重模板化200+ 标准基准(MMLU、HellaSwag 等)
自定义评估强(类继承 + 模板)中等(Task 类)
模型裁判原生支持需额外配置
多模型支持OpenAI 优先广泛支持各类开源/闭源模型
社区生态中等庞大
适合场景自定义评估、模型裁判标准基准跑分

选型建议

  • 需要跑 MMLU/GSM8K 等标准基准 → lm-eval-harness
  • 需要自定义业务评估、模型裁判 → OpenAI Evals
  • 两者可结合使用:lm-eval-harness 跑标准分,Evals 做定制评估

最佳实践

1. 数据集分层

// easy.jsonl - 基础能力
{"input": [{"role":"user","content":"1+1=?"}], "ideal":"2", "level":"easy"}

// hard.jsonl - 进阶能力  
{"input": [{"role":"user","content":"证明根号2是无理数"}], "ideal":"...", "level":"hard"}

2. 避免数据污染

# 使用 --seed 控制随机性
oaieval gpt-4o my-eval --seed 42

# 在评估集中排除训练数据
--exclude train_data.jsonl

3. 持续评估

# CI/CD 集成
- name: Run Evals
  run: |
    oaieval $MODEL_NAME my-eval --max_samples 100
    python scripts/check_eval_threshold.py --min-accuracy 0.85

总结

OpenAI Evals 框架为 LLM 评估提供了标准化、可复现的基础设施。它的核心价值在于模板化设计降低了评估门槛,模型裁判机制让主观质量评估变得可行。虽然在标准基准覆盖面上不及 lm-eval-harness,但在自定义评估和业务场景适配方面更加灵活。对于认真对待模型评估的团队,Evals 是值得投入的框架。

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。