Haystack Evaluation API 详解:EvaluationRunResult 评估结果容器与三种报告生成方法

发布时间:2026/9/14 20:53:00
Haystack Evaluation API 详解:EvaluationRunResult 评估结果容器与三种报告生成方法 Haystack Evaluation API 详解EvaluationRunResult 评估结果容器与三种报告生成方法【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystackHaystack 的评估体系分为两层底层是各类 Evaluator 组件如 MRR、Recall、Faithfulness负责产出每个样本的分数上层是haystack.evaluation模块中的EvaluationRunResult负责把一次评估运行的输入与所有指标分数组织起来并提供聚合报告、明细报告和跨运行对比报告三种输出。本文基于仓库中的 API 参考文档与源码实现完整讲解EvaluationRunResult的构造契约、参数校验规则、三种报告方法的行为细节以及如何从 Evaluator 管道无缝接入该 API 的端到端流程。读完后你可以独立构建一次 RAG 评估运行并生成 JSON/CSV/DataFrame 格式的报告用于版本对比。模块定位与导入方式EvaluationRunResult位于haystack/evaluation/eval_run_result.py并通过haystack/evaluation/__init__.py中的延迟导入机制对外暴露。该模块的_import_structure仅注册了eval_run_result下的EvaluationRunResult一个符号因此标准导入方式为from haystack.evaluation import EvaluationRunResult值得注意的是haystack/evaluation/__init__.py使用了LazyImporter做模块级懒加载只有在真正访问EvaluationRunResult时才会加载eval_run_result子模块。而在eval_run_result.py内部pandas 同样通过LazyImport(Run pip install pandas)延迟导入见 eval_run_result.py这意味着只有当你请求df格式输出时才需要安装 pandasjson和csv格式不依赖该库。EvaluationRunResult 构造与数据契约类文档描述其为“包含评估管道的输入与输出并提供检查它们的方法”。构造函数签名为def __init__(run_name: str, inputs: dict[str, list[Any]], results: dict[str, dict[str, Any]])三个参数各自的语义与约束结合 源码实现 整理如下参数类型说明run_namestr评估运行的名称例如rag_pipeline_a。在对比报告中会作为列名前缀使用因此两次运行必须使用不同名称才有可读的对比结果inputsdict[str, list[Any]]本次运行使用的输入。每个 key 是输入名如question、contexts、predicted_answervalue 是该输入下所有样本的值列表。所有列表长度必须相同即列表长度 样本数resultsdict[str, dict[str, Any]]评估管道中各评估器的结果。key 是指标名即 Evaluator 在管道中的组件名value 字典必须包含两个键score该指标的聚合分数与individual_scores每个输入样本对应的分数列表且individual_scores长度必须与inputs的列表长度一致构造时执行了四组强校验任一违反都会抛出ValueError这些规则在 test/evaluation/test_eval_run_result.py 中有对应的断言用例inputs为空 → 抛出ValueError(No inputs provided.)inputs各列表长度不一致 → 抛出ValueError(Lengths of the inputs should be the same.)某指标的results条目缺少score键 → 抛出ValueError(Aggregate score missing for {metric}.)缺少individual_scores键 → 抛出ValueError(Individual scores missing for {metric}.)individual_scores长度与输入样本数不一致 → 抛出ValueError(Length of individual scores for {metric} should be the same as the inputs...)。此外源码中self.inputs deepcopy(inputs)与self.results deepcopy(results)eval_run_result.py对输入做了深拷贝即构造完成后外部修改原始字典不会影响已创建的EvaluationRunResult实例。一个符合契约的最小示例取自单元测试from haystack.evaluation import EvaluationRunResult inputs { query_id: [53c3b3e6, 225f87f7], question: [What is the capital of France?, What is the capital of Spain?], contexts: [wiki_France, wiki_Spain], answer: [Paris, Madrid], predicted_answer: [Paris, Madrid], } results { reciprocal_rank: {individual_scores: [0.378064, 0.534964], score: 0.476932}, faithfulness: {individual_scores: [0.135581, 0.695974], score: 0.40585375}, } result EvaluationRunResult(testing_pipeline_1, inputsinputs, resultsresults)aggregated_report按指标聚合的报告def aggregated_report( output_format: Literal[json, csv, df] json, csv_file: Optional[str] None ) - Union[dict[str, list[Any]], DataFrame, str]生成只含每个指标聚合分数的报告。从 实现 看它只取每个指标的results[k][score]组装成两列数据metrics指标名列表与score对应聚合分数列表再交给统一的输出处理函数。以json格式调用时返回结构如{metrics: [reciprocal_rank, faithfulness], score: [0.476932, 0.40585375]}该断言在 test_score_report 中被完整验证。聚合分数本身由 Evaluator 计算例如DocumentMRREvaluator的聚合分是各样本 MRR 的算术平均见 document_mrr.pyscore sum(individual_scores) / len(ground_truth_documents)EvaluationRunResult只负责原样呈现。detailed_report逐样本明细报告def detailed_report( output_format: Literal[json, csv, df] json, csv_file: Optional[str] None ) - Union[dict[str, list[Any]], DataFrame, str]生成逐样本明细以inputs中的每一列作为列名再把每个指标的individual_scores追加为对应指标名的列最终形成一个“宽表”——一行对应一个样本一列对应一个输入字段或一个指标。实现 中有一个值得注意的细节对每个指标列的值会做类型归一化若列表中出现任何float则整列统一转为floatcol_values [float(v) for v in col_values]以保证 DataFrame/CSV 输出时列类型一致例如single_hit的[1, 1, 0, 1]与浮点指标混合输出时不会因整型/浮点混杂而出错。json格式返回的完整结构可见 test_to_df 中的断言列顺序先为全部输入列query_id、question、contexts、answer、predicted_answer再依次为各指标列。comparative_detailed_report跨运行对比报告def comparative_detailed_report( other: EvaluationRunResult, keep_columns: Optional[list[str]] None, output_format: Literal[json, csv, df] json, csv_file: Optional[str] None) - Union[str, DataFrame, None]用于在同一组输入上运行两条或多条中的两条管道时将两次运行的明细分数横向拼接便于逐样本对比。参数与行为细节源码见 comparative_detailed_reportother另一个EvaluationRunResult实例。传入非该类型实例会抛出TypeError缺少run_name/inputs/results属性会抛出ValueError。keep_columns指定要保留的公共输入列名列表。keep_columnsNone时本侧self的所有输入列都会出现在结果中且不加前缀对侧other的输入列则被全部过滤掉若给定keep_columns则仅保留这些列且这些列来自other侧并以{other.run_name}_前缀命名。列名拼接规则本侧中不属于keep_columns的列包括所有指标列统一加上{self.run_name}_前缀属于keep_columns的列保留原名对侧列统一加{other.run_name}_前缀。例如在单元测试中keep_columns[predicted_answer]时结果列依次为query_id、question、contexts、answer本侧公共输入无/本侧命名随后是testing_pipeline_1_predicted_answer、testing_pipeline_1_reciprocal_rank等本侧全部列以及testing_pipeline_2_predicted_answer、testing_pipeline_2_...等对侧列完整断言见 test_comparative_individual_scores_report。两个容错行为值得留意两次运行的run_name相同时仅记录warning日志列名仍会重复前缀需注意可读性两侧inputs的列集合不一致时会记录“使用本侧输入列”的 warning 并以本侧为准。输出格式与 csv_file 参数三个报告方法共享同一套输出处理逻辑_handle_outputeval_run_result.pyoutput_format取值及行为如下output_format返回值依赖json默认dict[str, list[Any]]可直接json.dumps无dfpandasDataFrame需要安装 pandas否则触发 LazyImport 提示Run pip install pandascsv写入文件后返回确认信息字符串失败时返回错误信息字符串而非抛异常必须提供csv_file参数否则抛出ValueErrorCSV 写入由静态方法_write_to_csv完成先校验所有列长度一致不一致抛ValueError然后按列名写表头、按行写入数据PermissionError与OSError被捕获后以错误消息字符串形式返回eval_run_result.py。端到端工作流从 Evaluator 管道到报告仓库的端到端测试 e2e/pipelines/test_evaluation_pipeline.py 演示了完整接入路径可作为实操参考该测试需要OPENAI_API_KEY环境变量用于 Embedding 与 LLM 评估器构建评估管道把多个 Evaluator 组件加入一条Pipeline如DocumentMRREvaluator、DocumentMAPEvaluator、DocumentRecallEvaluatorRecallMode.SINGLE_HIT/MULTI_HIT两种模式、FaithfulnessEvaluator、SASEvaluator、ContextRelevanceEvaluator。逐样本收集中间产物对每个问题运行 RAG 管道收集questions、contexts、predicted_answers、retrieved_documents与truth_docs等列表——这些列表将来既是评估管道的输入也是EvaluationRunResult.inputs的内容。运行评估管道按 Evaluator 的输入 socket 组装输入字典后eval_pipeline.run(eval_input)。每个 Evaluator 的输出均为{score: ..., individual_scores: [...]}这与results参数的契约天然一致——例如FaithfulnessEvaluator与DocumentMRREvaluator都以component.output_types(scorefloat, individual_scoreslist[float])声明输出参见 document_mrr.py。组装 EvaluationRunResult把 Evaluator 原始输出按指标名重新组织e2e 测试中的built_input_for_results_eval函数展示了如何从管道结果提取individual_scores与score连同输入列表一起传入构造函数并给每次运行一个有意义的run_name。生成报告aggregated_report()校验了 7 个指标全部出现在metrics列中detailed_report()校验了列顺序为 4 个输入列 7 个指标列最后用evaluation_result_a.comparative_detailed_report(evaluation_result_b)对比top_k2与top_k4两条 RAG 管道断言对比报告包含两组共 18 个带rag_pipeline_a_/rag_pipeline_b_前缀的分数列test_evaluation_pipeline.py。这一流程验证了 API 文档中参数描述的落地方式results的 key 即指标名inputs的 key 即样本维度字段二者在detailed_report中被横向合并为一张宽表。错误处理与适用前提小结数据契约的 5 类校验错误均为ValueError错误信息直接指明是哪个指标、期望长度与实际长度见 单元测试用例便于在数据管道上游快速定位错位comparative_detailed_report对类型与属性做了显式检查分别抛出TypeError与ValueError同名的运行只告警不中断适用前提本 API 属于 Haystack 2.x/3.x 的haystack.evaluation模块本文依据 2.21 版本 API 参考文档整理当前仓库版本见 VERSION.txtEvaluator 必须输出scoreindividual_scores双键结构才能直接映射为results使用df格式需额外安装 pandas相关代码索引实现 haystack/evaluation/eval_run_result.py单元测试 test/evaluation/test_eval_run_result.py端到端示例 e2e/pipelines/test_evaluation_pipeline.py评估器组件目录 haystack/components/evaluators/。【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考