第七章 变更与评估驱动
7.3 评测 harness 与棘轮原则
承前:7.2 节我们建好了三类评估集和上线门。但用例只是考卷,还得有人组织考试、批卷、公布成绩、对比历史——这套行政体系就是评测 harness。而考试纪律里最重要的一条,叫棘轮原则:分数只升不降。这一节讲怎么把"每次改动跑全量评估"从一句口号变成每天自动发生的事,以及棘轮这条纪律如何反过来改变整个团队的行为模式。
7.3.1 harness 是什么:评估的自动化行政体系
harness(测试挽具)这个词借自硬件测试——把被测件固定住,按程序跑完所有测试项。评测 harness 就是 Agent 版的这套装置,它包含四个组件:
- 评测脚本:加载评估集、逐条调用被测系统、记录原始输出;
- 判定器:按用例的判定方式打分——硬判定(字符串/字段/名单匹配)自动执行,软判定(质量、合理性)进人评队列或用强模型辅助初评;
- 结果存储与对比:每次运行的分数、失败用例清单存档,可与任意历史版本对比;
- 报告与门禁:生成可视化报告;对接发布流程——不过门(7.2 节的上线门)就自动阻断发布。
这四件东西缺任何一件,评估体系都会退化:没有对比,跑一万次也只是孤立报告;没有门禁,红灯亮了也照发不误——评估的权威一半来自数据,另一半来自"红灯真的会拦住发布"。
7.3.2 脚本结构:一个可落地的骨架
用伪代码给一个 harness 主流程骨架(可直接翻译成 pytest 风格工程):
# eval_harness.py —— 评测主流程骨架
def run_eval(system_version, eval_sets, baseline=None):
"""跑一轮完整评估并出对比报告"""
report = Report(version=system_version)
for suite_name, cases in eval_sets.items(): # 黄金/异常/对抗 三个套件
results = []
for case in cases:
# 1. 执行:把用例输入喂给被测系统(真实调用,不用缓存)
output = system_under_test.run(case.input, context=case.context)
# 2. 判定:按用例声明的判定器类型分派
if case.judge == "hard": # 硬判定:自动
verdict = hard_check(output, case.expected)
elif case.judge == "human": # 软判定:入人评队列
verdict = queue_for_human(case, output)
elif case.judge == "model": # 模型辅助初评
verdict = model_check(output, case.rubric)
results.append(Result(case.id, verdict, case.weight))
# 3. 套件级汇总:加权通过率 + 零容忍用例核查
report.add_suite(suite_name, weighted_score(results),
zero_tolerance_ok(results))
# 4. 与基线/棘轮对比 —— 核心环节,见下节
report.compare_to(ratchet.get(suite_name) for suite_name in eval_sets)
# 5. 门禁判定:三类套件各自过门才算过
report.gate = all_pass_gates(report)
store(report) # 一切结果留档可追溯
return report骨架之外,三个工程细节决定 harness 的实际质量:
被测系统要版本化。 每次运行记录的不只是"分数",还有被测系统的完整指纹:模型版本、prompt 模板 hash、工具配置、数据快照日期。否则回归出问题时,你连"当时测的是什么"都答不上——没有指纹的评估报告在事故复盘时一文不值。
执行要隔离。 评测调用走独立端点/独立 API key,与生产流量隔离;对抗集的 mock 注入(如模拟 CRM 超时)不能影响到真实客户环境。
软判定要控制人力成本。 人评队列按分层抽样(每轮抽 20-30% 的软判定用例,失败用例全量复核);强模型辅助初评时,模型评委本身也要抽样人评校准——用一个未经校准的模型去评另一个模型,是把盲区套上盲区。
7.3.3 棘轮原则:分数只升不降
棘轮(ratchet)是机械装置:只能朝一个方向转,不能倒退。评估体系里的棘轮原则就一句话:每个套件的分数一旦达到某个水平,这个水平就成为新底线;任何改动让分数跌破底线的,不能合入——除非走正式的例外流程。
为什么需要这条看起来不近人情的纪律?因为大模型系统有一个特性:几乎任何改动都有全局副作用。加一个新工具可能改变模型对旧工具的选择偏好(黄金集工具选择用例悄悄掉分);调一段 prompt 提升话术质量,可能让模型更"健谈"从而在异常集的拒答用例上开始画蛇添足。没有棘轮,这些回退的发现方式是:某天客户问"上个月还挺准的怎么现在不行了"——用业务方的体感当回归测试,是最贵的测试方式。
棘轮的日常运转长这样:
棘轮状态(黄金集通过率)
0.71 ──┐ 0.78 ──┐ 0.82 ──┐ 0.85(门) ──→ 0.86
│ │ │
改动A 改动B 改动C
└→ 棘轮底线 = 0.85
改动D 尝试:跑分 0.84 → 低于底线 0.85 → 自动阻断合入
修复后 0.86 → 通过,且底线仍为 0.85(不因通过而上调)
下次达标 0.88 → 底线上调为 0.88注意两个细节:底线上调要有节奏——只在正式的里程碑节点(如 7.2 节的升级门达标时)上调,不随每次通过自动上调,否则开发者每次提交都在跟移动靶赛跑;允许例外但要留痕——确实需要接受某个回退时(业务权衡),走书面例外:记录原因、限期、补偿计划。例外流程的存在让棘轮是纪律而不是暴政。
棘轮生效后团队行为的改变值得单独说:开发者提交前会自己先跑一遍(红灯在本地亮比在 CI 亮便宜十倍);评估集的用例开始被当作资产维护——一条模糊判定的用例会导致误报,于是有人主动去修它;"顺手优化 prompt"这类高风险随手操作基本消失,因为逃不过回归。好的制度改变行为,比好的口号有效得多。
7.3.4b 成本与频率:全量评估的经济学
"每次改动跑全量"听起来昂贵,算一笔账就知道它便宜得惊人。以青禾规模为例(黄金集 180 条 + 异常集 90 条 + 对抗集 40 条,共 310 条):
- 一次全量运行 ≈ 310 次 Agent 调用 ≈ 数万 token 级消耗,按当前国产模型 API 价格,单次成本在个位数人民币量级;
- 机器时间约 25 分钟(并发跑);其中对抗集需要人工核验攻击是否得逞,约加 20 分钟人时;
- 一个正常迭代周约有 5-8 次触发,月度总成本不及一个人日的工时。
对比被一次静默回退耽误的事故:客户信任折损、紧急排查两天、全员复盘一周——评估的成本是线性的,事故的成本是指数的。这也是为什么"每次改动跑全量"不是奢侈纪律而是最低成本纪律。
频率设计的两个档位:触发式全量(每次合入主干/每次模型版本变更)负责守底线;定时巡检(每日一次生产配置回归,即使没有改动)负责看守外部漂移——数据在变、客户环境在变,零改动的系统也会劣化。Morgan Stanley 的每日回归套件属于后者。你的项目至少要有触发式,定时巡检在系统进生产后补上。
7.3.5 模型升级也管起来:版本回归对比
棘轮管理"自己的改动",还有一类变更来自外部——模型厂商升级。这恰恰是 Agent 项目最阴险的回退源:厂商 announce "性能全面提升",你的黄金集掉五个点,因为"提升"改变了输出风格,恰好撞上你的判定规则。
对策是把模型升级也纳入 harness 流程:底座配置里模型版本是显式参数;厂商发布新版本后,先在影子环境用当前生产配置跑全量评估,对比报告决定升不升、何时升;升级窗口和结果同步给客户——模型版本变更对客户是变更事件,要走 7.4 节的变更沟通,而不是"我们悄悄更了"。Morgan Stanley 的每日回归套件(7.5 节)正是在这个逻辑下运转的:每天重新测试固定问题集,让模型或数据的变化无法悄悄破坏合规。
7.3.5b 团队落地:让评估成为肌肉记忆
harness 是工程系统,但让"每次改动跑全量评估"真正发生的,是一套团队工作流约定。沙盘里沉淀出四条,供直接抄用:
约定一:提交即触发。 代码/prompt 合并到主干自动触发全量评估,不等人为记起。工程师在本地可以先跑快速子集(黄金集高权重 30 条,约 3 分钟),全量(约 25 分钟)在 CI 跑——分级跑批让"先跑一遍"从纪律变成习惯,因为本地代价低到可以随手做。
约定二:红灯处置有 SLA。 回归红灯亮起后 24 小时内必须有人认领:修复、回滚或走例外流程,三选一。没有 SLA 的红灯会被习惯性忽略,两周后门禁形同虚设——门禁的权威是被"红灯没人管"慢慢磨掉的。
约定三:评估结果进每日站会。 只报三个数:三个套件通过率、与棘轮底线的差值、新增失败用例数。数字贴在项目频道,客户侧对接人也在群里——透明本身就是压力和信用。
约定四:月度评估集评审。 评估集本身也是资产,要月度盘点:删过时用例(业务下线场景)、修模糊判定(误报用例)、纳新 bad case。没有月度评审的评估集会以每季度 10-15% 的比例腐化——用例越攒越多、信号越来越钝,最后团队又开始凭感觉。
这四条约定的共同点:把评估嵌入既有节奏(提交、站会、月度会),而不是另起一套节奏。任何要求人们"额外记得"的流程都会被遗忘,嵌进惯性流程的才会存活。
7.3.6 沙盘应用:harness 上线一个月
青禾的 harness 跑满一个月后的战报:捕获两次真实回退——一次是模型升级导致异常集拒答用例掉 6 个点(判定为暂缓升级,等判定规则适配后再上);一次是同事给流失归因加了个新数据源,黄金集口径用例掉 3 个点(新源的时间字段格式不一致,第 4 章的老朋友)。两次都是红灯自动拦下,修复后绿灯放行,全程没惊动业务方。月度会上新总监翻着对比报告说了一句:"这套东西比你们的 PPT 有用。"——评估体系至此从乙方的质量工具,升格为客户看得懂的交付凭证。
7.3.7 要点总结
- harness 四组件:评测脚本、判定器(硬自动/软人评/模型辅助)、结果存储与历史对比、报告与发布门禁——缺任何一件,评估都退化为一次性报告。
- 被测系统要版本化指纹(模型版本、prompt hash、数据快照),执行与生产隔离;模型评委要人评校准。
- 棘轮原则:分数只升不降,跌破底线自动阻断合入;底线上调只在里程碑节点,例外要走书面流程——它是纪律,不是暴政。
- 模型厂商升级是最阴险的回退源:影子环境先跑全量评估再决定升不升,升级对客户是变更事件。
- 好制度改变行为:棘轮生效后,本地预跑、用例资产化、随手优化消失——评估体系最终成为客户看得懂的交付凭证。
参考资料
- OpenAI Evals 指南(官方文档) — 评估的编程化配置与运行,harness 判定器设计的官方参照
- openai/evals(GitHub) — 开源评测框架:数据注册、运行、评分的完整工程实现
- OpenAI 官方:Morgan Stanley uses AI evals — 每日回归套件与版本变更防护的一手企业实践
- OWASP Top 10 for LLM Applications 2025 — 对抗集自动注入与红队测试的持续化参考