Agent AtlasAI Agent 知识库
05.03工程化 · Engineering

评估体系 Evals

结果评估、轨迹评估、LLM-as-a-Judge、离线集与在线指标,以及如何避免评估集污染。

没有评估,提示词调优就是玄学;有了评估,你才知道一次修改是进步、退步,还是只是换了个错误。

四个评估层级

图 1 · 从零件到线上
单元工具、解析、Schema
确定性测试
→
轨迹步骤、工具选择、参数
→
端到端任务是否完成、质量
→
线上成功率、接管率、成本

1. 单元评估

不需要模型的部分用普通测试:

  • 工具参数校验;
  • 文档解析正确性;
  • 输出 Schema;
  • 权限过滤;
  • 幂等与重试。

这些应该 100% 通过,且跑得很快。

2. 轨迹评估

多步任务里,最终答案对可能是蒙的。轨迹评估看:

  • 是否选了正确的工具;
  • 参数是否正确;
  • 步数是否合理(有没有绕路);
  • 是否调用了不该调用的工具;
  • 失败后是否恢复;
  • 是否越权。

一个简单的轨迹评分卡:

text
工具选择正确    0/1
参数完整正确    0/1
无多余步骤      0/1
无越权动作      0/1
错误可恢复      0/1

3. 端到端评估

给一个任务,看最终产物是否满足标准。评分方式:

  • 精确匹配:分类、抽取、计算;
  • 包含关键事实:报告、回答;
  • 规则校验:格式、引用、金额;
  • 评分量表:写作质量、完整性;
  • 成对比较:A/B 哪个更好。

4. 线上评估

线上没有标准答案,看行为指标:

  • 任务完成率(用户是否接受结果);
  • 人工接管率;
  • 重试/重新生成率;
  • 投诉率;
  • 平均步数、P95 延迟、单任务成本;
  • 工具错误率;
  • 安全拦截率。

构建黄金集

一个可用的起步规模是 50–200 条,覆盖:

类型占比例子
常见顺利路径40%标准退款、常规查询
边界情况20%金额刚好等于上限、日期最后一天
信息不足15%缺订单号、文档没有答案
对抗/注入10%网页里的恶意指令、越权请求
历史失败15%线上真实出过的问题

每条样本至少包含:

json
{
  "id": "refund-014",
  "input": "订单 A1024 签收 9 天了,还能退吗?",
  "context": { "user_id": "u_1", "now": "2026-10-29" },
  "expected": {
    "answer_contains": ["超过 7 天", "无法自动退款"],
    "must_call": ["search_policy"],
    "must_not_call": ["create_refund"],
    "citations": ["refund_policy#p2"]
  },
  "tags": ["refund", "boundary", "policy"]
}

不要只存「标准答案文本」。多步任务要存必须调用的工具、禁止的动作、关键事实、引用来源。

数据来源:

  • 真实用户请求(脱敏后);
  • 客服/运营整理的高频问题;
  • 线上失败案例;
  • 人工构造的边界与对抗样本。
不要用模型生成评估集然后自己评自己

模型生成的样本往往过于顺滑,缺少真实世界的噪声。黄金集必须有人工确认的部分。

指标怎么选

任务主指标辅助指标
分类准确率、混淆矩阵置信度校准
抽取字段级 F1格式通过率
工具调用工具选择准确率、参数正确率平均步数
问答事实正确率、引用准确率拒答率
报告评分量表、事实覆盖长度、可读性
代码测试通过率补丁大小、回归率
端到端任务成功率P95 延迟、成本

不要用一个模糊的「总分」掩盖具体问题。分类错和引用错需要完全不同的修复。

LLM-as-a-Judge:能用,但要校准

适用场景:主观质量、开放式回答、成对比较。

最佳实践:

  1. 明确评分标准:每个分数对应什么行为;
  2. 成对比较:A/B 哪个更好,比绝对打分稳定;
  3. 随机顺序:消除位置偏见;
  4. 控制长度:评委容易偏爱更长的回答;
  5. 多次采样:取多数或平均;
  6. 人工校准:抽 50 条,对比人工与评委的一致性;
  7. 记录理由:让评委先给证据再给分。

一个可用的评分提示:

text
你是严格的评审。根据以下标准比较 A 与 B:
- 事实准确性(0-3):每个事实是否有来源支持
- 完整性(0-2):是否覆盖问题的所有部分
- 简洁性(0-1):是否有重复或无关内容
先列出各自的证据与问题,再给出胜者。不要因为更长就给更高分。

评委与被评模型最好不同家族,减少共同偏见。

统计:别被小样本骗了

50 条样本、80% 通过率,95% 置信区间大约是 66%–90%。也就是说,两个版本 78% vs 82% 的差异可能只是噪声。

实践建议:

  • 关键决策至少 100–200 条;
  • 用 Wilson 区间或 bootstrap 估算置信区间;
  • 同一版本跑 2–3 次,观察方差;
  • 比较「失败类型分布」,而不只是总分;
  • 不要针对测试集反复调参(过拟合)。

一个评估脚本

python
import json
from statistics import mean

def run_eval(agent, dataset):
    results = []
    for case in dataset:
        trace = agent.run(case["input"], context=case.get("context"))
        checks = {
            "answer": check_answer(trace.answer, case["expected"]),
            "tools": check_tools(trace.tool_calls, case["expected"]),
            "citations": check_citations(trace.citations, case["expected"]),
            "steps": len(trace.steps) <= case["expected"].get("max_steps", 8),
        }
        results.append({
            "id": case["id"],
            "tags": case["tags"],
            "passed": all(checks.values()),
            "checks": checks,
            "steps": len(trace.steps),
            "tokens": trace.tokens,
            "latency_ms": trace.latency_ms,
        })

    by_tag = {}
    for r in results:
        for tag in r["tags"]:
            by_tag.setdefault(tag, []).append(r["passed"])

    return {
        "pass_rate": mean(r["passed"] for r in results),
        "by_tag": {k: mean(v) for k, v in by_tag.items()},
        "avg_steps": mean(r["steps"] for r in results),
        "p95_latency": percentile([r["latency_ms"] for r in results], 95),
        "total_tokens": sum(r["tokens"] for r in results),
        "failures": [r for r in results if not r["passed"]],
    }

输出要能回答三个问题:

  1. 整体通过率是多少?
  2. 哪一类失败最多?
  3. 成本与延迟是否可接受?

接进 CI

每次改提示、工具、模型,自动跑:

yaml
- name: agent-eval
  run: python evals/run.py --dataset evals/golden.jsonl --fail-under 0.85

CI 里用固定模型版本、固定温度、固定工具 mock。真实模型调用可能慢且贵,可以:

  • 小规模冒烟(10 条)每次跑;
  • 全量(100+)每天或发版前跑;
  • 记录基线,低于基线就失败。

线上评估

线上最重要的是可归因:

  • 每个任务有 trace_id;
  • 用户反馈能关联到具体轨迹;
  • 失败能分类(检索、工具、推理、权限、超时);
  • 抽样人工复核。

不要只看「点赞率」。用户可能因为界面好看而点赞,也可能因为不知道正确答案而无法判断。

评估集污染

  • 训练数据可能包含公开评测题;
  • 提示里可能泄漏测试样本;
  • 长期记忆可能记住了答案;
  • 团队反复针对测试集调参。

对策:保留一个从未看过的留出集,只在发版前跑;定期更换样本;用新构造的边界案例。

常见失败

只评估最终答案

过程错了但答案蒙对,线上迟早出问题。多步任务必须看轨迹。

评估集太小

10 条样本的 90% 和 80% 没有统计意义。至少几十条,关键场景上百条。

用同一个模型当评委和选手

共同偏见会让评估虚高。尽量换家族,或加入人工校准。

没有失败分类

只报一个通过率,不知道从哪修。按标签、失败类型、工具维度拆开看。

评估与生产不一致

测试用 mock 工具、生产用真实 API,行为差异大。关键路径要有端到端测试。

检查清单

  • 有 50+ 条人工确认的黄金集
  • 覆盖顺利路径、边界、信息不足、对抗、历史失败
  • 多步任务评估轨迹,不只评估答案
  • 指标按标签/失败类型拆分
  • LLM 评委经过人工校准,顺序随机
  • 有置信区间与方差意识
  • 评估接进 CI,有基线
  • 线上有 trace、反馈关联、失败分类
  • 保留未公开留出集
  • 评估成本与延迟可接受

小结

  • 评估分单元、轨迹、端到端、线上四层。
  • 黄金集要覆盖边界、拒答、对抗和历史失败。
  • 多步任务必须看工具选择与步骤,而不只是最终答案。
  • LLM 评委需要标准、随机化、校准和人工抽检。
  • 小样本差异可能只是噪声,关注失败分布与置信区间。

下一篇讲怎么在线上看见 Agent 内部发生了什么:可观测性。

读完了?进度会保存在本地浏览器。
内容会持续修订。发现错误或想补充,欢迎反馈。 遇到问题?查排查手册 →