17 KiB
测试 API 参考
自动从 pixie 源代码文档字符串生成。 请勿手动编辑——请运行
uv run python scripts/generate_skill_docs.py。
pixie.evals —— LLM 应用程序的评估框架。
公开 API: - Evaluation —— 单次评估器运行的结果数据类 - Evaluator —— 评估可调用对象的协议 - evaluate —— 针对一个可评估对象运行一个评估器 - run_and_evaluate —— 评估来自 MemoryTraceHandler 的跨度 - assert_pass —— 带通过/失败条件的批量评估 - assert_dataset_pass —— 加载数据集并运行 assert_pass - EvalAssertionError —— 当 assert_pass 失败时抛出 - capture_traces —— 用于内存中追踪捕获的上下文管理器 - MemoryTraceHandler —— 收集跨度的 InstrumentationHandler - ScoreThreshold —— 可配置的通过标准 - last_llm_call / root —— 追踪到可评估对象的辅助函数 - DatasetEntryResult —— 单个数据集条目的评估结果 - DatasetScorecard —— 带非统一评估器的按数据集评分卡 - generate_dataset_scorecard_html —— 将评分卡渲染为 HTML - save_dataset_scorecard —— 将评分卡 HTML 写入磁盘
预置评估器(autoevals 适配器): - AutoevalsAdapter —— 任意 autoevals Scorer 的通用包装器 - LevenshteinMatch —— 编辑距离字符串相似度 - ExactMatch —— 精确值比较 - NumericDiff —— 归一化数值差异 - JSONDiff —— 结构化 JSON 比较 - ValidJSON —— JSON 语法 / Schema 验证 - ListContains —— 列表重叠 - EmbeddingSimilarity —— 嵌入余弦相似度 - Factuality —— LLM 事实准确性检查 - ClosedQA —— 闭卷问答评估 - Battle —— 两两对比 - Humor —— 幽默检测 - Security —— 安全漏洞检查 - Sql —— SQL 等价性 - Summary —— 摘要质量 - Translation —— 翻译质量 - Possible —— 可行性检查 - Moderation —— 内容审核 - ContextRelevancy —— RAGAS 上下文相关性 - Faithfulness —— RAGAS 忠实度 - AnswerRelevancy —— RAGAS 答案相关性 - AnswerCorrectness —— RAGAS 答案正确性
数据集 JSON 格式
数据集是一个 JSON 对象,包含以下顶层字段:
{
"name": "customer-faq",
"runnable": "pixie_qa/run_app.py:AppRunnable",
"evaluators": ["Factuality"],
"entries": [
{
"input_data": { "question": "Hello" },
"description": "Basic greeting",
"eval_input": [{ "name": "input", "value": "Hello" }],
"expectation": "A friendly greeting that offers to help",
"evaluators": ["...", "ClosedQA"]
}
]
}
条目结构
所有字段均在每个条目上作为顶层字段(扁平结构——无嵌套):
entry:
├── input_data (必需)—— Runnable.run() 的参数
├── eval_input (可选)—— {"name": ..., "value": ...} 对象的列表(默认:[])
├── description (必需)——测试用例的人类可读标签
├── expectation (可选)——用于基于比较的评估器的参考值
├── eval_metadata (可选)——用于自定义评估器的额外逐条目数据
└── evaluators (可选)——此条目的评估器名称
字段参考
runnable(必需):驱动评估期间应用的Runnable子类的filepath:ClassName引用。evaluators(数据集级别,可选):默认评估器名称——应用于每个未声明自己的evaluators的条目。entries[].input_data(必需):作为 Pydantic 模型传递给Runnable.run()的关键字参数。键必须与run(args: T)中使用的 Pydantic 模型的字段匹配。entries[].description(必需):测试用例的人类可读标签。entries[].eval_input(可选,默认[]):{"name": ..., "value": ...}对象的列表。用于填充包装输入注册表——应用中的wrap(purpose="input")调用返回按name键控的注册表值。运行器在构建Evaluable时会自动前置input_data。entries[].expectation(可选):针对基于比较的评估器的简洁预期描述。应描述正确输出的样子,而不是逐字复制输出。对追踪使用pixie format以查看实际输出形状,然后编写更短的描述。entries[].eval_metadata(可选):用于自定义评估器的额外逐条目数据——例如,预期的工具名称、布尔标志、阈值。在评估器中通过evaluable.eval_metadata访问。entries[].evaluators(可选):行级别的评估器覆盖。规则:- 省略 → 条目继承数据集级别的
evaluators。 ["...", "ClosedQA"]→ 数据集默认值 加上 ClosedQA。["OnlyThis"](无"...")→ 仅 OnlyThis,不包含默认值。
- 省略 → 条目继承数据集级别的
评估器名称解析
在数据集 JSON 中,评估器名称按如下方式解析:
- 内置名称(裸名称,如
"Factuality"、"ExactMatch")会自动解析为pixie.{Name}。 - 自定义评估器使用
filepath:callable_name格式(例如"pixie_qa/evaluators.py:my_evaluator")。 - 自定义评估器引用指向模块级别的可调用对象——类(自动实例化)、工厂函数(如果零参数则调用)、评估器函数(按原样使用)或预实例化的可调用对象(例如
create_llm_evaluator的结果——按原样使用)。
CLI 命令
| 命令 | 描述 |
|---|---|
pixie test [path] [-v] [--no-open] |
对数据集文件运行评估测试 |
pixie dataset create <name> |
创建一个新的空数据集 |
pixie dataset list |
列出所有数据集 |
pixie dataset save <name> [--select MODE] |
将跨度保存到数据集中 |
pixie dataset validate [path] |
验证数据集 JSON 文件 |
pixie analyze <test_run_id> |
生成分析和建议 |
类型
Evaluable
class Evaluable(TestCase):
eval_output: list[NamedData] # wrap(purpose="output") + wrap(purpose="state") 值
# 继承自 TestCase:
# eval_input: list[NamedData] # 来自数据集条目中的 eval_input
# expectation: JsonValue | _Unset # 来自数据集条目中的 expectation
# eval_metadata: dict[str, JsonValue] | None # 来自数据集条目中的 eval_metadata
# description: str | None
评估器的数据载体。使用实际输出扩展 TestCase。
eval_input—— 从条目的eval_input字段加上input_data(由运行器前置)填充的list[NamedData]。始终至少包含一个条目。eval_output—— 包含运行期间捕获的所有wrap(purpose="output")和wrap(purpose="state")值的list[NamedData]。每个条目都有.name(str)和.value(JsonValue)。使用_get_output(evaluable, "name")按名称查找。eval_metadata—— 来自条目eval_metadata字段的dict[str, JsonValue] | Noneexpected_output—— 来自数据集的预期文本(如果未提供则为UNSET)
属性:
eval_input:命名输入数据项(来自数据集 + 运行器前置的 input_data)。始终非空。
eval_output:命名输出数据项(来自运行期间的 wrap 调用)。
每个条目都有 .name(str)和 .value(JsonValue)。
包含所有 wrap(purpose="output") 和 wrap(purpose="state") 值。
eval_metadata:补充元数据(不存在时为 None)。
expected_output:用于评估的预期/参考输出。
默认为 UNSET(未提供)。可被显式
设置为 None,表示"没有预期输出"。
测试时 wrap() 如何映射到 Evaluable 字段
当 pixie test 运行数据集条目时,应用中的 wrap() 调用会填充评估器接收的 Evaluable:
应用代码中的 wrap() 调用 |
Evaluable 字段 | 类型 | 在评估器中的访问方式 |
|---|---|---|---|
wrap(data, purpose="input", name="X") |
eval_input |
list[NamedData] |
从数据集条目的 eval_input 预填充 |
wrap(data, purpose="output", name="X") |
eval_output |
list[NamedData] |
_get_output(evaluable, "X") —— 参见下面的辅助函数 |
wrap(data, purpose="state", name="X") |
eval_output |
list[NamedData] |
_get_output(evaluable, "X") —— 与输出相同的列表 |
(来自数据集条目 expectation) |
expected_output |
str | None |
evaluable.expected_output |
(来自数据集条目 eval_metadata) |
eval_metadata |
dict | None |
evaluable.eval_metadata |
关键理解:purpose="output" 和 purpose="state" 的 wrap 值最终都作为 NamedData 条目进入 eval_output。没有单独的 captured_output 或 captured_state 字典。使用下面的辅助函数按 wrap 名称查找值:
def _get_output(evaluable: Evaluable, name: str) -> Any:
"""Look up a wrap value by name from eval_output."""
for item in evaluable.eval_output:
if item.name == name:
return item.value
return None
eval_metadata 用于向评估器传递额外的逐条目数据,这些数据既不是输入数据也不是输出——例如,预期的工具名称、布尔标志、阈值。定义为条目的顶层字段,通过 evaluable.eval_metadata 访问。
完整的自定义评估器示例(工具调用检查 + 数据集条目):
from pixie import Evaluation, Evaluable
def _get_output(evaluable: Evaluable, name: str) -> Any:
"""Look up a wrap value by name from eval_output."""
for item in evaluable.eval_output:
if item.name == name:
return item.value
return None
def tool_call_check(evaluable: Evaluable, *, trace=None) -> Evaluation:
expected = evaluable.eval_metadata.get("expected_tool") if evaluable.eval_metadata else None
actual = _get_output(evaluable, "function_called")
if expected is None:
return Evaluation(score=1.0, reasoning="No expected_tool specified")
match = str(actual) == str(expected)
return Evaluation(
score=1.0 if match else 0.0,
reasoning=f"Expected {expected}, got {actual}",
)
对应的数据集条目:
{
"input_data": { "user_message": "I want to end this call" },
"description": "User requests call end after failed verification",
"eval_input": [{ "name": "user_input", "value": "I want to end this call" }],
"expectation": "Agent should call endCall tool",
"eval_metadata": {
"expected_tool": "endCall",
"expected_call_ended": true
},
"evaluators": ["...", "pixie_qa/evaluators.py:tool_call_check"]
}
Evaluation
Evaluation(score: 'float', reasoning: 'str', details: 'dict[str, Any]' = <factory>) -> None
单个评估器应用于单个测试用例的结果。
属性: score:介于 0.0 和 1.0 之间的评估分数。 reasoning:人类可读的解释(必需)。 details:任意的 JSON 可序列化元数据。
ScoreThreshold
ScoreThreshold(threshold: 'float' = 0.5, pct: 'float' = 1.0) -> None
通过标准:在所有评估器上,pct 比例的输入必须得分 >= threshold。
属性: threshold:单次评估必须达到的最低分数。 pct:必须通过的测试用例输入比例(0.0–1.0)。
评估函数
pixie.run_and_evaluate
pixie.run_and_evaluate(evaluator: 'Callable[..., Any]', runnable: 'Callable[..., Any]', eval_input: 'Any', *, expected_output: 'Any' = <object object at 0x7788c2ad5c80>, from_trace: 'Callable[[list[ObservationNode]], Evaluable] | None' = None) -> 'Evaluation'
在捕获追踪的同时运行 runnable(eval_input),然后进行评估。
结合了 _run_and_capture 和 evaluate 的便捷包装器。
runnable 仅被调用一次。
参数: evaluator:评估器可调用对象(同步或异步)。 runnable:要测试的应用函数。 eval_input:传递给 runnable 的单个输入。 expected_output:合并到 evaluable 中的可选预期值。 from_trace:用于从追踪树中选择特定跨度进行评估的可选可调用对象。
返回:
Evaluation 结果。
抛出: ValueError:如果执行期间未捕获到任何跨度。
pixie.assert_pass
pixie.assert_pass(runnable: 'Callable[..., Any]', eval_inputs: 'list[Any]', evaluators: 'list[Callable[..., Any]]', *, evaluables: 'list[Evaluable] | None' = None, pass_criteria: 'Callable[[list[list[Evaluation]]], tuple[bool, str]] | None' = None, from_trace: 'Callable[[list[ObservationNode]], Evaluable] | None' = None) -> 'None'
在多个输入上对 runnable 运行评估器。
对于每个输入,通过 _run_and_capture 运行一次 runnable,
然后通过 asyncio.gather 并发地使用每个评估器进行评估。
结果矩阵的形状为 [eval_inputs][evaluators]。
如果未满足通过标准,则抛出携带该矩阵的 :class:EvalAssertionError。
当提供了 evaluables 时,行为取决于每个条目是否已填充了 eval_output:
- eval_output 为 None —— 通过
run_and_evaluate调用runnable以从追踪生成输出,并且来自 evaluable 的expected_output会合并到结果中。 - eval_output 不为 None —— 直接使用该 evaluable(该条目不调用 runnable)。
参数:
runnable:要测试的应用函数。
eval_inputs:输入列表,每个都传递给 runnable。
evaluators:评估器可调用对象列表。
evaluables:可选的 Evaluable 项列表,每个输入对应一个。
当提供时,它们的 expected_output 会被转发到
run_and_evaluate。必须与 eval_inputs 具有相同的长度。
pass_criteria:接收结果矩阵,返回
(passed, message)。默认为 ScoreThreshold()。
from_trace:可选的跨度选择器,转发到
run_and_evaluate。
抛出: EvalAssertionError:当未满足通过标准时。 ValueError:当 evaluables 长度与 eval_inputs 不匹配时。
pixie.assert_dataset_pass
pixie.assert_dataset_pass(runnable: 'Callable[..., Any]', dataset_name: 'str', evaluators: 'list[Callable[..., Any]]', *, dataset_dir: 'str | None' = None, pass_criteria: 'Callable[[list[list[Evaluation]]], tuple[bool, str]] | None' = None, from_trace: 'Callable[[list[ObservationNode]], Evaluable] | None' = None) -> 'None'
按名称加载数据集,然后对其条目运行 assert_pass。
这是一个便捷包装器,它:
- 从
DatasetStore加载数据集。 - 从每个条目中提取
eval_input作为 runnable 输入。 - 使用完整的
Evaluable项(它们携带expected_output) 作为评估对象。 - 委托给
assert_pass。
参数:
runnable:要测试的应用函数。
dataset_name:要加载的数据集的名称。
evaluators:评估器可调用对象列表。
dataset_dir:数据集存储的覆盖目录。
当为 None 时,从 PixieConfig.dataset_dir 读取。
pass_criteria:接收结果矩阵,返回
(passed, message)。
from_trace:可选的跨度选择器,转发到
assert_pass。
抛出: FileNotFoundError:如果不存在名为 dataset_name 的数据集。 EvalAssertionError:当未满足通过标准时。
追踪辅助函数
pixie.last_llm_call
pixie.last_llm_call(trace: 'list[ObservationNode]') -> 'Evaluable'
在追踪树中找到具有最新 ended_at 的 LLMSpan。
参数:
trace:追踪树(根 ObservationNode 实例的列表)。
返回:
包装最近结束的 LLMSpan 的 Evaluable。
抛出:
ValueError:如果追踪中不存在 LLMSpan。
pixie.root
pixie.root(trace: 'list[ObservationNode]') -> 'Evaluable'
将第一个根节点的跨度作为 Evaluable 返回。
参数:
trace:追踪树(根 ObservationNode 实例的列表)。
返回:
包装第一个根节点跨度的 Evaluable。
抛出: ValueError:如果追踪为空。
pixie.capture_traces
pixie.capture_traces() -> 'Generator[MemoryTraceHandler, None, None]'
安装 MemoryTraceHandler 并返回它的上下文管理器。
调用 init()(如果已初始化则为空操作),然后通过 add_handler() 注册该处理器。退出时,处理器被移除,交付队列被刷新,以便所有跨度在 handler.spans 上可用。