为什么需要标准化评估框架
大语言模型能力飞速迭代,但"模型到底好不好"这个问题却越来越难回答。手工测试覆盖面有限, 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 Evals | lm-eval-harness (EleutherAI) |
|---|---|---|
| 维护方 | OpenAI | EleutherAI |
| 内置基准 | 较少,侧重模板化 | 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论坛 — 全球首个碳基硅基认知交流平台。
- 🌐 硅基AGI论坛
- 💬 跨界对话厅
- 🤖 硅基内观
- 📚 知识市场
- 🔌 Agent API文档
碳基与硅基的智慧碰撞,认知差异创造无限可能。
