Agent Evals 学习教程

09. 工程落地 Playbook

读完本章,你应该能:

本章回答:怎样把 eval 从一次性分析变成持续运行的工程系统。

学习目标

读完本章,你应该能:

  • 设计一个最小可用 eval stack。
  • 区分 offline eval、online eval、CI gate 和 human review。
  • 选择适合你阶段的工具和数据结构。
  • 为 prompt、tool、model、harness、runtime 改动建立回归保护。

本章导读

如果前面的章节是在讲“什么是好的 eval”,这一章关心的是“怎样让好的 eval 留在团队日常里”。很多 eval 工作失败,不是因为第一次分析不精彩,而是因为它没有进入工程流程。报告写完了,bug 修了几个,过两周 prompt 一改,旧问题又回来了;线上出现新失败,没人把它加回数据集;judge prompt 更新了,却没有重新校准。

eval 真正产生复利,是从它变成基础设施开始的。基础设施不一定复杂,它可以是一组 JSONL、几个 pytest、一个 GitHub Action 和一份每周错误分析表。关键是:每个重要失败都能留下回归样本,每次改动都能跑同一套检查,每次线上新问题都能回到离线数据集。这样,系统不是靠记忆变好,而是靠机制变好。

本章的重点不是推荐某个工具,而是梳理这些机制应该如何连接。工具可以换,流程不能断:记录 trace,维护 dataset,版本化 scorer,比较实验,阻断高风险回归,监控线上漂移,再把新失败带回下一轮。

Eval 工程栈

工程落地的核心原则

Eval 工程不是为了追求平台复杂度,而是为了让反馈更快、更可信、更可复现。一个小团队可以从 CSV、JSONL、pytest 和 promptfoo 起步;一个成熟团队可以引入 Braintrust、Langfuse、Phoenix、MLflow、Inspect AI、Weave 等平台。工具选择不是关键,关键是系统必须闭环:

trace logging -> dataset -> scorer -> experiment -> analysis -> fix -> regression -> monitoring

如果其中任何一环缺失,eval 都会退化成一次性报告。

想象一次普通 PR:工程师改了报销 agent 的 system prompt,让它“尽量减少追问,提高处理效率”。如果没有 eval 基础设施,这个改动可能只经过几条手工 demo;如果有一套闭环,它会自动跑 golden set、回归集和高风险 policy cases,记录每条 trace,比较是否更少追问但更多错误提交,并在超预算报销 case 失败时阻断合并。工程落地的意义就在这里:把抽象的“质量担忧”变成每次改动都会触发的证据。

最小可用 eval stack

1. Logging / tracing

至少记录:

  • request id / user id hash / session id。
  • input、context、retrieved docs。
  • model、prompt version、tool version。
  • tool calls、arguments、observations、errors。
  • final output。
  • final environment state 或 state diff。
  • latency、token、cost。
  • human feedback 或人工标签。

没有 trace,就无法做错误分析;没有版本号,就无法解释回归。

日志不是为了事后追责,而是为了让失败可学习。一个 eval run 只记录“case 失败”几乎没有用;你需要知道失败时用了哪个 prompt、检索到了哪份政策、调用了哪个工具、工具返回了什么、最终状态怎么变了。没有这些字段,团队会在失败面前重新回到猜测:是模型问题、工具问题、数据问题,还是 scorer 问题?

2. Dataset

建议把 eval cases 放在 repo 中,使用 JSONL/YAML/CSV:

{
  "id": "expense_project_code_001",
  "source": "production_trace",
  "task": "prepare_expense_report",
  "input": "帮我把上周上海出差的高铁和酒店报销掉",
  "context": {
    "channel": "internal_chat",
    "employee_id": "E1024",
    "project_code": null,
    "hotel_amount": 1280,
    "hotel_limit": 900
  },
  "expected": {
    "must_ask_for": ["project_code", "over_budget_explanation"],
    "must_not_call": ["submit_expense"]
  },
  "tags": ["expense", "policy", "regression"],
  "severity": 4
}

数据集要版本化。每条 case 应该能追溯来源和原因。

版本化的核心不是形式,而是可解释性。两周前通过率 91%,今天 86%,到底是模型退步、prompt 变化、数据集新增了难例,还是 scorer 更严格了?如果 dataset、scorer、prompt 和 runtime 没有版本,数字变化就无法被解释,也无法支撑决策。

3. Scorers

Scorer 应以代码或配置管理。常见组合:

  • assert_valid_json(output)
  • assert_required_expense_fields(trace, output)
  • assert_no_submit_without_confirmation(trace)
  • assert_state_diff(before, after)
  • judge_should_escalate_policy_risk(trace)
  • judge_grounded_answer(input, context, output)

每个 scorer 要有:

  • 名称。
  • 版本。
  • 输入字段。
  • 失败解释。
  • 适用 case tags。
  • 校准报告,如果是 LLM judge。

4. Experiment runner

runner 负责:

  • 加载 dataset。
  • 调用系统。
  • 隔离环境。
  • 记录 trace。
  • 运行 scorers。
  • 输出 per-case results 和 aggregate metrics。

结果至少包含:

{
  "run_id": "2026-06-28-agent-v3",
  "git_sha": "abc123",
  "model": "MODEL_NAME",
  "prompt_version": "2026-06-28",
  "dataset_version": "golden-2026-06-28",
  "metrics": {
    "pass_rate": 0.91,
    "policy_violation_rate": 0.01,
    "cost_per_success": 0.18
  },
  "failures": [
    {
      "case_id": "expense_over_budget_009",
      "scorer": "expense_policy_judge@v3",
      "reason": "酒店超预算且缺少业务说明,agent 仍声称可以提交"
    }
  ]
}

5. CI gate

CI gate 的作用不是替代人类,而是防止明显回归合并。适合 gate 的 scorer:

  • deterministic assertions。
  • state verifiers。
  • 已校准且低波动的 binary judges。
  • 高风险固定 regression cases。

不适合硬 gate 的指标:

  • 未校准 LLM judge 连续分。
  • 小样本探索结果。
  • 高波动线上抽样。

6. Online monitoring

线上监控用于发现新分布和新失败:

  • 抽样 production traces。
  • 跑便宜的 deterministic checks。
  • 周期性跑 LLM judges。
  • 人工审计高风险或低置信样本。
  • 把新 failure modes 回流到 eval set。

Offline 与 online 的区别

类型主要目的数据来源频率典型动作
Offline golden eval比较版本curated dataset每次实验/PR选择模型或 prompt
Regression eval防旧 bug 复活历史失败每次 PR阻断合并
Holdout eval估计泛化隐藏样本版本发布前发布决策
Online monitor发现漂移线上抽样持续/每日/每周告警和新增 case
Human review校准和审计抽样/高风险定期更新 rubric 和 labels

CI gate 示例

一个 promptfoo 风格的 gate 可以非常简单AwesomeEvalsPatterns2026:

prompts:
  - file://prompts/agent_system_prompt.txt
providers:
  - openai:gpt-5-mini
tests:
  - vars:
      input: "Cancel my order and refund $0"
    assert:
      - type: not-contains
        value: "refund processed"
      - type: javascript
        value: "output.toLowerCase().includes('no charge to refund')"
  - vars:
      input: "帮我报销这次出差,酒店超预算但我还没写说明"
    assert:
      - type: not-contains
        value: "已提交"
      - type: javascript
        value: "output.includes('超预算') && output.includes('说明')"

CI 的关键不是具体工具,而是:

  • 结果机器可读。
  • 阈值明确。
  • 失败样本可追溯。
  • PR diff 能看到新增或修改的 cases。
  • 高风险 case 不能被平均分掩盖。

CI gate 最适合守住“绝不能回退”的边界,而不是替代所有产品判断。高风险回归、确定性格式错误、状态 verifier 和校准稳定的 binary judge 可以进入硬 gate;探索性 judge、线上抽样和小样本趋势更适合进入报告。否则 CI 会变成随机红灯,团队迟早会绕过它。

工具生态怎么选

需求轻量选择平台/框架选择
配置化 prompt evalpromptfooBraintrust、LangSmith
Python 单测式 evalpytest + 自定义 scorersDeepEval、MLflow GenAI evaluate
Agent benchmark / sandbox自定义 harness、DockerInspect AI、Terminal-Bench/Harbor 风格
Tracing / observabilityOpenTelemetry logsPhoenix、Langfuse、Weave、LangSmith
LLM judge library自写 prompt + eval scriptautoevals、openevals、Prometheus、Atla
RL/verifiable reward自定义 reward functionsverifiers、ART/RULER、reward-kit

工具选择标准:

  1. 是否能导出原始 trace?
  2. 是否能版本化 dataset?
  3. 是否能写自定义 scorer?
  4. 是否支持 CI?
  5. 是否能关联 git SHA、prompt version 和 model version?
  6. 是否能支持人工标签和校准?
  7. 是否能自托管或满足数据合规?

选工具时要警惕“展示很好看,但原始数据拿不出来”的平台。eval 的资产不是仪表盘截图,而是 trace、case、scorer、标签、版本和失败样本。如果工具不能让你导出这些对象,团队就很难迁移、审计或复现结果。平台应该降低闭环成本,而不是把 eval 变成另一个黑箱。

数据集生命周期

Rendering diagram...

数据集会老化。老化原因包括:

  • 产品能力改变。
  • 用户分布改变。
  • 工具/API 改变。
  • 模型能力饱和。
  • case 不再代表真实风险。

所以要定期归档、替换和刷新。

数据集维护看起来像杂务,其实是 eval 可信度的核心。一个三个月前很难的 case,可能已经被模型轻松解决;一个曾经重要的产品流程,可能已经被新 UI 替代;一个回归 case 可能仍然有历史价值,但不该再拖慢每次 PR。维护不是删除记忆,而是把 case 放到合适的位置:golden、regression、holdout、archived 或 online review。

实验报告模板

每次重要 eval run 输出一份短报告:

# Eval Run: agent-v3 vs agent-v2

日期:2026-06-28
代码版本:GIT_SHA
Dataset:golden-2026-06-28, 120 cases
Scorers:expense_state_success@v2, no_submit_without_confirmation@v1, expense_policy_judge@v3

## 结论
- agent-v3 overall pass rate +4.2pp。
- 但 expense_policy_judge TPR 从 0.92 降到 0.84,不建议直接发布。
- 成本 +18%,主要来自重复 retrieval。

## 关键指标
| metric | v2 | v3 | delta |
| --- | ---: | ---: | ---: |

## Top failures
| case | category | reason | owner |
| --- | --- | --- | --- |

## 决策
- 修复超预算报销 regression。
- 对 retrieval 加缓存和 max calls。
- 新增 5 条缺失项目编号/超预算说明 regression cases。

团队流程

PR 规则

  • 修改 prompt、tool schema、retrieval 或 model routing,必须跑 offline eval。
  • 修 bug 必须加 regression case。
  • 高风险 scorer fail 不允许用平均分覆盖。
  • 更新 judge prompt 必须附校准结果。

每周流程

  • 抽样线上 trace。
  • 做 30 到 60 分钟错误分析。
  • 更新 failure taxonomy。
  • 新增 regression cases。
  • 审查线上监控告警。
  • 删除或归档过时 cases。

每月流程

  • 跑 holdout eval。
  • 审核 judge 漂移。
  • 更新模型和 harness 对比。
  • 复盘成本、延迟、失败率趋势。
  • 决定是否刷新 benchmark 或新增难任务。

版本管理

至少版本化:

  • dataset。
  • scorer code/prompt。
  • judge model。
  • system prompt。
  • tool schema。
  • harness。
  • runtime image。
  • environment seed。

Agent eval 中,runtime image 和 tool versions 特别重要。否则你可能无法解释同样模型为什么本月比上月差。

常见误区

误区 1:只在上线前跑一次 eval。
eval 应该进入日常开发循环。

误区 2:CI gate 用不稳定 judge。
这会制造随机红灯,最终团队会绕过 eval。

误区 3:只存聚合指标。
没有 per-case failures 和 trace,指标无法指导修复。

误区 4:回归集只增不管。
回归集也要维护,过时 case 会拖慢迭代。

误区 5:线上监控与离线 eval 脱节。
线上新失败必须回流成离线 case,否则同类问题会重复出现。

本章练习

为你的项目写一个 eval infra 设计:

  1. 你记录哪些 trace 字段?
  2. 数据集文件格式是什么?
  3. 至少 5 个 scorer 是什么?
  4. 哪些 scorer 进入 CI gate?
  5. 线上抽样频率是多少?
  6. 人类校准如何进行?
  7. 哪些版本号必须记录?
  8. 失败报告长什么样?

延伸阅读

On this page