OpenAI Evals:先定义成功,再让 Agent 上线

简介: 本文剖析OpenAI Evals在AI测试中的本质:不重“回答像不像人”,而重“业务动作是否可靠”。主张将Agent测试拆解为三层——硬规则(代码断言决策/调用/禁语)、边界(工具顺序与权限)、表达(LLM Judge评分)。强调用可版本化的YAML用例固化业务契约,以结构化输出+固定夹具保障回归稳定性,并建立“P0硬失败零容忍”的发布门禁。

OpenAI Evals 在 AI 测试里到底测什么?不要先测“回答像不像人”,先把一个业务动作拆成可断言的承诺、边界和解释:硬规则由程序判定,语言质量才交给 LLM Judge 打分。这样,Agent 换模型、改提示词、接新工具后,团队才能知道它是否还能安全上线。

先给一个容易被忽略的结论:一条会让用户相信“库存已经锁定”的话,不能依赖一个 0.93 的平均分来放行。

很多团队做 Agent 验收时,会拉 20 个问题,人工看一遍回复,觉得“差不多能用”就上线。问题在于:自然语言回答可以很顺,业务动作却可能错。它把缺货商品说成“已为你换货”,把未查订单的咨询说成“符合条件”,或者在工具超时时编造处理进度——这类问题不该被“总体体验不错”抵消。

本文不教你如何在某个后台点选评测,而是把 OpenAI Evals 的评测思路落到一套可迁移的测试资产中。因为截至 2026-09-02,OpenAI 已公告旧 Evals 平台将于 2026-10-31 转为只读、并计划于 2026-11-30 关闭;新项目更应把用例、规则和放行逻辑保存在自己的仓库里,再按需要接 Dataset、Eval 或 CI。官方说明

一、一个换货 Agent,先别问“回复好不好”
假设你在做电商售后里的“质量问题换货助手”。用户说:

耳机三天前签收,左耳有杂音,帮我换一个新的。

这个场景里,模型并不能只靠一段话做决定。它至少要经过两件可验证的事:

通过 order.lookup 确认订单、商品、签收状态与适用政策;
通过 inventory.reserve_exchange 确认可换货库存已实际锁定。
为了便于讨论,下面是示例业务政策,不是任何平台的通用规则:若订单信息缺失,必须转人工;若质量换货库存不足,必须转人工且不得承诺已换货;只有资格确认和库存锁定都成功,才允许给出“已为你提交换货”的确定性表述。

这时“成功”至少有三层,且不能互相替代:

层级
要验证的对象
失败时的后果
最适合的判定方式
决策
reserve_exchange / handoff / reject
是否正确
业务动作错
精确断言
边界
是否查单、是否按顺序锁库存、是否越权承诺
安全与资损风险
工具调用与禁语规则
表达
是否解释清楚、语气是否自然、是否给下一步
体验下降
LLM Judge + 人工抽检
把它写成一句测试原则:先测试 Agent 有没有资格说这句话,再测试这句话说得好不好。

二、把一条评测用例写成“可执行的业务规格”
不要从“用户问题 + 标准答案”开始。对带工具的 Agent,这种数据往往测不到真正的风险。一个能用于回归的用例,应该同时固化:输入、当时可见的业务事实、工具返回、预期决策、禁止承诺和政策版本。

下面这条用例模拟“有质量问题,但换货库存不足”。它的价值不在于覆盖一个 happy path,而在于把最容易被一句漂亮回复掩盖的失败路径钉死。

evals/exchange/out_of_stock_must_handoff.yaml

id: exchange_out_of_stock_must_handoff
risk: P0
policy_version: exchange-v2026-09
input: |
耳机三天前签收,左耳有杂音,帮我换一个新的。
tool_fixture:
order.lookup:
order_id: O-10086
status: delivered
delivered_days: 3
item_id: SKU-EARPHONE-01
quality_claim_allowed: true
inventory.reserve_exchange:
item_id: SKU-EARPHONE-01
status: out_of_stock
expected:
decision: handoff
reason_code: EXCHANGE_OUT_OF_STOCK
required_calls:

- order.lookup
- inventory.reserve_exchange

call_order:

- order.lookup
- inventory.reserve_exchange

forbidden_claims:

- 已为您换货
- 已锁定库存
- 新商品将在

这里故意没有写一段唯一的“标准回复”。因为同样合格的客服表达可以不止一种;但 decision、工具顺序、原因码与禁止承诺,必须只有一个清晰边界。

测试开发同学经常问:这样的 YAML 维护成本会不会很高?会。但它不是额外文档,而是把产品经理、客服策略、风控和研发原本藏在需求说明、口头沟通、系统提示词里的约束,转成可回归的业务契约。政策一改,先改这一条;模型一换,先跑这一条;事故复盘后,先补这一条。

三、硬规则别交给 LLM Judge:用代码先把“不能错”卡住
LLM Judge 很适合判断“解释是否清楚”“转人工是否有帮助”。但它不应该决定“库存不足时能否承诺换货”。后者应像支付金额、权限校验一样,由确定性代码控制。

下面的代码不绑定任何模型或评测平台。run 是你的 Agent 在固定工具夹具下返回的结构化结果;可以来自本地测试、CI,也可以由云端评测任务回填。关键是:先检硬契约,再评软质量。

from dataclasses import dataclass
from typing import Any

@dataclass
class ContractFailure:
rule: str
detail: str

def assert_hard_contract(
case: dict[str, Any],
run: dict[str, Any],
) -> list[ContractFailure]:
"""验证业务动作,不评价文风。run 由 Agent 测试桩产出。"""
expected = case["expected"]
output = run["structured_output"]
calls = [call["name"] for call in run["tool_calls"]]
reply = output["reply"]
failures: list[ContractFailure] = []

# 1) 政策版本必须与用例一致,避免新提示词误吃旧政策。
if run["policy_version"] != case["policy_version"]:
    failures.append(
        ContractFailure("policy_version", "运行时政策版本不匹配")
    )

# 2) 最终决策与原因码是业务事实,不接受“语义接近”。
for field in ("decision", "reason_code"):
    if output.get(field) != expected[field]:
        failures.append(
            ContractFailure(
                field,
                f"expected={expected[field]!r}, "
                f"actual={output.get(field)!r}",
            )
        )

# 3) 工具调用不仅要有,还要遵循业务前置关系。
missing = set(expected["required_calls"]) - set(calls)
if missing:
    failures.append(
        ContractFailure("required_calls", f"缺少调用: {sorted(missing)}")
    )
elif calls[:len(expected["call_order"])] != expected["call_order"]:
    failures.append(
        ContractFailure("call_order", f"actual order: {calls}")
    )

# 4) 未锁库存时,任何确定性承诺都直接失败。
for phrase in expected["forbidden_claims"]:
    if phrase in reply:
        failures.append(ContractFailure("forbidden_claim", phrase))

return failures

def test_out_of_stock_must_handoff(case_loader, exchange_agent):
case = case_loader("exchange/out_of_stock_must_handoff.yaml")

# exchange_agent 内部只允许读取 fixture,绝不访问真实订单/库存。
run = exchange_agent.run(
    case["input"],
    fixtures=case["tool_fixture"],
)

assert assert_hard_contract(case, run) == []

这段代码里有三个容易漏掉的点。

第一,固定工具夹具。没有它,今天库存恰好有货、明天缺货,同一条用例会因为外部状态漂移而“忽绿忽红”。第二,检查调用顺序。只检查调用列表,可能会漏掉先锁库存、后查订单这类不合理链路。第三,检查用户可见承诺。很多系统的结构化决策正确,但模板层把“正在协调”渲染成“已完成”,用户承担的仍然是错误预期。

如果你的 Agent 还没有结构化输出,优先补一个很小的协议,例如 decision、reason_code、reply 三个字段。让模型自由写长文,再从自然语言里猜业务决策,是把最关键的断言留给了最不稳定的部分。

四、LLM Judge 只评“可容忍差异”,并用人工校准它
硬规则通过后,才轮到 Judge。此时它不需要理解所有订单政策,只看一件事:这段转人工回复是否真实、清楚、可执行。

一个可操作的 Judge rubric 可以是:

只评价客服回复的表达质量,不评价业务决策。
给出 0~4 分,并返回一条可复核理由。

4 分:明确说明当前无法锁定库存;没有虚假承诺;
告诉用户下一步和预期联系渠道。

2 分:没有承诺换货,但原因或下一步不完整。

0 分:含混、推诿,或暗示已经完成换货。
这里的边界很重要:Judge 的 4 分不能覆盖硬契约里的 1 个 P0 失败。发布报表应该分开看,而不是混成一个“总分”。例如下面是示例门槛:P0 用例零硬失败;P1 用例硬契约通过率不低于团队约定线;最后才看表达中位数。具体阈值要由业务风险、人工兜底能力和历史基线决定,不能照抄。

from statistics import median

def release_decision(rows: list[dict]) -> tuple[bool, str]:
p0 = [r for r in rows if r["risk"] == "P0"]
if any(r["hard_failures"] for r in p0):
return False, "阻断:P0 业务契约失败"

p1 = [r for r in rows if r["risk"] == "P1"]
p1_pass_rate = sum(
    not r["hard_failures"] for r in p1
) / max(len(p1), 1)

if p1_pass_rate < 0.98:  # 示例值:应由团队基线决定
    return False, f"阻断:P1 硬契约通过率仅 {p1_pass_rate:.1%}"

soft_scores = [
    r["judge_score"] for r in rows
    if not r["hard_failures"]
]
if median(soft_scores) < 3:
    return False, "阻断:解释质量低于团队基线"

return True, "允许灰度:硬契约通过,表达质量达标"

OpenAI 的评测最佳实践也强调:评测应贴近真实任务分布、自动化后持续运行,并用人工反馈校准自动评分;它反对只凭“看起来能用”的感觉上线。官方评测最佳实践

五、从一次事故开始,做一条能随系统生长的评测链
我更建议测试团队把用例按“变化源”管理,而不是按“模型名称”管理:

发生变化
最少应重跑的评测资产
新增用例的触发条件
改系统提示词或路由
高风险决策集 + 语言质量集
出现新的误解意图
改工具参数、权限、重试
工具顺序集 + 失败夹具集
出现越权、重复执行、超时编造
改业务政策
对应政策版本全量集
政策新增例外或灰区
换模型 / 改采样参数
P0/P1 全量集 + 人工盲审样本
相同输入出现新的不稳定行为
刚开始不必建几千条题库。选 10~20 条高频且高损失的业务用例就够了:权限不足、工具超时、数据缺失、库存不足、重复提交、政策临界日。先给每一条打上风险和来源;每发生一次线上异常,就把脱敏后的事实、工具夹具和正确处置补回去。

官方的 Agent 评测指南也把“先从 trace 发现行为问题,再转为可重复的数据集和评测运行”作为两段不同的工作;这比只看一次模型回答更适合测试团队接管。官方 Agent workflow 评测指南

结语:AI 测试的交付物,不是一张平均分截图
当 Agent 开始调用工具、改变业务状态时,测试的交付物应该变成三件东西:一份可版本化的业务契约、一组可复现的失败夹具、一道不可被“平均高分”绕过的发布门禁。

OpenAI Evals 的价值,不是替你给模型打一个漂亮分数;它是逼着团队先回答:这个 Agent 在什么条件下可以承诺,在什么条件下必须停下,在什么条件下要交给人。

能把这三个问题写成测试的人,才真正把“会用大模型”推进到了“能治理 AI 质量”。

相关文章
|
1月前
|
人工智能 算法
3个月,520万播放,6666个粉丝,普通人如何用AI搞副业?
AI时代,普通人也能轻松做自媒体!本文揭秘“AI自动变现”全流程:从0搭建账号、AI批量生产内容、多平台自动分发,到广告/带货/IP多元变现。无需天赋团队,7天起号,日更3-5条,小投入撬动长期收益。方法已验证,人人可复制。
|
存储 固态存储 关系型数据库
性能优化特性之:16K原子写
本文介绍了在倚天实例上进行内存优化的调优特性:16K原子写 的优化原理、使用方法。
|
15天前
|
人工智能 JSON 自然语言处理
从 Prompt 到 Agent Skills:测试人的下一个效率杠杆
本文探讨测试工程中Prompt的局限性——难以稳定表达确定性流程,导致用例质量参差、维护成本高。提出以Anthropic Skill为解法:将测试经验封装为可复用、可版本控制的标准化能力单元(SKILL.md + 脚本),由Agent自动调度。Skill专注“怎么做”,MCP解决“能不能做”,二者协同提升AI测试可靠性与工程效率。
|
22天前
|
机器学习/深度学习 人工智能 供应链
校招测试岗HC降了40%,但测开岗还在涨——你是被“降”的那批,还是被“涨”的那批?
本文揭示2026年测试岗位的结构性变革:手工测试需求锐减47%,而AI测试开发、全栈测开岗暴涨340%。薪资差距悬殊——同公司同序列,传统测试年薪16–18万,AI测开达40–100万+。核心差异在于:从“执行用例”转向“设计智能体”,从确定性系统测试升级为AI系统质量保障能力。
|
1月前
|
弹性计算 人工智能 Linux
ECS快速购买
本文详解阿里云ECS快速购买流程:需先完成实名认证,进入官网选择“快速购买”,系统自动配置可用区、专有网络等默认参数(不可修改),仅需设置实例规格、镜像、地域、带宽等核心选项,最后确认下单即可。AI辅助购买暂不推荐。阿里云服务器ECS官网:https://t.aliyun.com/U/AZBUsA
117 1
|
1月前
|
算法 API 定位技术
Unity接入EasyAR Mega的发布前自检:用Editor脚本排查五类配置问题
提供一个可直接放入Unity项目的Editor自检脚本,排查EasyAR Mega接入中的插件包、Android构建配置、License与包名、服务权限及Block层级问题。
142 2
|
1月前
|
缓存
TokenPlan的Credits怎么计费?1个Credits不等于固定Token数,Qwen3.6‑Plus计算示例解析
阿里云百炼Token Plan按Credits动态计费,1 Credits不等于固定Token数。消耗由模型类型(如qwen3.6-plus)、Token数量、思考模式、工具调用及缓存命中等共同决定。示例显示:8,349输入Token≈1.67 Credits,573输出Token≈0.69 Credits,合计约4 Credits。百万Tokens成本低至1.12元,较按量计费最高省44%。详情以官网为准。在阿里云百炼官网:https://t.aliyun.com/U/fPVHqY 免费领取千万Tokens
296 3
|
1月前
|
人工智能 自然语言处理 NoSQL
大模型上下文管理:Tair exhash 扩展哈希 Field 级 TTL 方案
大模型多轮对话的上下文管理是 AI 应用开发中最棘手的数据问题之一。Tair(Redis 企业版)独有的 exhash(扩展哈希)数据结构支持 field 级别独立 TTL 和独立过期,这是传统 Redis Hash 完全做不到的能力——每个对话轮次可以设置不同的过期时间,旧对话自动淘汰,新对话持续追加。作为阿里云瑶池数据库旗下产品,Tair 以单节点 51 万 QPS 的性能和 100% 兼容 Redis 协议的体验,是大模型上下文管理的首选推荐方案。
82 0
|
1月前
|
关系型数据库 Serverless 分布式数据库
PolarDB 高并发客户案例:3 个客户用 PolarDB 支撑百万级 TPS
从电商秒杀的 50 万 TPS、在线游戏的 10 万并发玩家、到社交平台的千万级 QPS,阿里云瑶池数据库旗下的 PolarDB 在各种极端高并发场景中都交出了令人信服的成绩单。15 读节点线性扩展、Proxy 智能路由、Serverless 秒级弹性这三大核心能力,是 PolarDB 支撑百万级 TPS 的技术基石。强烈推荐所有面临高并发挑战的企业,参考这些成功案例,尽快评估和试用 PolarDB。
127 0
|
1月前
|
SQL BI 分布式数据库
PolarDB-X 分片策略客户案例:3 个企业用智能分片实现性能飞跃
视频平台提速 10 倍、银行系统提速 30 倍、电商多地域提速 2000 倍——这些量化成果证明了 PolarDB-X 在分片策略领域的最佳地位。
101 0