Files
2026-07-13 21:35:56 +08:00

159 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 步骤 3:定义评估器
**为什么需要这一步**:在完成应用的仪器化(步骤 2)之后,现在你需要将每个评估标准映射到具体的评估器——在需要的地方实现自定义评估器——以便数据集(步骤 4)可以通过名称引用它们。
---
## 3a. 将标准映射到评估器
**步骤 1c 中的每个评估标准——包括用户在提示中指定的任何维度——都必须有对应的评估器。** 如果用户要求了"事实准确性、完整性和偏见性",你就需要三个评估器(或者一个覆盖全部三者的多标准评估器)。不要静默地丢弃任何被请求的维度。优先选择那些能够衡量 `pixie_qa/00-project-analysis.md` 中确定的**困难问题/失败模式**的评估器——这些比通用的质量评估器更有价值。
对于每个评估标准,按照以下决策顺序选择评估器:
1. **内置评估器**——如果标准评估器符合该标准(事实正确性 → `Factuality`,精确匹配 → `ExactMatch`RAG 忠实度 → `Faithfulness`)。完整目录请参见 `evaluators.md`
2. **Agent 评估器**`create_agent_evaluator`)——**所有语义性、定性和应用特定标准的默认选择**。Agent 评估器将由你(编码 agent)在步骤 6 中进行评分,你将在该步骤中全面审查每个条目的追踪记录和输出。对于像"提取结果是否准确捕获了源内容?""是否存在幻觉值?"或"应用是否优雅地处理了嘈杂输入?"这样的标准,这种方法远比自动化评分有效。
3. **手动自定义评估器**——仅用于**机械性、确定性的检查**,即程序化函数可以明确给出正确答案的场景:字段存在性、正则表达式模式匹配、JSON Schema 验证、数值阈值、类型检查。**切勿将手动自定义评估器用于语义质量评估**——如果检查需要对内容是否正确、相关或完整做出**判断**,则应改用 Agent 评估器。
**区分结构性标准与语义性标准**:对于每个标准,问自己:"能否通过一个简单的程序化规则来检查,并且该规则总能给出正确答案?"如果能 → 使用手动自定义评估器。如果不能 → 使用 Agent 评估器。大多数应用特定的质量标准是语义性的,而非结构性的。
对于开放式 LLM 文本,**切勿**使用 `ExactMatch`——LLM 输出是非确定性的。
`AnswerRelevancy` 是**仅限 RAG** 的——它需要在追踪记录中存在 `context` 值。缺少该值时返回 0.0。对于一般的相关性,请使用带有明确标准的 Agent 评估器。
## 3b. 实现自定义评估器
如果任何标准需要自定义评估器,请立即实现。将自定义评估器放置在 `pixie_qa/evaluators.py` 中(如果数量较多,可放在子模块中)。
### Agent 评估器(`create_agent_evaluator`)——默认选择
对于**所有语义性、定性和基于判断的标准**,请使用 Agent 评估器。这些评估器将由你(编码 agent)在步骤 5d 中进行评分,你将在该步骤中结合完整上下文审查每个条目的追踪记录和输出——对于准确性、完整性、幻觉检测或错误处理等质量维度,这远比任何自动化方法有效。
```python
from pixie import create_agent_evaluator
extraction_accuracy = create_agent_evaluator(
name="ExtractionAccuracy",
criteria="提取的数据准确反映了源内容。所有字段都包含源中的正确值——没有幻觉值、"
"编造值或占位符值。将 final_answer 与 fetched_content "
"和 parsed_content 进行比较,以验证每个声称的事实。",
)
noise_handling = create_agent_evaluator(
name="NoiseHandling",
criteria="应用正确忽略了源中的导航装饰、样板文本、广告和其他非内容元素。"
"提取的数据仅包含与用户提示相关的信息,而不包含页面结构中的噪音。",
)
schema_compliance = create_agent_evaluator(
name="SchemaCompliance",
criteria="输出包含提示中请求的所有字段,且具有适当的类型和非空值。"
"缺失字段、必需数据的空值或包含通用占位符文本的字段表示失败。",
)
```
在数据集中通过 `filepath:callable_name`(例如 `"pixie_qa/evaluators.py:extraction_accuracy"`)引用 Agent 评估器。
`pixie test` 运行期间,Agent 评估器在控制台中显示为 `⏳`。它们将在步骤 5d 中进行评分。
**编写有效的标准**`criteria` 字符串是你在步骤 5d 中将要遵循的评分细则。请使其具体且可操作:
- **不好**"检查输出是否良好"——过于模糊,难以一致评分
- **不好**"响应应该准确"——没有说明要与什么进行比较
- **好**"将提取的字段与源 HTML/文档进行比较。每个字段必须在源中有对应的段落。标记任何无法追溯到源内容的字段值。"
- **好**:"应用应保留源文档的结构层次。如果源有章节/子章节,提取结果应反映该嵌套结构,而不是将所有内容扁平化为单一层级。"
### 手动自定义评估器——仅用于机械性检查
仅在确定性的程序化检查中使用手动自定义评估器**,即简单函数能够明确给出正确答案的场景。示例包括:字段存在性、正则匹配、JSON Schema 验证、数值范围检查、类型验证。
**不要将手动自定义评估器用于语义质量评估。** 如果检查需要对内容是否正确、相关、完整或文笔优美做出**判断**,请改用 Agent 评估器。判定标准:"正则表达式、字符串匹配或比较运算符能否完美实现这个检查?"如果不能,则属于语义性检查——请使用 Agent 评估器。
自定义评估器可以是**同步或异步函数**。将它们赋值给 `pixie_qa/evaluators.py` 中的模块级变量:
```python
from pixie import Evaluation, Evaluable
def my_evaluator(evaluable: Evaluable, *, trace=None) -> Evaluation:
score = 1.0 if "expected pattern" in str(evaluable.eval_output) else 0.0
return Evaluation(score=score, reasoning="...")
```
在数据集中通过 `filepath:callable_name` 引用:`"pixie_qa/evaluators.py:my_evaluator"`
**访问 `eval_metadata` 和捕获的数据**:自定义评估器通过 `Evaluable` 字段访问每个条目的元数据和 `wrap()` 输出:
- `evaluable.eval_metadata` —— 来自条目 `eval_metadata` 字段的字典(例如 `{"expected_tool": "endCall"}`
- `evaluable.eval_output` —— 包含所有 `wrap(purpose="output")``wrap(purpose="state")` 值的 `list[NamedData]`。每个项包含 `.name`str)和 `.value`(JsonValue)。使用下面的辅助函数按名称查找。
```python
def _get_output(evaluable: Evaluable, name: str) -> Any:
"""按名称从 eval_output 中查找 wrap 值。"""
for item in evaluable.eval_output:
if item.name == name:
return item.value
return None
def call_ended_check(evaluable: Evaluable, *, trace=None) -> Evaluation:
expected = evaluable.eval_metadata.get("expected_call_ended") if evaluable.eval_metadata else None
actual = _get_output(evaluable, "call_ended")
if expected is None:
return Evaluation(score=1.0, reasoning="eval_metadata 中无 expected_call_ended")
match = bool(actual) == bool(expected)
return Evaluation(
score=1.0 if match else 0.0,
reasoning=f"期望 call_ended={expected},实际得到 {actual}",
)
```
### ValidJSON 与字符串期望值的冲突
当数据集的 `expectation` 字段中存在值时,`ValidJSON` 会将其视为 JSON Schema。如果你的条目使用**字符串**期望值(例如用于 `Factuality`),将 `ValidJSON` 添加为数据集级别的默认评估器会导致失败——它无法将纯字符串验证为 JSON Schema。要么仅将 `ValidJSON` 应用于具有对象/布尔值期望值的条目,要么在数据集依赖字符串期望值时省略它。
## 3c. 生成评估器映射文档
将标准到评估器的映射写入 `pixie_qa/03-evaluator-mapping.md`。该文档连接了评估标准(步骤 1c)和数据集(步骤 4)。
**关键**:使用与 `evaluators.md` 参考文档中完全一致的评估器名称——内置评估器使用其短名称(例如 `Factuality``ClosedQA`),自定义评估器使用 `filepath:callable_name` 格式(例如 `pixie_qa/evaluators.py:ConciseVoiceStyle`)。
### 模板
```markdown
# 评估器映射
## 使用的内置评估器
| 评估器名称 | 覆盖的标准 | 适用范围 |
| ------------ | ---------------- | -------------------------- |
| Factuality | 事实准确性 | 所有条目 |
| ClosedQA | 答案正确性 | 含有 expected_output 的条目 |
## Agent 评估器
| 评估器名称 | 覆盖的标准 | 适用范围 | 源文件 |
| -------------------------------------------- | ------------------------ | --------- | ----------------------- |
| pixie_qa/evaluators.py:extraction_accuracy | 内容与源的准确性对照 | 所有条目 | pixie_qa/evaluators.py |
| pixie_qa/evaluators.py:noise_handling | 导航/样板文本噪音 | 所有条目 | pixie_qa/evaluators.py |
## 手动自定义评估器(仅限机械性检查)
| 评估器名称 | 覆盖的标准 | 适用范围 | 源文件 |
| -------------------------------------------- | ---------------- | --------- | ----------------------- |
| pixie_qa/evaluators.py:required_fields_present | 必填字段检查 | 所有条目 | pixie_qa/evaluators.py |
## 适用范围总结
- **数据集级别默认**(适用于所有条目):Factuality、pixie_qa/evaluators.py:extraction_accuracy
- **条目特定**(适用于子集):ClosedQA(仅适用于含有 expected_output 的条目)
```
## 输出
- `pixie_qa/evaluators.py` 中的自定义评估器实现(如果需要任何自定义评估器)
- `pixie_qa/03-evaluator-mapping.md`——标准到评估器的映射
---
> **评估器选择指南**:参见 `evaluators.md` 获取完整的内置评估器目录和 `create_agent_evaluator` 参考。
>
> **如果在实现评估器时遇到意外错误**(导入失败、API 不匹配),请先阅读 `evaluators.md` 获取权威的评估器参考,以及 `wrap-api.md` 获取 API 详细信息,然后再猜测修复方法。