本文是「智能体评测系统认知」系列第 ① 篇。系列导航:
一、评测 vs 测试:从"验证"到"评估"
传统软件测试:确定性世界
传统软件测试建立在一个前提上:相同的输入产生相同的输出。
输入: user_id=123, action=withdraw, amount=100
-> 处理逻辑固定
输出: balance=900, status=success
-> 验证: output == expected? 对 / 错
测试框架的核心能力是验证(verification):给定输入,断言输出等于期望值。对就是对,错就是错。单元测试、集成测试、端到端测试,本质上都在做这件事。
这个模型之所以有效,是因为传统软件的行为是确定性的。同样的代码、同样的输入,永远产生同样的输出。测试可以复现,可以回归,可以自动化。
LLM 评测:非确定性世界
LLM 应用打破了确定性前提。相同的输入可能产生不同的输出。
输入: "写一封双十一营销邮件"
-> LLM 生成
输出 A: "亲爱的会员,双十一狂欢来袭..."
输出 B: "限时特惠!年度最低折扣..."
输出 C: "尊敬的客户,感谢您一年的支持..."
-> 哪个"对"?没有唯一正确答案
这不是 bug,是 LLM 的特性。温度参数、采样的随机性、模型版本的迭代,都会导致输出变化。传统测试的"断言输出等于期望值"在这里失效了--你无法预先定义"正确答案"。
评测(evaluation)由此产生。评测不是验证"对/错",而是评估"多好"。
性质差异:不是程度,是类别
测试 (Testing): 验证 -> 对/错 -> 有标准答案
评测 (Evaluation): 评估 -> 多好 -> 无唯一答案
这不是"更难的测试",是性质不同的学科。
测试关心"功能正不正确",评测关心"质量好不好"。
这个性质差异驱动了后续所有的方法论选择。为什么需要 LLM-as-judge?因为没有标准答案,需要"裁判"来判断质量。为什么需要人工标注?因为"好不好"本质上是人类判断。为什么评测比测试难?因为"对/错"是二元的,"多好"是连续的、主观的、难以量化的。
为什么传统测试方法不够用
| 传统测试方法 | 在 LLM 场景的问题 |
|---|---|
| 断言(assert equal) | 输出非确定,无法预定义期望值 |
| 覆盖率(code coverage) | LLM 的"逻辑"是模型权重,不是代码分支 |
| 回归测试(regression) | 模型升级后输出全变,不能逐条断言 |
| 性能测试(perf test) | 延迟和吞吐可测,但"质量"无法用性能指标衡量 |
传统测试方法不是没用--LLM 应用的工程层(API 网关、数据处理、业务逻辑)仍然需要传统测试。但 LLM 的生成质量需要评测,测试覆盖不了。
二、评测 vs 观测:描述与判断
一个常见的误解
"我装了 Langfuse,有 trace 了,所以我有了评测。"
这是最常见的误解。有 trace 不等于有评测。trace 是观测,评测是观测之上的一层判断。
观测:描述"发生了什么"
观测(observability)回答的是描述性问题:
LLM 调用的输入是什么?输出是什么?
耗时多少?token 用量多少?
调用了哪些工具?按什么顺序?
延迟是否正常?是否有错误?
观测的核心是采集和展示:把发生的事情记录下来,让人能看到。OpenTelemetry、Langfuse 的 trace 采集、Dashboard、告警,都是观测能力。
观测不判断"好不好"。它告诉你"LLM 输出了这句话",但不告诉你"这句话写得好不好"。
评测:判断"好不好"
评测(evaluation)回答的是判断性问题:
这个回复准确吗?
这个回复有帮助吗?
这个回复忠实于事实吗?
这个回复安全吗?
评测的核心是判分:对输出做质量判断,给出分数或评级。LLM-as-judge、人工标注、规则校验,都是评测能力。
80% 共通,20% 独有
评测和观测有大量技术重叠:
┌─────────────────────────────────────────────┐
│ 观测 (Observation) │
│ trace 采集 / 存储 / Dashboard / 告警 │
│ 延迟监控 / 成本统计 / 错误率 │
│ │
│ + 判分层 (Judging Layer) ← 评测独有 20% │
│ + 测试集管理 │
│ + LLM-as-judge / 规则校验 │
│ + 人工标注 │
│ │
│ 评测 (Evaluation) │
└─────────────────────────────────────────────┘
评测 = 观测基础设施 + 判分层(插件)
80% 的技术是共通的:管道、存储、Dashboard、告警。评测独有的 20% 是判分层--对输出做质量判断的能力。
这意味着:如果你已经有观测基础设施(如 Langfuse),加评测不需要重建系统,只需要加判分层。但也意味着:只有观测没有判分层,不等于有评测。
本系列的边界
观测: "发生了什么?" -> 采集、展示、告警 (描述性)
评测: "好不好?" -> 判分、质量评估 (判断性)
本系列讲判分层,不讲 trace 采集。
观测是评测的基础设施,不是本系列的教学内容。
三、三层模型:评测在生命周期中的位置
评测不是单一活动,它分布在整个生命周期中。按时机和目的,分为三层。
三层架构
┌──────────────────────────────────────────────────────┐
│ 层 1 离线评测 -- 测能力上限 -- 发布前跑 │
│ │
│ 用预定义的测试集离线运行,评估系统能不能完成任务。 │
│ 类似传统软件的"测试",但判分是"多好"而非"对错"。 │
│ 在新版本发布前跑,防止质量退化。 │
│ │
│ <- 本系列的重点 -> │
├──────────────────────────────────────────────────────┤
│ 层 2 在线评测 -- 实时质量打分 -- 线上 │
│ │
│ 对生产环境的真实流量实时打分,发现"静默失败"。 │
│ 静默失败: 系统看起来正常运行,但输出偏离预期。 │
│ 这是 LLM 应用特有的风险--非确定性导致的问题难以 │
│ 通过传统监控发现。 │
│ │
│ <- 已有实践,⑤ 评测工程化展开 -> │
├──────────────────────────────────────────────────────┤
│ 层 3 观测 -- 测运行健康 -- 7x24 │
│ │
│ trace 采集、延迟监控、成本统计、错误告警。 │
│ 传统可观测性在 LLM 场景的延伸。 │
│ 工具: Langfuse、Phoenix、OpenTelemetry 等。 │
│ │
│ <- 其他工具覆盖,本系列不讲 -> │
└──────────────────────────────────────────────────────┘
层与层的关系
层 1 (离线评测): 发布前 -> "能不能用?" -> 有测试集, 有判分
层 2 (在线评测): 运行中 -> "有没有出问题?" -> 对线上流量打分
层 3 (观测): 运行中 -> "系统健康吗?" -> 只记录, 不判分
层 1 是主动的: 你主动跑测试集来评。
层 2 是被动的: 线上流量来了, 你实时评。
层 3 是记录的: 线上流量来了, 你记录但不评。
层 2 是层 1 和层 3 的交叉地带:它对线上数据打分(像层 1 的判分),但是对实时流量(像层 3 的在线)。智能体应用特别需要层 2,因为智能体的静默失败比传统服务严重得多--看起来正常完成了任务,但结果偏离了预期。
本系列的位置
本系列聚焦层 1(离线评测)。原因:
- 层 1 是评测的起点--在发布前发现问题比在线上发现问题成本低
- 层 1 的方法论最成熟--测试集、判分方法、聚合指标都有实践积累
- 层 1 是层 2 的基础--在线评测复用离线评测的判分逻辑
层 2 已有实践--Langfuse、Phoenix、DeepEval 均支持对生产 trace 实时打分,但仍在发展中。本系列在⑤ 评测工程化中展开在线评测实践。层 3 由观测工具覆盖,不是本系列的教学范围。
四、为什么 LLM 评测难
LLM 评测不是"把传统测试改一改"。它面临三个传统测试不存在的根本困难。这三个困难驱动了后续所有文章的方法选择。
困难 1:非确定性
传统软件: 输入 A -> 永远输出 B (确定性)
LLM: 输入 A -> 可能输出 B, 也可能输出 C, D (非确定性)
同一输入产生不同输出,这意味着:
- 不能断言特定输出:你不能说"输入 A 必须输出 B",因为输出 C 也可能是好的
- 不能逐条回归:模型升级后,100 条测试用例的输出可能全变了,但不能说"全坏了"
- 需要多次运行:同一条用例跑 3 次,可能 2 次好 1 次差,如何判分?
非确定性使得评测从"一次断言"变成"多次评估取统计"。这增加了成本和复杂度。
困难 2:无真值
真值(ground truth)= 可用于比对的地面真值。传统测试有真值(期望输出),LLM 评测多数没有。
有真值的任务:
提取: "从文本提取日期" -> 正确日期可定义 -> 有真值
分类: "邮件是否垃圾" -> 正确标签可定义 -> 有真值
代码: "修这个 bug" -> 测试套件可判 -> 有真值
无真值的任务:
生成: "写一封营销邮件" -> 没有唯一正确答案 -> 无真值
摘要: "总结这篇文章" -> 多种好摘要 -> 无真值
建议: "该不该买这只股票" -> 没有标准答案 -> 无真值
对话: "回复用户问题" -> 多种合理回复 -> 无真值
无真值是大多数 LLM 评测场景的默认状态。没有真值,就不能用"比对"来判分,只能退到 LLM-as-judge或人工评测--更贵、更模糊、更不可规模化。
真值有无是评测方法选择的决定性约束。有真值时可以用确定性判分(便宜、可靠),无真值时只能用模糊判分(昂贵、不稳定)。这个分叉贯穿了整个评测方法论。
困难 3:开放输出
封闭输出 (传统软件):
API 返回 JSON: {"status": "success", "code": 200}
-> 结构固定, 字段固定, 可以逐字段断言
开放输出 (LLM):
LLM 返回自然语言: "重庆明天 33°C,降雨概率 30%,建议带伞。"
-> 内容开放, 表达多样, 无法逐字段断言
-> 同一信息可以有多种表达方式
开放输出使得"比对"变得困难。即使你有真值(如天气数据),LLM 的表达方式也是多样的--"33°C"可以写成"三十三度"、"33 摄氏度"、"温度为 33°C"。你需要从自然语言中提取信息再比对,这本身就是一个 NLP 问题。
三个困难的连锁效应
非确定性 -> 不能断言特定输出 -> 需要多次评估
无真值 -> 不能比对 -> 需要裁判(LLM/人工)
开放输出 -> 不能逐字段断言 -> 需要从自然语言提取信息
三个困难叠加:
传统测试: 跑一次, 断言, 通过/失败 (秒级, 免费)
LLM 评测: 跑多次, 裁判判分, 统计聚合 (分钟级, 有成本)
这就是为什么 LLM 评测是一个新学科, 而不是"改改测试框架"。
这三个困难驱动了什么
后续文章的所有方法论都可以追溯到这三个困难:
| 困难 | 驱动的方法选择 |
|---|---|
| 非确定性 | 多次运行取统计、LLM-as-judge跑 3 次取均分 |
| 无真值 | LLM-as-judge、人工评测、标注队列 |
| 开放输出 | 规则校验(从自然语言提取数值再比对)、LLM-as-judge(评语义质量) |
② 评测全景将展示工程界的评测维度、学界的方法分类、基准与工具全景。③ 评测思维框架将给出一个设计框架,让读者对任何评测情境都能推出"该评什么、怎么评、为什么"。
决策:你需要评测体系吗?
读完本文,做一个判断:你的 LLM 应用,现在怎么回答"好不好"?
□ 凭感觉(demo 看起来不错)
□ 凭用户没投诉
□ 凭测试通过率(测试验证对错,不评估质量)
□ 有评测体系(测试集 + 判分 + 持续跑)
选前三个中的任何一个,说明你需要评测体系。承认"我现在没有标准"是建立评测体系的第一步。