OpenAI 评分器
评分器(grader)将模型输出与参考答案比较,以评估表现。评分器 API可用于测试评分器、比较结果,改进评测框架。
随着相关评测与微调工作流退出,OpenAI 也在弃用这些评分器。当前过渡时间见弃用说明。
概览
评分器返回评分,常用范围为0至1;相比只给0或1,对部分正确的答案给予部分分数有时更有用。评分器以 JSON 定义,类型包括字符串检查、文本相似度、模型数值评分及Python代码执行。
本文介绍各类评分器与入门示例;开始评测请参阅 Evals 指南。
模板
部分评分器的输入支持模板,让同一配置适用于多个样例。字符串中的{{ }}会替换为变量值。格式必须是{{ namespace.variable }},命名空间只支持item与sample;嵌套变量可用类似 JSON Path 的语法访问。
item 命名空间
评测时来自输入数据源。例如:
来源示例 1(json):
{
"reference_answer": "..."
}
评分器可用{{ item.reference_answer }}引用。
sample 命名空间
来自评测采样阶段的模型输出,包含:
output_text:字符串形式的输出。output_json:JSON对象形式的输出,仅样本包含response_format时填充。output_tools:模型的tool_calls,结构与 Chat Completions API输出工具调用一致。choices:结构与 Chat Completions 输出选项一致。output_audio:包含Base64编码data和transcript的音频对象。
例如,{{ sample.output_text }}引用输出文本。
字符串检查评分器
基本字符串操作返回0或1,适合城市名、是/否、是否包含或以正确内容开头等明确判断。
来源示例 2(json):
格式说明:本块保留来源的模式或片段写法,不是可直接解析的完整严格JSON;代码内容保持原样。
{
"type": "string_check",
"name": string,
"operation": "eq" | "ne" | "like" | "ilike",
"input": string,
"reference": string,
}
支持的操作:eq为区分大小写的相等;ne为区分大小写的不等;like为区分大小写的包含;ilike为不区分大小写的包含。满足条件返回1,否则返回0。
原指南正文将不等操作拼为neq,与其示例和评分器接口参考不一致;这里按接口定义使用ne。
文本相似度评分器
用于按不同评估方法衡量模型输出与参考的接近程度,适合开放式回答,例如把模型段落与专家参考答案作数值比较。
来源示例 3(json):
格式说明:本块保留来源的模式或片段写法,不是可直接解析的完整严格JSON;代码内容保持原样。
{
"type": "text_similarity",
"name": string,
"input": string,
"reference": string,
"pass_threshold": number,
"evaluation_metric": "fuzzy_match" | "bleu" | "gleu" | "meteor" | "cosine" | "rouge_1" | "rouge_2" | "rouge_3" | "rouge_4" | "rouge_5" | "rouge_l"
}
支持方法:
fuzzy_match:使用rapidfuzz模糊匹配。bleu:BLEU。gleu:Google BLEU。meteor:METEOR。cosine:使用text-embedding-3-large嵌入计算余弦相似度,仅用于评测。rouge-*:ROUGE。
模型评分器
使用模型评分器,就是提示另一个模型,为待评估模型的输出评分。
模型数值评分器
按提示词在指定范围内返回数值。
来源示例 4(json):
格式说明:本块保留来源的模式或片段写法,不是可直接解析的完整严格JSON;代码内容保持原样。
{
"type": "score_model",
"name": string,
"input": Message[],
"model": string,
"pass_threshold": number,
"range": number[],
"sampling_params": {
"seed": number,
"top_p": number,
"temperature": number,
"max_completions_tokens": number,
"reasoning_effort": "minimal" | "low" | "medium" | "high"
}
}
每条消息的格式:
来源示例 5(json):
格式说明:本块保留来源的模式或片段写法,不是可直接解析的完整严格JSON;代码内容保持原样。
{
"role": "system" | "developer" | "user" | "assistant",
"content": str
}
输入为包含role与content的聊天消息列表。输出会限制在给定range内,非数值输出默认记0分。消息可用相同模板语法引用标准答案和模型样本。
来源完整调用示例:
来源示例 6(python):
## [中文] 调用评分器测试接口:完全相同得1分,意思相近得0.5,否则0;密钥来自环境变量。
import os
import requests
## get the API key from environment
api_key = os.environ["OPENAI_API_KEY"]
headers = {"Authorization": f"Bearer {api_key}"}
## Define a score-model grader.
grader = {
"type": "score_model",
"name": "my_score_model",
"input": [
{
"role": "system",
"content": "You are an expert grader. If the reference and model answer are exact matches, output a score of 1. If they are somewhat similar in meaning, output a score in 0.5. Otherwise, give a score of 0.",
},
{
"role": "user",
"content": "Reference: {{ item.reference_answer }}. Model answer: {{ sample.output_text }}",
},
],
"pass_threshold": 0.5,
"model": "gpt-4.1-2025-04-14",
"range": [0, 1],
"sampling_params": {
"max_completions_tokens": 32768,
"top_p": 1,
},
}
## validate the grader
payload = {"grader": grader}
response = requests.post(
"https://api.openai.com/v1/fine_tuning/alpha/graders/validate",
json=payload,
headers=headers,
)
print("validate response:", response.text)
## run the grader with a test reference and sample
payload = {"grader": grader, "item": {"reference_answer": 1.0}, "model_sample": "0.9"}
response = requests.post(
"https://api.openai.com/v1/fine_tuning/alpha/graders/run",
json=payload,
headers=headers,
)
print("run response:", response.text)
来源示例 7(ruby):
## [中文] Ruby调用模型评分器测试接口,比较候选回答与参考;需要实际凭证,代码未在本轮执行。
require "openai"
client = OpenAI::Client.new
grader = {
"type" => "score_model",
"name" => "my_score_model",
"input" => [
{
"role" => "system",
"content" => "You are an expert grader. If the reference and model answer are exact matches, output a score of 1. If they are somewhat similar in meaning, output a score in 0.5. Otherwise, give a score of 0."
}, {
"role" => "user",
"content" => "Reference: {{ item.reference_answer }}. Model answer: {{ sample.output_text }}"
}
],
"pass_threshold" => 0.5,
"model" => "gpt-4.1-2025-04-14",
"range" => [0, 1],
"sampling_params" => {
"max_completions_tokens" => 32768,
"top_p" => 1
}
}
item = { reference_answer: 1.0 }
model_sample = "0.9"
puts(client.fine_tuning.alpha.graders.validate(grader: grader).to_json)
puts(client.fine_tuning.alpha.graders.run(grader: grader, item: item, model_sample: model_sample).to_json)
模型数值评分器的输出
score_model使用指定提示词和采样参数请求模型,并要求特定响应格式:
来源示例 8(json):
格式说明:本块保留来源的模式或片段写法,不是可直接解析的完整严格JSON;代码内容保持原样。
{
"result": float,
"steps": ReasoningStep[],
}
其中每个推理步骤的结构:
来源示例 9(json):
格式说明:本块保留来源的模式或片段写法,不是可直接解析的完整严格JSON;代码内容保持原样。
{
description: string,
conclusion: string
}
格式既要求数值result(奖励值),也为解释评分保留空间。编写评分提示词时可明确引用字段,例如要求在推理结论分析化学键类型,或在不满足条件X时令result为−1.0。
模型评分器约束
来源列出的model取值为:gpt-4o-2024-08-06、gpt-4o-mini-2024-07-18、gpt-4.1-2025-04-14、gpt-4.1-mini-2025-04-14、gpt-4.1-nano-2025-04-14、o1-2024-12-17、o3-mini-2025-01-31、o3-2025-04-16和o4-mini-2025-04-16。此为来源支持列表,仍受模型生命周期及平台退出限制。
推理模型不支持更改temperature;非推理模型不支持reasoning_effort。
如何编写评分提示词
这是迭代过程。建议为模型评分器本身建立评测,准备:
- 极详细的任务提示词,包含分步要求与多个具体上下文示例。
- 模型及可信领域专家给出的多种高质量回答。
- 对这些回答的标准评分,例如理想专家答案应得1分。
这样可自动检验评分器能否区分质量差异。发现边界案例后,将其加入评分器评测,并修改提示词。
例如,已知专家偏好的答案:
来源示例 10():
answer_1 > answer_2 > answer_3
再检查评分器判断是否一致:
来源示例 11():
model_grader(answer_1, reference_answer) > model_grader(answer_2, reference_answer) > model_grader(answer_3, reference_answer)
Python 评分器
允许执行自定义 Python 评分。代码必须有恰好两个参数的grade函数,并返回浮点数。异常、无效浮点值等均视为无效结果,记0分。
来源示例 12(json):
{
"type": "python",
"source": "def grade(sample, item):\n return 1.0",
"image_tag": "2025-05-08"
}
来源示例 13(python):
## [中文] grade必须恰有两个参数并返回浮点数;当前恒返回1.0只是占位逻辑,不能作为有效质量评分。
from typing import Any
def grade(sample: dict[str, Any], item: dict[str, Any]) -> float:
# your logic here
return 1.0
第一个参数是模型输出字典;只有输出使用response_format时,output_json才填充。
来源示例 14(json):
格式说明:本块保留来源的模式或片段写法,不是可直接解析的完整严格JSON;代码内容保持原样。
{
"choices": [...],
"output_text": "...",
"output_json": {},
"output_tools": [...],
"output_audio": {}
}
第二个参数是评分上下文字典;评测时包含来自数据源的键。
来源示例 15(json):
格式说明:本块保留来源的模式或片段写法,不是可直接解析的完整严格JSON;代码内容保持原样。
{
"reference_answer": "...",
"my_key": {...}
}
以下为来源调用示例。Ruby示例要求把前述grade函数及导入保存为运行目录下的grader.py。示意函数只返回1.0,需替换为真正评分逻辑。
来源示例 16(python):
## [中文] 将Python评分源码作为字符串提交,使用RapidFuzz归一化相似度,除以100得到0到1。
import os
import requests
## get the API key from environment
api_key = os.environ["OPENAI_API_KEY"]
headers = {"Authorization": f"Bearer {api_key}"}
grading_function = """
from rapidfuzz import fuzz, utils
def grade(sample, item) -> float:
output_text = sample["output_text"]
reference_answer = item["reference_answer"]
return fuzz.WRatio(output_text, reference_answer, processor=utils.default_process) / 100.0
"""
## Define a Python grader.
grader = {"type": "python", "source": grading_function}
## validate the grader
payload = {"grader": grader}
response = requests.post(
"https://api.openai.com/v1/fine_tuning/alpha/graders/validate",
json=payload,
headers=headers,
)
print("validate request_id:", response.headers["x-request-id"])
print("validate response:", response.text)
## run the grader with a test reference and sample
payload = {
"grader": grader,
"item": {"reference_answer": "fuzzy wuzzy had no hair"},
"model_sample": "fuzzy wuzzy was a bear",
}
response = requests.post(
"https://api.openai.com/v1/fine_tuning/alpha/graders/run",
json=payload,
headers=headers,
)
print("run request_id:", response.headers["x-request-id"])
print("run response:", response.text)
来源示例 17(ruby):
## [中文] Ruby读取当前目录grader.py并提交Python评分配置;须先保存函数和依赖导入。
require "openai"
client = OpenAI::Client.new
## Save your Python grading function as grader.py before running this example.
grading_function = File.read("grader.py")
grader = {
type: :python,
source: grading_function
}
item = { reference_answer: "fuzzy wuzzy had no hair" }
model_sample = "fuzzy wuzzy was a bear"
puts(client.fine_tuning.alpha.graders.validate(grader: grader).to_json)
puts(client.fine_tuning.alpha.graders.run(grader: grader, item: item, model_sample: model_sample).to_json)
不想手动将函数写成字符串时,可用importlib和inspect从Python文件加载。例如grader.py:
来源示例 18(python):
## [中文] 加载grader模块并取得整个文件源码,组成type=python的评分器配置。
import importlib
import inspect
grader_module = importlib.import_module("grader")
grader = {"type": "python", "source": inspect.getsource(grader_module)}
这会自动使用整个文件源码,适合较长评分器。
技术约束
- 上传代码小于
256kB,执行环境无网络。 - 单次评分最多2分钟。
- 内存2Gb、磁盘1Gb。
- 最多2个CPU核,超出会被限流。
镜像标签2025-05-08提供以下第三方包,版本列表保留原样:
来源示例 19():
numpy==2.2.4
scipy==1.15.2
sympy==1.13.3
pandas==2.2.3
rapidfuzz==3.10.1
scikit-learn==1.6.1
rouge-score==0.1.2
deepdiff==8.4.2
jsonschema==4.23.0
pydantic==2.10.6
pyyaml==6.0.2
nltk==3.9.1
sqlparse==0.5.3
rdkit==2024.9.6
scikit-bio==0.6.3
ast-grep-py==0.36.2
另有以下 NLTK 语料:
来源示例 20():
punkt
stopwords
wordnet
omw-1.4
names
限制与建议
评分器设计需要从小规模开始试验,持续改进。
设计建议
- 避免标签严重失衡;平衡数据或提高罕见样例权重,防止猜多数类。
- 代码难以判断丰富、开放的答案时,用LLM裁判;用多个候选答案和标准答案校准稳定性与偏好一致性,并在提示词中提供优秀、一般、较差的少样本示例。

TRAE-AI编程


更多建议: