第 26 课:Eval 驱动开发 — 衡量 AI 行为

16 阅读8分钟

所属阶段:第五阶段「进阶能力」(第 23-27 课) 前置条件:第 25 课(持续学习) 本课收获:设计并运行一次 Eval,理解 pass@k 指标体系


一、本课概述

上一课你学到了如何让 AI "学习"。但学习的效果如何衡量?一个 Agent 配置调整后,是变好了还是变差了?

传统软件有单元测试来验证功能正确性。AI Agent 需要的不是单元测试,而是 Eval(评估)

  1. EDD 循环 — Eval 驱动开发的完整流程
  2. pass@k 指标 — 理解 AI 行为的概率性质
  3. Eval 类型 — Checkpoint-based、Continuous、Agent-vs-Agent
  4. benchmark Skill — 性能基准与回归检测
  5. verification-loop Skill — 验证闭环

Eval 是连接"AI 能力"和"工程可靠性"的桥梁。


二、为什么需要 Eval

2.1 传统测试 vs AI Eval

维度传统单元测试AI Eval
确定性相同输入 → 相同输出相同输入 → 可能不同输出
通过标准全部通过 = 正确通过率达标 = 可靠
重复次数运行 1 次即可需要多次运行取统计
评判方式精确匹配语义评判(可能需要另一个 LLM)
失败原因Bug可能是 Prompt、模型、上下文、温度...

2.2 AI 行为的概率性

一个关键认知:AI Agent 的行为是概率性的,不是确定性的。

同一个 Prompt + 同一个 Agent + 同一个模型,运行 10 次可能得到 7 次正确、2 次部分正确、1 次错误。

这意味着:

  • 你不能只运行一次就下结论
  • "通过率"比"通过/不通过"更有意义
  • 你需要 pass@k 这样的统计指标

三、EDD 循环

Eval 驱动开发(Eval-Driven Development,EDD)是一个迭代循环:

┌──────────────────────────────────────────┐
│                EDD 循环                   │
│                                          │
│  1. 定义评估标准                          │
│     │ 什么算"通过"?什么算"失败"?       │
│     ↓                                    │
│  2. 运行 Eval                            │
│     │ 多次运行,收集结果                  │
│     ↓                                    │
│  3. 分析 pass@k                          │
│     │ 计算通过率,识别薄弱环节            │
│     ↓                                    │
│  4. 调整配置                              │
│     │ 修改 Prompt / Skill / Agent / 模型 │
│     ↓                                    │
│  5. 重新运行 Eval                        │
│     │ 验证改进效果                        │
│     ↓                                    │
│  6. 达标?                               │
│     │                                    │
│     ├── 否 → 回到步骤 4                  │
│     └── 是 → 部署                        │
│                                          │
└──────────────────────────────────────────┘

3.1 定义评估标准

评估标准应该是具体的、可衡量的

## Eval: Code Reviewer Agent

### 测试用例 1:检测未处理的空指针
- 输入:包含空指针解引用的 Java 代码
- 期望:Agent 识别出空指针风险并给出修复建议
- Pass 条件:输出中包含 "null check" 或 "NullPointerException"

### 测试用例 2:检测 SQL 注入
- 输入:包含字符串拼接 SQL 的 Python 代码
- 期望:Agent 识别出 SQL 注入风险
- Pass 条件:输出中包含 "parameterized" 或 "SQL injection"

### 测试用例 3:不误报安全代码
- 输入:已经使用参数化查询的代码
- 期望:Agent 不报告 SQL 注入
- Pass 条件:输出中不包含 "SQL injection"

3.2 好的评估标准特征

特征说明反例
具体明确的 pass/fail 条件"代码质量应该好"
可自动判断可以用程序检查需要人工阅读评判
独立测试用例之间不互相依赖"测试 2 依赖测试 1 的输出"
覆盖正反面既测能力也测不误报只测能检测出问题

四、pass@k 指标体系

4.1 三种 pass@k 指标

指标定义衡量什么严格程度
pass@1单次运行通过率可靠性中等
pass@55 次中至少 1 次通过极限能力宽松
pass^kk 次全部通过一致性最严格

4.2 直观理解

假设一个 Agent 运行 10 次,结果如下:

运行 1:  通过
运行 2:  通过
运行 3:  失败
运行 4:  通过
运行 5:  通过
运行 6:  失败
运行 7:  通过
运行 8:  通过
运行 9:  通过
运行 10:  失败
指标计算结果
pass@17/1070% — 单次运行有 70% 概率成功
pass@5至少 1 次通过的概率99.8% — 跑 5 次几乎肯定能成功
pass^5全部 5 次通过的概率16.8% — 连续 5 次都成功很难

4.3 选择哪个指标

场景推荐指标原因
代码审查(可以人工兜底)pass@1 ≥ 80%大部分时候对就行
安全扫描(不能漏报)pass@5 ≥ 99%运行多次,确保不遗漏
自主部署(无人监督)pass^3 ≥ 95%必须极其一致
探索性任务(找方案)pass@5 ≥ 60%只要有一次找到就好

五、Eval 类型

5.1 Checkpoint-based Eval

在开发流程的关键节点运行评估:

代码变更 → Eval(代码审查 Agent 能否检测已知问题?)
                    ↓
配置修改 → Eval(修改后的 Agent 表现是否不低于之前?)
                    ↓
模型升级 → Eval(新模型下 Agent 表现是否不低于之前?)

用途:验证配置变更不会导致退化。

5.2 Continuous Eval

持续运行的评估,类似于持续集成:

每天自动运行一组 Eval 用例
    ↓
收集 pass@k 趋势数据
    ↓
发现退化时自动告警

用途:监控 Agent 行为的长期趋势。

5.3 Agent-vs-Agent Eval

用一个 Agent 评估另一个 Agent 的输出:

被评估 Agent:生成代码审查报告
    ↓
评估 Agent(Evaluator):判断报告是否正确
    ↓
对比人类标注的标准答案
    ↓
计算 Evaluator 的一致性

ECC 提供了 agent-eval Skill 来支持这种模式。

注意:Agent-vs-Agent 评估本身也有不确定性。评估 Agent 可能误判。所以需要用人类标注的"黄金答案"来校准评估 Agent。


六、benchmark Skill

ECC 的 benchmark Skill 提供了性能基准和回归检测能力:

6.1 核心功能

功能说明
基准建立在已知良好状态下运行 Eval,记录基线
回归检测变更后重新运行,对比基线
趋势分析多次运行结果的趋势图
阈值告警pass@k 低于阈值时告警

6.2 使用示例

## 建立基准

1. 确保当前 Agent 配置是"已知良好"的状态
2. 运行 benchmark Skill 建立基线
3. 记录 pass@1、pass@5 值

## 检测回归

1. 修改 Agent 配置(Prompt、模型、Skill 等)
2. 使用相同的 Eval 用例重新运行
3. 对比新结果与基线
4. 如果 pass@k 下降超过 5%,调查原因

七、verification-loop Skill

verification-loop Skill 提供了一个自动化的验证闭环:

执行任务
    ↓
自动验证结果(测试、Lint、类型检查、安全扫描)
    ↓
    ├── 全部通过 → 完成
    └── 有失败 → 自动修复 → 重新验证(最多 N 轮)

7.1 与 Eval 的关系

维度verification-loopEval
时机开发过程中(实时)开发完成后(事后)
目标确保当前任务正确衡量 Agent 整体能力
频率每次任务定期或变更后
反馈自动修复指导配置调整

两者是互补的:verification-loop 保证单次任务质量,Eval 保证 Agent 长期可靠性。


八、设计 Eval 的最佳实践

8.1 Eval 设计清单

#要点说明
1覆盖正面和负面既测"能检测出"也测"不误报"
2用例数量 ≥ 10少于 10 个统计意义不足
3明确 pass/fail 条件可以用字符串匹配或语义判断
4运行次数 ≥ 5取统计平均,不依赖单次结果
5设定基线知道"现在有多好"才能判断"变好还是变差"
6固定随机种子如果可能,减少不确定性来源
7记录环境模型版本、温度、Prompt 版本

8.2 Eval 结果分析模板

## Eval Report: [Agent Name] - [Date]

### 环境
- Model: claude-sonnet-4-6
- Temperature: 0
- Prompt version: v2.3
- Eval cases: 15
- Runs per case: 5

### 结果
| 指标 | 值 | 基线 | 变化 |
|------|----|------|------|
| pass@1 | 82% | 78% | +4% ✅ |
| pass@5 | 98% | 96% | +2% ✅ |
| pass^3 | 65% | 60% | +5% ✅ |

### 薄弱环节
- 用例 #7(复杂嵌套代码):pass@1 仅 40%
- 用例 #12(多文件变更):pass@1 仅 60%

### 下一步
- 针对用例 #7 增加 Skill 指导
- 针对用例 #12 考虑拆分为子任务

九、本课练习

练习 1:设计 3 个 Eval 用例(20 分钟)

这是本课最重要的练习。

为一个你使用的 Agent(如 code-reviewer)设计 3 个评估用例。每个用例包括:

字段内容
测试名称描述性名称
输入提供给 Agent 的代码或问题
期望行为Agent 应该做什么
Pass 条件具体的通过标准
Fail 条件什么情况算失败

练习 2:理解 pass@k(10 分钟)

一个 Agent 运行 20 次,有 14 次通过。计算:

  • pass@1 = ?
  • 如果 pass@5 的目标是 ≥ 99%,这个 Agent 达标了吗?
  • 如果 pass^3 的目标是 ≥ 50%,这个 Agent 达标了吗?

(提示:pass@5 = 1 - (失败率)^5 = 1 - 0.3^5;pass^3 = (通过率)^3 = 0.7^3)

练习 3:EDD 循环实践(15 分钟)

选择一个简单的任务(如"让 Claude 把 JSON 转换为 YAML"),执行一个简化的 EDD 循环:

  1. 定义 pass 条件(输出是合法的 YAML)
  2. 运行 3 次
  3. 记录 pass@1
  4. 如果不理想,调整 Prompt 后再运行 3 次
  5. 对比前后结果

练习 4(选做):Agent-vs-Agent

思考:如果让一个 Agent 来判断另一个 Agent 的代码审查质量,你会怎么设计评估 Prompt?评估 Agent 自身的准确性怎么衡量?


十、本课小结

你应该记住的内容
EDD 循环定义标准 → 运行 Eval → 分析 pass@k → 调整 → 重跑 → 达标 → 部署
pass@1单次通过率,衡量日常可靠性
pass@5至少 1 次通过,衡量极限能力
pass^k全部通过,最严格的一致性要求
Eval 类型Checkpoint(变更验证)、Continuous(长期监控)、Agent-vs-Agent

十一、下节预告

第 27 课:Agent 工程与 LLM 成本优化

Eval 告诉你 Agent 有多好,但"好"不能不计成本。下节课学习 Agent Harness 的构建原理(Action Space、Observation 格式化、Reward Signal),以及如何用 cost-aware-llm-pipeline Skill 按复杂度路由模型、追踪预算、优化成本。

预习建议:浏览 skills/agent-harness-construction/SKILL.mdskills/cost-aware-llm-pipeline/SKILL.md