评测工程化:从手动到持续

一、从方案到工程化

③ 评测思维框架的决策树到"评测方案确定"就停了:

复制代码
  看到系统 -> 问题1粒度 -> 问题2时机 -> 问题3来源 -> 问题4目的 -> 方案确定
                                                                       │
                                                                       ▼
                                                                       停了

方案确定后,还有四步工程化工作:

复制代码
  评测方案确定
       │
       ▼
  ① 测试集管理    -- "拿什么来评?"
       │
       ▼
  ② 执行管道      -- "跑一次还是持续跑?"
       │
       ▼
  ③ 回归保护      -- "怎么防止退化?"
       │
       ▼
  ④ 在线评测      -- "线上有没有出问题?"

判分实现(规则校验/LLM-as-judge/两层配方)已在④ 评测实践中展开,本文不重复。本文聚焦"怎么持续跑"。

二、测试集管理

测试集是评测的输入--"拿什么来评"。没有测试集,方案和决策树都是空的。

来源:三种途径

复制代码
  ┌──────────────────┬──────────────────┬──────────────────┐
  │ 真实日志          │ 合成数据          │ 人工构造          │
  ├──────────────────┼──────────────────┼──────────────────┤
  │ 从生产环境采集    │ 用 LLM 生成变体   │ 手写边缘用例      │
  │ 最贴近实际        │ 可规模化          │ 覆盖极端情况      │
  │ 但有隐私/合规问题 │ 但可能不代表真实  │ 但不可规模化      │
  └──────────────────┴──────────────────┴──────────────────┘

建议:阶段 0 用真实日志 10 条起步(最贴近实际,量小无隐私压力)。阶段 1 扩展时混合三种:真实日志为主,合成数据补量,人工构造补边缘用例。

数量:多少够用?

复制代码
  阶段 0:  10 条    -- 手动跑通,验证评测逻辑能跑
  阶段 1:  50-100条 -- 统计有意义,能看出通过率分布
  阶段 2:  200+ 条  -- 回归保护,CI 触发时足够稳定

不要等"够了"才开始。10 条就能验证评测逻辑是否可用。评测集是渐进的,不是一次定终身的。

版本化与演化策略

测试集会演化--加用例、改用例、删过时用例。版本化的最低要求:

复制代码
  v1: 初始 10 条 (阶段 0)
  v2: 扩展到 50 条 (阶段 1)
  v3: 删除 3 条过时用例, 加 5 条边缘用例
  ...

每个版本记录:哪些用例、什么时候加的、为什么加。这样当通过率变化时,能区分"是系统变好了"还是"测试集变了"。

演化策略

  • 定期审查:每月检查一次,删除过时用例(业务场景已变的),补充新发现的问题模式
  • 缺陷驱动:线上发现的新问题,转化为测试用例加入集
  • 难度分级:标注用例难度(简单/中等/困难),避免测试集全是简单用例导致通过率虚高

三、执行管道

测试集有了,下一步是"怎么跑、怎么读结果"。

跑一次 vs 持续跑

复制代码
  跑一次 (阶段 0-1):
    "这次评测通过率多少?"
    -> 手动触发, 看结果, 改系统, 再跑
    -> 目的: 验证系统当前能力

  持续跑 (阶段 2):
    "系统有没有退化?"
    -> CI 触发, 每次提交自动跑
    -> 目的: 回归保护, 防止改 A 破坏 B

阶段 0-1 是"跑一次"。手动跑评测脚本,看结果,改系统,再跑。这够了。不需要 CI,不需要自动化。等评测集稳定到 100+ 条、评测逻辑成熟后,再上 CI。

结果聚合:分数意味着什么

跑完评测,会得到一堆分数。怎么读?

复制代码
  A 层 (代码评测) 的聚合:
    忠实度通过率 = 通过用例数 / 总用例数
    例: 85/100 = 85%
    
    含义: 85% 的用例中, 节点3 忠实渲染了节点2 的观测值
    15% 的用例有谎报/失真/编造 -> 这些是缺陷, 要修

  B 层 (LLM-as-judge) 的聚合:
    质量均分 = 所有用例的质量均分
    例: 3.8/5.0
    
    含义: 通过忠实度的用例, 语义质量平均 3.8 分
    低于 3.0 的用例是质量问题 -> 看裁判的理由, 改提示词

两个分数分开看,不要合成一个。忠实度 85% + 质量 3.8/5 不能合成"综合分 78.5"--它们测的是不同评测维度,合成会掩盖问题。忠实度失败是缺陷(要修),质量低是优化(要调提示词)。

评测本身的健康度

评测也可能有问题。这些信号说明评测本身需要检查:

复制代码
  信号 1: 忠实度通过率 = 100%
    -> 可能规则太松 (所有用例都过, 没区分力)
    -> 检查: 手动看几条输出, 确认规则在校验对的东西

  信号 2: 质量分数全是 3 分
    -> 可能裁判提示词太模糊 (LLM 不敢给极端分)
    -> 检查: 加锚点用例 (已知应该是 1 分和 5 分的用例)

  信号 3: 同一用例跑 3 次, 分数差 2 分以上
    -> 裁判不稳定
    -> 检查: 换裁判模型, 或加少样本示例稳定判分

  信号 4: 通过率突然跳变 (85% -> 50%)
    -> 要么系统坏了, 要么测试集变了
    -> 检查: 先确认测试集版本没变, 再查系统

评测不是"设好就忘"的。定期检查评测本身的健康度,否则在用一把弯的尺子量东西。

四、回归保护

持续跑评测的核心目的是回归保护--防止改 A 悄悄破坏 B。

退化检测

复制代码
  正常波动: ±2% (LLM 非确定性导致)
  退化信号: 通过率下降 >5%
  严重退化: 通过率下降 >15%

检测方法

  • 每次评测结果与上一版本对比
  • 下降 >5% 触发告警,下降 >15% 阻止发布
  • 区分"整体退化"和"个别用例退化":整体退化是系统问题,个别用例退化可能是测试集问题

告警阈值设计

复制代码
  ┌──────────────────┬──────────────────────────────┐
  │ 通过率变化        │ 动作                         │
  ├──────────────────┼──────────────────────────────┤
  │ ±2% 以内         │ 正常波动,无需干预            │
  │ 下降 2-5%        │ 记录,观察趋势                │
  │ 下降 5-15%       │ 告警,人工审查                │
  │ 下降 >15%        │ 阻止发布,必须修复            │
  │ 上升 >5%         │ 警惕(可能是测试集变简单了)   │
  └──────────────────┴──────────────────────────────┘

注意:通过率突然大幅上升也要警惕--可能是测试集泄露(模型见过答案),或测试集被改简单了。

CI 集成

复制代码
  PR 提交 -> 自动跑评测 -> 与基线对比
    │
    ├─ 通过率下降 <5%  -> CI 通过
    ├─ 通过率下降 5-15% -> CI 通过但告警
    └─ 通过率下降 >15% -> CI 失败, 阻止合并

五、在线评测实践

离线评测测能力上限,在线评测测线上健康。智能体的静默失败(看起来正常但结果偏离预期)比传统服务严重得多,需要在线评测及时发现。

工具能力

Langfuse、Phoenix、DeepEval 均支持在线评测:

复制代码
  Langfuse:
    对生产 trace 实时打分
    支持 LLM-as-a-judge、code evaluators、user feedback
    在 Dashboard 中展示评测趋势

  Phoenix:
    对生产 trace 打分
    支持 LLM-based evaluations、human annotations
    组件级评测(span 级)

  DeepEval:
    专门的 Online Evals 功能
    对 trace/span/thread 三级打分
    集成 Confident AI 平台做监控

静默失败检测

复制代码
  传统监控: 延迟升高、错误率上升 -> 告警
  在线评测: 输出偏离预期 -> 告警

  区别:
    传统监控看"系统有没有报错"
    在线评测看"输出质量有没有下降"

  智能体的静默失败:
    系统正常返回 200, 没有报错
    但输出内容偏离了预期(编造信息、遗漏关键字段、语义跑偏)
    只有在线评测能发现

采样策略

在线评测对每条生产流量打分成本太高(LLM-as-judge 需要 LLM 调用)。采样策略:

复制代码
  全量打分:  代码评测(便宜,可对每条流量跑)
  采样打分:  LLM-as-judge(贵,采样 1-10% 跑)
  触发打分:  只对异常 trace 打分(如延迟超阈值、用户反馈负面)

在线评测不替代离线评测。离线评测用测试集测能力上限,在线评测用真实流量测线上健康。两者互补。

六、从手动到自动

不需要一开始就建评测管道。从手动开始,渐进自动化。

三阶段路径

复制代码
  阶段 0: 手动 (本周就能开始)
  ┌──────────────────────────────────────────────┐
  │ - 10 条用例 (从真实日志选)                     │
  │ - 评测脚本: 一个 Python 文件                   │
  │ - 执行: 手动跑 python eval.py                 │
  │ - 结果: 打印到终端 / 写 CSV                    │
  │ - 频率: 改完系统跑一次                         │
  │                                                │
  │ 目标: 验证评测逻辑能跑, 能区分好/坏用例        │
  │ 成功标准: 能指着某条用例说"这个该失败"         │
  │          且评测确实给了失败                     │
  └──────────────────────────────────────────────┘
       │ (评测逻辑稳定后, 2-3 周)
       ▼
  阶段 1: 脚本化
  ┌──────────────────────────────────────────────┐
  │ - 50-100 条用例                               │
  │ - 评测脚本: 包化的模块, 可导入                 │
  │ - 执行: 一键脚本 run_eval.sh                   │
  │ - 结果: 写 DB / 写评测平台分数                 │
  │ - 频率: 每周跑一次 / 版本发布前跑              │
  │                                                │
  │ 目标: 评测可重复, 结果可追踪                   │
  │ 成功标准: 两次跑同一版本, 通过率一致 (±2%)     │
  └──────────────────────────────────────────────┘
       │ (评测稳定后, 4-6 周)
       ▼
  阶段 2: CI 触发 + 在线评测
  ┌──────────────────────────────────────────────┐
  │ - 200+ 条用例                                 │
  │ - 评测脚本: CI 流水线的一部分                  │
  │ - 执行: 每次 PR / 每次合并自动触发             │
  │ - 结果: 写 DB + 告警 (通过率下降 >5% 时)       │
  │ - 在线: 对生产 trace 采样打分                  │
  │ - 频率: 每次代码变更 + 线上持续                │
  │                                                │
  │ 目标: 回归保护 + 线上质量监控                  │
  │ 成功标准: 有一次 CI 拦住了一个退化              │
  │          或在线评测发现了一次静默失败           │
  └──────────────────────────────────────────────┘

关键原则

不等管道,本周就能开始阶段 0。

最常见的错误是"等评测基础设施建好再开始评测"。这是倒着的--不知道评测什么,怎么建基础设施?阶段 0 的 10 条手动评测就能告诉你:真值逻辑对不对、裁判提示词稳不稳定、维度选择准不准。这些信息反过来指导管道建设。

阶段 0 不需要任何工具。 一个 Python 文件、10 条用例、print() 输出结果。够了。工具是阶段 1-2 的事。

每个阶段的退出条件是"评测逻辑稳定",不是"时间到了"。 如果阶段 0 跑了 2 周还在改评测逻辑(规则校验老是误判、裁判提示词不稳定),不要急着进阶段 1。先让评测逻辑稳定。

决策:评测流水线架构

读完本文,画出你的评测流水线:

复制代码
  ┌─────────────────────────────────────────────────────┐
  │ 评测流水线架构                                       │
  ├─────────────────────────────────────────────────────┤
  │ 测试集:    □ 10条   □ 50-100条   □ 200+条           │
  │ 执行方式:  □ 手动    □ 脚本化     □ CI触发          │
  │ 回归保护:  □ 无      □ 告警       □ 阻止发布        │
  │ 在线评测:  □ 无      □ 采样打分   □ 全量打分        │
  ├─────────────────────────────────────────────────────┤
  │ 当前阶段:  □ 阶段0   □ 阶段1      □ 阶段2           │
  │ 下一步:                                               │
  │   (基于当前位置,写出下一步行动)                      │
  └─────────────────────────────────────────────────────┘

⑥ 工具选型将帮你选择评测工具,⑦ 工具落地将展示选定工具的接入方式。

相关推荐
GISer_Jing18 小时前
0719一个月总结
人工智能·ai·前端框架
颜淡慕潇18 小时前
WAIC 2026:当AI学会说谎,合合信息用多模态鉴伪技术为数字世界“打假”
人工智能
kp0000018 小时前
AI系统输入安全基线
人工智能·安全·网络安全·信息安全·ai安全
雪碧聊技术18 小时前
中国可重复使用火箭首次成功着陆——航天“降本时代”正式开启
大数据·人工智能
饼干哥哥18 小时前
n8n 又活了?用 Codex把跨境电商工作流转成 Skill
人工智能·后端·代码规范
武子康18 小时前
Java 后端 → 实时语音 AI 转型复盘:4 个 FDE 技术底座 + 6 个差距 + 6 类职业资产路线
人工智能·后端·openai
卖微积分的男孩18 小时前
【论文精读】Tapered Language Models|锥形语言模型
人工智能·语言模型·自然语言处理
_瑞18 小时前
AI Coding 那么快,为什么还需要 SDD?
人工智能·ios·ai编程
Python私教18 小时前
我用 AI 做出了第一个 Godot 贪吃蛇
人工智能·游戏引擎·godot