Skip to content

第七章 变更与评估驱动 ​

7.3 评测 harness 与棘轮原则 ​

承前:7.2 节我们建好了三类评估集和上线门。但用例只是考卷,还得有人组织考试、批卷、公布成绩、对比历史——这套行政体系就是评测 harness。而考试纪律里最重要的一条,叫棘轮原则:分数只升不降。这一节讲怎么把"每次改动跑全量评估"从一句口号变成每天自动发生的事,以及棘轮这条纪律如何反过来改变整个团队的行为模式。


7.3.1 harness 是什么:评估的自动化行政体系 ​

harness(测试挽具)这个词借自硬件测试——把被测件固定住,按程序跑完所有测试项。评测 harness 就是 Agent 版的这套装置,它包含四个组件:

  1. 评测脚本:加载评估集、逐条调用被测系统、记录原始输出;
  2. 判定器:按用例的判定方式打分——硬判定(字符串/字段/名单匹配)自动执行,软判定(质量、合理性)进人评队列或用强模型辅助初评;
  3. 结果存储与对比:每次运行的分数、失败用例清单存档,可与任意历史版本对比;
  4. 报告与门禁:生成可视化报告;对接发布流程——不过门(7.2 节的上线门)就自动阻断发布。

这四件东西缺任何一件,评估体系都会退化:没有对比,跑一万次也只是孤立报告;没有门禁,红灯亮了也照发不误——评估的权威一半来自数据,另一半来自"红灯真的会拦住发布"。

7.3.2 脚本结构:一个可落地的骨架 ​

用伪代码给一个 harness 主流程骨架(可直接翻译成 pytest 风格工程):

python
# 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、数据快照),执行与生产隔离;模型评委要人评校准。
  • 棘轮原则:分数只升不降,跌破底线自动阻断合入;底线上调只在里程碑节点,例外要走书面流程——它是纪律,不是暴政。
  • 模型厂商升级是最阴险的回退源:影子环境先跑全量评估再决定升不升,升级对客户是变更事件。
  • 好制度改变行为:棘轮生效后,本地预跑、用例资产化、随手优化消失——评估体系最终成为客户看得懂的交付凭证。

参考资料 ​