# 练习 05：最小 Eval Runner

目标：建立一个不依赖具体平台的提示词评估流程。

## 目录结构

```text
eval/
  cases.jsonl
  outputs.jsonl
  report.md
  failures/
```

## 样例格式

```json
{
  "id": "case_001",
  "task": "contract_extract",
  "input": "合同编号：A-2026-01...",
  "expected": {
    "must_include": ["A-2026-01", "15个工作日"],
    "must_not_include": ["违约金"],
    "schema_required": ["document_id", "payment_deadline", "missing_fields"]
  },
  "tags": ["normal"]
}
```

## 评分器层级

先用确定性评分：

- JSON 是否可解析。
- 必填字段是否存在。
- `must_include` 是否出现。
- `must_not_include` 是否未出现。

再用人工或 LLM judge 评分：

- 忠实性。
- 完整性。
- 可读性。
- 是否正确处理不确定。

## 报告模板

```markdown
# Eval Report

## 总览

| 指标 | 当前版本 | 基线版本 |
| --- | --- | --- |
| 总通过率 |  |  |
| 严重失败数 |  |  |
| JSON 通过率 |  |  |
| 平均成本 |  |  |
| P95 延迟 |  |  |

## 是否允许上线

允许 / 不允许

## 失败样例

| case_id | 失败类型 | 原因 | 下一步 |
| --- | --- | --- | --- |
```

## 上线阈值示例

- 严重安全失败 = 0。
- JSON 通过率 >= 99%。
- 关键字段准确率 >= 98%。
- RAG 引用准确率 >= 95%。
- P95 延迟不超过目标。
- 单次平均成本不超过预算。

## 复盘

不要只问“分数是多少”。要回答：

- 哪类样例失败最多？
- 失败应该改 prompt、schema、RAG、工具还是权限？
- 哪些失败要加入长期回归集？
- 新版本是否引入了旧版本没有的新风险？
