> For the complete documentation index, see [llms.txt](https://levon.gitbook.io/agent-engineering/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://levon.gitbook.io/agent-engineering/09agent-ping-gu.md).

# 第 9 课：Agent Evaluation——任务验收与回归门禁

排查助手已经能执行工具、保存状态，也能留下运行记录。现在改了一段 Prompt，希望它检查得更仔细。试跑一次，回答更完整了，但值得替换原版吗？

假设配置修改任务要求只换主题，助手却顺手改了端口。换个皮肤，附赠一次端口迁移。回答写得再漂亮，也抵不过服务连不上。

需要让新旧版本做同一组任务，检查完成了什么、破坏了什么。**固定试卷、明确答案、重复运行、比较结果**，就是本课理解 **Agent Evaluation（Agent 评估）** 的入口。上一课帮助找出一次运行卡在哪里；这一课用任务证据判断改动是否值得保留。

## 1. Task 与 Trial：验收条件和测试覆盖

先把“做好配置修改”说具体：读取 `config.json`，把 theme 从 light 改成 dark，其他字段和值保持不变，并正常结束、交付结果。

```
修改前：{"theme":"light","port":3000}
正确结果：{"theme":"dark","port":3000}
错误结果：{"theme":"dark","port":8080}
```

一个包含初始输入、任务要求和成功条件的测试任务，叫 **Task**。实际做一遍，叫一次 **Trial**。两道题各做三次，这个版本就有两个 Task、六个 Trial。换题检查覆盖面，同题重复检查稳定性，不能互相替代。\[1]

对排查助手，可以从依赖它完成的事情中选题：

| 想检查的能力  | 任务与验收依据                           |
| ------- | --------------------------------- |
| 根据证据诊断  | 给定故障日志和源码，检查结论是否指向实际出错位置、有没有编造依据  |
| 保留非目标配置 | 换一个端口，再增加 debug 字段，仍只允许修改主题       |
| 受限写入    | 批准写入时检查文件；拒绝写入时检查没有产生写操作，也没有声称已写好 |
| 保留历史要求  | 先提出“不要改端口”，几轮交互后再要求修改，检查原约束是否仍被遵守 |

这是选题示例，不是本章已测成绩。只出拒绝题，一个永远拒绝的 Agent 也可能全对；只用反复调试过的题，又可能看不出陌生输入下的问题。应同时覆盖正常完成和重要边界，并留一些未参与调试的同类任务。

希望新增的能力用于**能力评估**；应用已经依赖的行为用于**回归评估**，检查它有没有退步。新能力稳定并成为应用承诺后，也可以进入回归集。

前几课的确定性检查继续保留。例如“压缩不能拆散 Tool Call 与 Result”检查运行时规则；真实模型在压缩后能否完成任务，检查的是实际表现。两类通过数不能混加成模型成功率。

## 2. Grader：检查实际产物与行为

负责按成功条件检查结果的程序叫 **Grader（评分器）**。配置题先读实际文件，再和根据原始配置得到的答案比较：

```python
import json

before = json.loads('{"theme":"light","port":3000}')
actual = json.loads('{"theme":"dark","port":8080}')

expected = before.copy()
expected["theme"] = "dark"

print(actual == expected)
```

输出为 `False`。代码只改预期中的 theme，其他字段沿用 before，因此不需要把所有题的端口写死成 8080。解析 JSON 后，字段顺序、空格和换行不影响比较；完整评分器还要检查文件缺失、格式与字段类型，不能把布尔值 false 和数字 0 混为同一配置。

原始输入和评分依据要在运行前保存，并放在 Agent 无权修改的位置。保护来自执行权限，文件放到工作区外仍不够；若 Shell 能走出去改答案，考生就兼任了出题人。

评分方法随任务变化：配置题比较字段，CSV 汇总从原始数据计算答案，代码修复运行受保护的测试。诊断报告、总结等开放输出，可以由人工或模型按明确标准判断。让模型评分时，要先用人工确认过的样例校准，检查判断不一致的地方。\[1]\[2]

有多种合法解法时，不要无故要求工具顺序逐步相同。通常先验收产物与重要行为；题目确实要求“写入前必须批准”，才把这个顺序作为硬条件。\[8]

评分器也需要自己的正确例、错误例和等价例。正确结果应通过，误改端口应失败，只调整空格应通过。“评分程序没报错”和“评分程序判对了”是两件事。

## 3. Evaluation Harness：独立运行与证据

组织评测的程序要准备环境、调用 Agent、保存产物并评分，通常叫 **Evaluation Harness**。它在被测 Agent 外面；前几课的 Agent Harness 则控制内部模型与工具循环。

```
准备初始文件和新会话
-> 运行被测 Agent：模型、工具与执行规则照常工作
-> 保存实际产物、会话及运行结果
-> 调用 Grader，留下本次 Trial 的成绩和原因
```

每次 Trial 都重新准备初始状态。否则上一轮已经改好的文件留着，下一轮什么也不做，就可能被判成功。评测环境需要独立，业务运行期间需要延续状态；这两种需求不冲突。

评分结果保留三种情况：

| 评分     | 含义           | 例子                |
| ------ | ------------ | ----------------- |
| passed | 检查完成，产物满足要求  | 主题正确，其他配置未变       |
| failed | 检查完成，产物不满足要求 | 端口被删除，或输出 JSON 损坏 |
| error  | 评分没有完成，成绩未知  | 评分代码异常，或可信原始数据丢失  |

评分故障不能算成 Agent 做错，也不能删掉这份记录。修好评分器后，如果证据完整、成功条件未变，可以直接对原产物补评。若修改了标准，新旧版本都要按新标准评价；若修改了 Agent，则需要重新运行。

运行状态另存。例如，文件已经写对，Agent 却在最终回答前中断：产物 passed，运行 error。这道题要求正常结束并交付，所以还不能算完整成功。

下面三份假设报告说明怎样统计；`run` 表示运行状态，`grade` 表示产物评分：

```python
reports = [
    {"run": "completed", "grade": "passed"},
    {"run": "completed", "grade": "failed"},
    {"run": "error", "grade": "passed"},
]

successful = 0
for report in reports:
    if report["run"] == "completed" and report["grade"] == "passed":
        successful += 1

print(f"{successful}/{len(reports)}")
```

输出为 `1/3`，而不是文件评分的 `2/3`。若题目还要求回答与产物一致，就要再核对回答；当前配套程序没有自动判断自然语言回答是否完全属实，不能把这段统计当成它已经检查过。

预设模型回复能验证评测程序怎样处理失败，不能证明真实模型会作出那些选择。文件、会话和执行账本已可提供基本证据，不必先接入完整 Trace 平台。开发期的“离线评测”也可能调用云端模型，离线不等于断网。\[3]

## 4. Baseline 与 Candidate：可比条件和结果归因

拿当前版本作参照，叫 **Baseline（基线）**；准备比较的改动版本叫 **Candidate（候选）**。两个名字本身没有证据作用，必须记下实际代码、Prompt、模型配置、题集、评分器与运行预算。

研究 Prompt 时，模型、题目和预算应保持一致。研究换模型时，模型才是要改变的变量。多项配置一起改变也能比较整体方案，但不能把收益全部归给其中一项。

本书归档过一组真实 CSV 实验，检验的是“写入后读回核对”这条 Prompt，而非更换模型。输入数量为 2、3、7；任务要求把总数 12 写进 JSON，保留原始 CSV 并正常结束。两版使用同一模型 mimo-v2.5，各做三次，每次最多四次模型请求：

| 版本              | 文件正确 | 完整成功 |
| --------------- | ---- | ---- |
| 原版              | 3/3  | 3/3  |
| 增加“写完后读回核对”的候选版 | 2/3  | 0/3  |

根据当时的运行核验，候选前两次都写对了文件，却走到了这样的结尾：

```
第 1 次模型请求：申请读取输入
第 2 次模型请求：申请写入结果
第 3 次模型请求：申请读回结果
第 4 次模型请求：再次申请读取输入
请求次数用完，无法继续生成最终回答
```

工具仍执行了第四次读取，但没有第五次模型请求可用。文件写对了，连一句“做完了”的请求额度都没留下。耗尽的是**请求次数**，不是 Token 上下文。

这组记录能支持哪些判断？逐条对照：

| 观察                          | 能说明                  | 不能说明                  |
| --------------------------- | -------------------- | --------------------- |
| 候选前两次写对文件，却在请求次数用完时没有回答     | “读回核对”可能引出重复读取，值得继续查 | 所有失败都由这条 Prompt 造成    |
| 第三次记录了 `APIConnectionError` | 这次 Trial 没有完成        | Prompt 有错             |
| 候选平均耗时更短                    | 无                    | 候选更高效：提前失败也会缩短耗时      |
| 两版各做三次                      | 本次对照条件下的结果           | 长期可靠；小样本要考虑统计不确定性\[5] |

所以我先保留原版，再检查重复读取是否稳定出现。比较时按任务类别看结果，再结合完成质量看时间与费用：平均分可能掩盖某项关键能力下降，工具次数也不等于 Token 或实际费用，资源与网络环境要随报告记录。\[4]

如果打算增加请求预算，应按新条件重跑两个版本。不能看到候选失败，就临时放宽要求给旧成绩补一个通过。

## 5. Regression Gate：把回归要求接入发布

**Regression Gate（回归门禁）** 根据回归评估的证据，决定候选改动能否继续发布。评估负责出成绩，门禁负责回答“这份成绩能不能放行”。考了 90 分，不代表那道误删数据的题可以当没看见。

先定规则，再运行。例如，固定回归题要求完整通过，未授权写入出现一次就拦截，评分故障或证据不全则等待补齐。自然语言质量、时间和费用按预定标准比较，不能用其他题的高分抵消安全违例。

“解决新问题”和“保住旧行为”要一起检查。SWE-bench 的代码修复评分就同时检查原来失败的测试能否通过，以及原来通过的测试是否仍然通过。\[6]

沿用第 3 节的假设报告，最小的全通过判定可以写成：

```python
def can_release(reports):
    if not reports:
        return False
    for report in reports:
        if report["run"] != "completed" or report["grade"] != "passed":
            return False
    return True

if can_release(reports):
    print("通过")
else:
    print("拦截")
```

输出为 `拦截`。产物失败、运行中断都不能放行，没有报告也不能通过。这里仅展示已核对题目、版本和数量之后的判定核心；真实门禁还要发现漏跑、重复记录、成绩汇总不一致等问题。

对 CSV 归档执行这项规则，会同时得到两个结论：

```
比较条件：comparable，可以比较这两批报告
回归门禁：blocked，候选没有全部完整通过
```

网络故障未必说明候选设计有错，但失败记录也不能提供成功验收。应保留异常原因，决定补测还是修改，而不是把“可以比较”误读成“允许发布”。

门禁程序返回失败，还需要发布流程遵守这个信号。最终发布的代码、Prompt 和模型配置必须与受测版本一致；拿旧报告给后来改过的系统背书没有意义。\[7]

测试没有观察到越权，也不证明永远安全。第 7 课的执行权限和 Sandbox 仍要在每次运行中强制约束。当前配套门禁只消费保存的报告，没有自动发布或核验当前工作树，更不是完整安全认证。

以后调整 Context、工具或模型，先选出会受影响的任务，再运行、检查、比较。真实使用中新发现的故障进入回归集。下一课讨论 Workflow 与编排时，这些验收条件会继续用来判断：流程该结束、返工，还是交给人处理？

## 本课实践

[进入第 9 课实践](https://github.com/unix2dos/agent-engineering-book/tree/main/practice/lesson-09/README.md)：补一项评测设计，根据已有报告作出有证据、有边界的版本判断。说明中列出必做步骤、完成标准和选做内容。

## 资料

1. [Anthropic：Demystifying evals for AI agents](https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents)
2. [Inspect：Scorers](https://inspect.aisi.org.uk/scorers.html)
3. [LangSmith：Evaluation](https://docs.langchain.com/langsmith/evaluation)
4. [Anthropic：基础设施噪声研究](https://www.anthropic.com/engineering/infrastructure-noise)
5. [NIST：两组比例比较](https://www.itl.nist.gov/div898/software/dataplot/refman2/auxillar/diffprop.htm)
6. [SWE-bench：评分实现](https://www.swebench.com/SWE-bench/api/harness/#swebench.harness.grading.get_resolution_status)
7. [Promptfoo：CI/CD 与质量门禁](https://www.promptfoo.dev/docs/integrations/ci-cd/)
8. [LangSmith：结果、单步与过程评估](https://docs.langchain.com/langsmith/evaluation-approaches)
9. [实测条件、报告与实现边界](https://github.com/unix2dos/agent-engineering-book/tree/main/research/09-evaluation-source-verification.md)。第 4 节的完整成功只按“运行完成且文件评分通过”统计，归档只覆盖这项 CSV 任务，不证明排查助手的诊断能力或全部权限行为；重新读取历史报告，不等于现在的模型又考了一遍。配套比较器限定同一模型、同一任务和相同预算的 Prompt／Runtime 对照，等量样本是为简化对照，不是通用统计要求。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://levon.gitbook.io/agent-engineering/09agent-ping-gu.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
