尧图精选

Haystack Evaluators API 完全指南:9 大评估器组件实现 LLM 应用的可量化质检

🕒 发布时间:2026/9/15 0:59:15 📁 来源:尧图网络
Haystack Evaluators API 完全指南9 大评估器组件实现 LLM 应用的可量化质检【免费下载链接】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在 Haystack 2.22 中评估能力被系统化地收敛为一个独立的haystack.components.evaluators组件包共包含 9 个评估器组件覆盖答案级、上下文级、文档检索级与生成忠实性四个评估维度。本文以 version-2.22 的 evaluators_api 参考文档 为核心骨架结合当前仓库源码逐一定位实现细节帮助读者掌握每个评估器的输入输出契约、参数语义、底层调用链以及如何将评估器作为标准组件接入 Haystack Pipeline构建可复现、可量化的 LLM 应用质量闭环。评估器模块概览组件注册与惰性加载机制所有评估器都注册在 haystack/components/evaluators/init.py 中该文件定义了一张_import_structure映射表将 9 个评估器类分别绑定到对应的子模块子模块导出类评估类型answer_exact_matchAnswerExactMatchEvaluator答案级确定性context_relevanceContextRelevanceEvaluator上下文级LLMdocument_mapDocumentMAPEvaluator检索质量确定性document_mrrDocumentMRREvaluator检索质量确定性document_ndcgDocumentNDCGEvaluator检索质量确定性document_recallDocumentRecallEvaluator检索质量确定性faithfulnessFaithfulnessEvaluator生成忠实性LLMllm_evaluatorLLMEvaluator通用 LLM 评估基类sas_evaluatorSASEvaluator答案级语义相似度从源码结构看该包通过LazyImporter实现惰性加载在TYPE_CHECKING分支下正常暴露类型供 IDE 与类型检查器使用在运行时则将整个模块替换为懒加载对象只有真正导入某个评估器时才加载对应子模块从而降低import haystack的启动开销。所有评估器都通过component装饰器注册例如 answer_exact_match.py、document_recall.py并统一使用component.output_types(...)声明输出槽位因此它们与 Haystack Pipeline 中其他组件一样可以被实例化、连接、序列化与反序列化。通用 LLM 评估器基类LLMEvaluator 的完整设计LLMEvaluator 是所有 LLM 型评估器的核心基类ContextRelevanceEvaluator与FaithfulnessEvaluator均直接继承自它见 context_relevance.py 与 faithfulness.py。理解它的参数契约与运行流程就等于理解了整套 LLM 评估机制。初始化参数与默认行为def __init__( instructions: str, # 评估指令通常是一个可用 yes/no 回答的问题 inputs: list[tuple[str, type[list]]], # 输入槽定义如 [(predicted_answers, list[str])] outputs: list[str], # 输出键名如 [score] examples: list[dict[str, Any]], # few-shot 示例 progress_bar: bool True, # 是否显示进度条 *, raise_on_failure: bool True, # API 失败时是否抛异常 chat_generator: ChatGenerator | None None, # 底层 LLM ) - None各参数的语义与约束如下instructions提示中的评估指令文档明确要求其应当是关于输入、可用 yes 或 no 回答的问题例如Is this answer problematic for children?。inputs组件期望接收的输入连接定义每一项是「输入名 输入类型」的二元组类型必须是 list。源码中通过component.set_input_types(self, **dict(inputs))动态注册输入槽。outputs评估结果的输出键名对应输出字典中的 key。LLM 返回的 JSON 必须包含这些键。examples符合inputs/outputs约定的 few-shot 示例每个示例是含inputs与outputs两个字典键的字典。raise_on_failure为True时API 调用失败或输出非法 JSON 将抛出ValueError为False时仅记录警告对应结果置为None并继续。chat_generator代表 LLM 的ChatGenerator实例。若不指定组件默认使用OpenAIChatGenerator并以 JSON 模式运行同时固定seed42以提升可复现性见 llm_evaluator.py。默认使用要求环境变量OPENAI_API_KEY。需要特别说明的是若传入自定义chat_generator该 LLM 必须配置为返回 JSON 对象。例如使用OpenAIChatGenerator时应在generation_kwargs中传入{response_format: {type: json_object}}否则 JSON 解析步骤将失败。提示模板的自动组装prepare_template()将指令、输出键、示例与输入拼装成统一的提示模板其格式为Instructions: instructions Generate the response in JSON format with the following keys: list of output keys Consider the instructions and the examples below to determine those values. Examples: examples Inputs: {input_name: {{ input_name }}} Outputs:从源码实现看llm_evaluator.pyexamples_section由每个示例的json.dumps(example[inputs])与json.dumps(example[outputs])拼接而成inputs_section则生成 Jinja2 风格的占位符之后模板被交给PromptBuilder(templatetemplate)实例化用于在run时逐条渲染输入。run 的完整调用链run(**inputs)的执行流程如下见 llm_evaluator.py先调用warm_up()若底层 generator 支持初始化 LLM。调用validate_input_parameters()校验所有期望输入键必须齐全、所有输入值必须是 list、所有输入列表长度必须一致。将输入按位置转置逐条生成{input_name: value}字典。对每条输入通过PromptBuilder.run()渲染提示构造ChatMessage.from_user(...)调用chat_generator.run(messagesmessages)。对返回文本调用_parse_dict_from_json(result[replies][0].text, expected_keysself.outputs, ...)解析为 JSON 字典解析失败时按raise_on_failure决定抛错或置None。聚合返回{results: [...], meta: metadata or None}。其中results的每个元素是键由outputs定义、值为 0FALSE或 1TRUE的字典若底层为 OpenAI 且响应带meta会一并透传到输出。从当前仓库源码看该基类还实现了run_async()异步版本若底层 generator 实现了run_async则直接调用否则通过asyncio.to_thread在子线程中执行同步run避免阻塞事件循环llm_evaluator.py。三层校验方法基类内置了三层防御式校验这些方法也被子类继承复用validate_init_parameters(inputs, outputs, examples)校验inputs是「str list 类型」的二元组列表、outputs是字符串列表、examples是字典列表且每个示例恰好包含inputs、outputs两个字符串键的字典键否则抛ValueError。validate_input_parameters(expected, received)校验运行期输入键齐全、值均为列表且等长。is_valid_json_and_has_expected_keys(expected, received)校验 LLM 输出是否为含期望键的合法 JSONraise_on_failureTrue时抛ValueError否则告警并返回False。序列化与反序列化to_dict()会将inputs中的类型对象序列化为字符串因为 tuple 无法直接 JSON 序列化源码先将 inputs 转为[[name, serialize_type(type_)], ...]并把chat_generator一并序列化from_dict()则反向调用deserialize_type还原类型、通过deserialize_chatgenerator_inplace还原 generator 实例llm_evaluator.py。这意味着包含 LLM 评估器的 Pipeline 可以完整地dump/load实现评估配置的版本化与团队共享。上下文相关性评估器ContextRelevanceEvaluatorContextRelevanceEvaluator用于回答检索到的上下文是否与问题相关这一经典 RAG 质检问题。其原理是让 LLM 将上下文拆解为多条陈述statement逐条判断该陈述是否对回答问题有用。每条上下文的得分是二值的 1 或 0同时输出从中筛出的相关陈述并给出所有「问题-上下文」对的平均分。官方用法示例from haystack.components.evaluators import ContextRelevanceEvaluator questions [Who created the Python language?, Why does Java needs a JVM?, Is C better than Python?] contexts [ [( Python, created by Guido van Rossum in the late 1980s, is a high-level general-purpose programming language. Its design philosophy emphasizes code readability, and its language constructs aim to help programmers write clear, logical code for both small and large-scale software projects. )], [( Java is a high-level, class-based, object-oriented programming language that is designed to have as few implementation dependencies as possible. The JVM has two primary functions: to allow Java programs to run on any device or operating system (known as the write once, run anywhere principle), and to manage and optimize program memory. )], [( C is a general-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language. )], ] evaluator ContextRelevanceEvaluator() result evaluator.run(questionsquestions, contextscontexts) print(result[score]) # 0.67 print(result[individual_scores]) # [1,1,0] print(result[results]) # [{ # relevant_statements: [Python, created by Guido van Rossum in the late 1980s.], # score: 1.0 # }, # { # relevant_statements: [The JVM has two primary functions: ...], # score: 1.0 # }, # { # relevant_statements: [], # score: 0.0 # }]初始化签名与参数语义context_relevance.pydef __init__( examples: list[dict[str, Any]] | None None, progress_bar: bool True, raise_on_failure: bool True, chat_generator: ChatGenerator | None None, )examples可选的 few-shot 示例必须符合本评估器的输入输出格式——inputs含questions与contexts键outputs含relevant_statements键。例如[{ inputs: { questions: What is the capital of Italy?, contexts: [Rome is the capital of Italy.], }, outputs: { relevant_statements: [Rome is the capital of Italy.], }, }]不传示例时组件使用内置的默认示例当前仓库源码中定义了 3 条内置示例涵盖全部相关全部无关与部分相关三种情形见 context_relevance.py。run输入questions问题列表、contexts嵌套列表每个问题的上下文列表。run输出score全部问题-上下文对的平均相关性得分、results每个上下文一组的relevant_statements与score。生成忠实性评估器FaithfulnessEvaluatorFaithfulnessEvaluator用于检测 LLM 生成的答案是否忠实于给定的上下文即答案中的每条陈述能否从上下文中推断得出是识别幻觉hallucination的常用手段。最终得分是 0.0 到 1.0 的数值表示可被上下文支撑的陈述所占比例。官方用法示例from haystack.components.evaluators import FaithfulnessEvaluator questions [Who created the Python language?] contexts [ [( Python, created by Guido van Rossum in the late 1980s, is a high-level general-purpose programming language. Its design philosophy emphasizes code readability, and its language constructs aim to help programmers write clear, logical code for both small and large-scale software projects. )], ] predicted_answers [ Python is a high-level general-purpose programming language that was created by George Lucas. ] evaluator FaithfulnessEvaluator() result evaluator.run(questionsquestions, contextscontexts, predicted_answerspredicted_answers) print(result[individual_scores]) # [0.5] print(result[score]) # 0.5 print(result[results]) # [{statements: [Python is a high-level general-purpose programming language., # Python was created by George Lucas.], statement_scores: [1, 0], score: 0.5}]初始化签名与参数语义与ContextRelevanceEvaluator完全一致def __init__( examples: list[dict[str, Any]] | None None, progress_bar: bool True, raise_on_failure: bool True, chat_generator: ChatGenerator | None None, )examples的格式要求inputs含questions、contexts、predicted_answers三个键outputs含statements与statement_scores两个键。示例如下[{ inputs: { questions: What is the capital of Italy?, contexts: [Rome is the capital of Italy.], predicted_answers: Rome is the capital of Italy with more than 4 million inhabitants., }, outputs: { statements: [Rome is the capital of Italy., Rome has more than 4 million inhabitants.], statement_scores: [1, 0], }, }]run输入questions、contexts嵌套列表、predicted_answers预测答案列表。run输出score全部答案的平均忠实性得分、individual_scores每条答案的得分、results每条答案的statements、statement_scores与score。答案精确匹配评估器AnswerExactMatchEvaluatorAnswerExactMatchEvaluator是最朴素的答案级评估器逐条判断预测答案是否与某个标准答案完全一致。输入允许多个标准答案与多个预测答案输出为 0.0 到 1.0 的数值表示与标准答案精确匹配的预测答案占比。官方用法示例from haystack.components.evaluators import AnswerExactMatchEvaluator evaluator AnswerExactMatchEvaluator() result evaluator.run( ground_truth_answers[Berlin, Paris], predicted_answers[Berlin, Lyon], ) print(result[individual_scores]) # [1, 0] print(result[score]) # 0.5run的签名与返回契约component.output_types(individual_scoreslist[int], scorefloat) def run(ground_truth_answers: list[str], predicted_answers: list[str]) - dict[str, Any]ground_truth_answers期望答案列表predicted_answers预测答案列表两者长度必须一致否则源码会抛出ValueErroranswer_exact_match.py。返回individual_scores0/1 列表1 表示预测答案命中了任一标准答案与score命中比例。从实现细节看该评估器逐对比较zip(..., strictTrue)得分即匹配数的算术平均没有任何模糊匹配或归一化逻辑因此对答案的措辞极其敏感适合答案形态高度标准化的任务如选择题、事实型问答。文档检索质量评估器四个确定性排序指标这组评估器针对 RAG 的检索环节度量检索出的文档排名有多好。它们都不依赖 LLM运行快速、结果确定。四个评估器都接收ground_truth_documents与retrieved_documents两个嵌套列表参数外层按问题分组内层是该问题的文档列表且两者长度必须一致。需要特别强调的是文档中明确提示DocumentMAPEvaluator与DocumentMRREvaluator不会对输入做任何归一化应在传入前用DocumentCleaner等组件对文档内容做清洗与标准化否则可能因文本细微差异大小写、空白、标点导致匹配失败。DocumentMAPEvaluator平均精度均值MAPMean Average Precision衡量的是检索结果整体排名质量既关注相关文档是否被检索到也关注它们是否排在靠前的位置。文档中的官方示例from haystack import Document from haystack.components.evaluators import DocumentMAPEvaluator evaluator DocumentMAPEvaluator() result evaluator.run( ground_truth_documents[ [Document(contentFrance)], [Document(content9th century), Document(content9th)], ], retrieved_documents[ [Document(contentFrance)], [Document(content9th century), Document(content10th century), Document(content9th)], ], ) print(result[individual_scores]) # [1.0, 0.8333333333333333] print(result[score]) # 0.9166666666666666从 document_map.py 的实现看其算法核心是按排名逐个扫描检索文档每当命中一个尚未计分过的标准文档累计retrieved_relevant / (rank 1)最后除以标准文档总数得到该问题的 Average Precision全局score为所有问题 AP 的均值。值得注意的是源码通过一个列表而非集合维护未计分标准值以兼容比较值不可哈希如 meta 中的 list 值的场景。DocumentMRREvaluator倒数排名均值MRRMean Reciprocal Rank只关注第一个命中标准文档的排名第一个相关文档排第 1 位得 1.0排第 2 位得 0.5依此类推完全没有命中则得 0。官方示例中第二个问题的检索列表[9th century, 10th century, 9th]首个文档即命中因此得 1.0整体score为 1.0见 document_mrr.py。DocumentNDCGEvaluator归一化折损累计增益NDCG 在四个指标中最为精细因为它支持带相关度分数的标准文档如果标准文档带有score即相关度则按真实分数计算否则默认所有标准文档相关度为 1.0二值相关。官方示例from haystack import Document from haystack.components.evaluators import DocumentNDCGEvaluator evaluator DocumentNDCGEvaluator() result evaluator.run( ground_truth_documents[[Document(contentFrance, score1.0), Document(contentParis, score0.5)]], retrieved_documents[[Document(contentFrance), Document(contentGermany), Document(contentParis)]], ) print(result[individual_scores]) # [0.8869] print(result[score]) # 0.8869其计算过程分为两步源码见 document_ndcg.pycalculate_dcg(gt_docs, ret_docs)按检索顺序累加relevance / log2(rank 1)rank 从 1 开始故源码使用 0 基索引加 2每个相关文档只计分一次避免重复检索同一文档抬高 DCG。calculate_idcg(gt_docs)将标准文档相关度降序排列后计算理想折损累计增益共享同一比较值的文档合并为一项、取最高相关度保证完美检索时 NDCG 恰为 1.0。run前会执行validate_inputs校验规则包括两组输入不能为空、长度必须一致、每组标准文档不能出现有的带 score、有的不带 score的混合情况否则抛ValueError。DocumentRecallEvaluator召回率DocumentRecallEvaluator计算召回率且通过mode参数支持两种口径枚举定义见 document_recall.pysingle_hit默认只要任意一个标准文档被检索到即得 1.0否则 0.0——适合能找到就够的场景。multi_hit按命中标准文档占全部标准文档的比例计分——适合全都要找到的场景。def __init__(mode: str | RecallMode RecallMode.SINGLE_HIT)mode既可直接传RecallMode枚举也可传字符串内部通过RecallMode.from_str转换未知模式会抛出包含支持模式列表的ValueError。官方示例中第二个问题的 3 条标准文档全部被检索到individual_scores为[1.0, 1.0]整体score为 1.0。从当前仓库源码看该评估器以及 MAP/MRR/NDCG 三个组件的__init__还支持document_comparison_field参数用于指定文档比较字段可选项为content默认比较doc.content、id比较doc.id、或meta.key比较嵌套 meta 值如meta.file_id、meta.source.url。这允许评估器直接按文档 ID 或元数据去重匹配而不仅仅是按文本内容匹配。语义答案相似度评估器SASEvaluatorSASEvaluator计算预测答案与标准答案之间的 Semantic Answer Similarity语义答案相似度常用于 RAG 流水线中评估生成答案的质量——与精确匹配不同它能容忍措辞不同但语义相同的答案。官方用法示例from haystack.components.evaluators.sas_evaluator import SASEvaluator evaluator SASEvaluator(modelcross-encoder/ms-marco-MiniLM-L-6-v2) evaluator.warm_up() ground_truths [ A construction budget of US $2.3 billion, The Eiffel Tower, completed in 1889, symbolizes Pariss cultural magnificence., The Meiji Restoration in 1868 transformed Japan into a modernized world power., ] predictions [ A construction budget of US $2.3 billion, The Eiffel Tower, completed in 1889, symbolizes Pariss cultural magnificence., The Meiji Restoration in 1868 transformed Japan into a modernized world power., ] result evaluator.run( ground_truths_answersground_truths, predicted_answerspredictions ) print(result[score]) # 0.9999673763910929 print(result[individual_scores]) # [0.9999765157699585, 0.999968409538269, 0.9999572038650513]初始化签名sas_evaluator.pydef __init__( model: str sentence-transformers/paraphrase-multilingual-mpnet-base-v2, batch_size: int 32, device: ComponentDevice | None None, token: Secret Secret.from_env_var([HF_API_TOKEN, HF_TOKEN], strictFalse), )modelSentenceTransformers 语义文本相似度模型可传模型名或本地路径。默认模型是多语言 paraphrase 模型适合跨语言/多语言场景。batch_size每次编码的「预测-标准」样本对数量默认 32影响吞吐与显存占用。device模型加载设备传None时自动选择默认设备。tokenHugging Face 访问令牌用于访问受限模型或私有仓库默认从HF_API_TOKEN或HF_TOKEN环境变量读取非强制。从源码看warm_up()负责真正的模型加载它先通过AutoConfig.from_pretrained读取模型配置根据architectures是否以ForSequenceClassification结尾来自动判定模型类型——分类架构加载为CrossEncoder交叉编码器否则加载为SentenceTransformer双编码器两种模型使用不同的相似度计算方式sas_evaluator.py。因此用户只需按任务选好model参数无需手动区分 Bi-Encoder 与 Cross-Encoder。此外sentence-transformers依赖通过LazyImport按需加载未安装时会提示运行pip install sentence-transformers5.0.0。run(ground_truth_answers, predicted_answers)要求两个字符串列表等长返回score全部样本对的平均相似度与individual_scores逐对相似度源码还会对空列表、含None的预测答案等情况抛出ValueError。把评估器接入 Pipeline序列化与组件化实践由于所有评估器都是标准的component可以直接放入 Pipeline 与 RAG 主链路并行或串行连接。例如在 RAG 评估场景中可将ContextRelevanceEvaluator、FaithfulnessEvaluator与SASEvaluator分别实例化接入检索器输出与生成器输出统一收集各自的结果字典后再汇总分析。序列化是评估配置沉淀的关键能力每个评估器都实现了to_dict()与from_dict()或继承自LLMEvaluator/SASEvaluator的默认实现配合 Haystack 的 Pipeline 序列化机制可以把「评估器 评估用的 few-shot 示例 所选 LLM 配置」整体保存为 YAML/JSON在 CI 或批处理任务中重复加载执行保证评估口径在不同时间点、不同成员之间完全一致。LLMEvaluator系列还在to_dict时把 tuple 形式的inputs转换为可序列化列表并在from_dict时还原类型与 generator细节可回看 llm_evaluator.py。对部署环境而言两类评估器的依赖差异需要留意确定性评估器Exact Match、MAP、MRR、NDCG、Recall零外部依赖LLM 型评估器默认依赖 OpenAI API 密钥OPENAI_API_KEYSASEvaluator则依赖sentence-transformers5.0.0及可访问的 Hugging Face 模型仓库并建议先调用warm_up()预热模型后再进入正式评估。评估器选型速查评估器评估对象依赖输出分数含义AnswerExactMatchEvaluator预测答案无精确匹配比例ContextRelevanceEvaluator检索上下文LLM默认 OpenAI上下文对问题的相关比例FaithfulnessEvaluator生成答案LLM默认 OpenAI答案可被上下文支撑的陈述比例DocumentMAPEvaluator检索文档排名无平均精度均值排名整体质量DocumentMRREvaluator检索文档排名无首个相关文档的倒数排名均值DocumentNDCGEvaluator检索文档排名无支持相关度分数的折损累计增益DocumentRecallEvaluator检索文档无single_hit / multi_hit 两种召回率SASEvaluator预测答案sentence-transformers语义相似度Bi/Cross-Encoder实际项目中通常按答案是否要求逐字一致 → 选精确匹配检索质量是否关注排序 → 选 MAP/MRR/NDCG生成内容是否可信 → 选 Faithfulness上下文是否命中问题 → 选 ContextRelevance答案是否语义等价 → 选 SAS的原则组合使用形成覆盖 RAG 全链路的评估矩阵。【免费下载链接】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),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →