十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Kibana Evals 评估器模式详解:从 CODE 断言到 LLM-as-Judge 与 RAG 评估的完整实践

Kibana Evals 评估器模式详解:从 CODE 断言到 LLM-as-Judge 与 RAG 评估的完整实践 Kibana Evals 评估器模式详解从 CODE 断言到 LLM-as-Judge 与 RAG 评估的完整实践【免费下载链接】kibanaYour window into all of your data项目地址: https://gitcode.com/GitHub_Trending/ki/kibanaKibana 仓库内置了一套基于kbn/evals包的 LLM 评估Evals体系用于对 Agent、RAG 检索、工具调用链等 AI 功能进行系统化打分。本文以技能参考文档 evaluator-patterns.md 为主体完整讲解其中五种评估器模式——CODE 确定性评估器、LLM-as-Judge 准则评估器、工具调用评估器、RAG 检索评估器与基于 Trace 的评估器并结合仓库中真实存在的kbn-evals-suite-workflows评估套件源码说明这些模式在 Kibana 项目内的落地方式帮助你在编写新的 eval spec 时正确选择与组合评估器。评估体系背景runExperiment 与两种评估器入口在 Kibana 的 eval 规范文件中评估器不是孤立存在的而是与 dataset数据集和 task任务函数一起通过executorClient.runExperiment提交给执行器。评估器的职责是拿到每个 example 的input输入、output任务实际输出、expected期望输出和metadata示例级元数据返回一个带score0/1 或数值分、可选labelPASS/FAIL和explanation解释文本的结果。runExperiment接受评估器的入口有两种见配套文档 SKILL.md 的 “Evaluators” 一节内联数组—— 直接传入评估器对象数组适合简单的套件selectEvaluators—— 类型化的包装器强制Example/TaskOutput泛型为input、output、expected、metadata提供完整的 TypeScript 类型安全。下文各节即参考文档中给出的各类型评估器的扩展示例均来自真实 eval 套件。CODE 评估器用 selectEvaluators 获得类型安全的确定性检查kind: CODE的评估器不调用 LLM因此速度快、结果确定、成本为零适合二值断言“有没有返回文档”“URL 是否合法”“是否包含必备词”等。参考文档从llm-tasks套件提取的完整示例如下import { selectEvaluators, type Example, type TaskOutput } from kbn/evals; type MyExample Example { input: { searchTerm: string; products?: string[] }; metadata?: { minDocs?: number; requiredTerms?: string[] }; }; type MyTaskOutput TaskOutput { success: boolean; documents: Array{ title: string; url: string; content: string }; }; await executorClient.runExperiment( { datasets: [dataset], task }, selectEvaluatorsMyExample, MyTaskOutput([ { name: NonEmptyDocuments, kind: CODE, evaluate: async ({ output, metadata }) { const minDocs typeof metadata?.minDocs number ? metadata.minDocs : 1; const count output?.documents?.length ?? 0; return { score: count minDocs ? 1 : 0, metadata: { minDocs, count } }; }, }, { name: RequiredTermsInContent, kind: CODE, evaluate: async ({ output, metadata }) { const requiredTerms metadata?.requiredTerms ?? []; if (requiredTerms.length 0) return { score: 1 }; const text (output?.documents ?? []) .slice(0, 3) .map((d) ${d.title}\n${d.content}) .join(\n); const ok requiredTerms.every((term) text.toLowerCase().includes(term.toLowerCase()) ); return { score: ok ? 1 : 0, metadata: { requiredTerms } }; }, }, { name: HasValidUrl, kind: CODE, evaluate: async ({ output }) { const urls (output?.documents ?? []).map((d) d.url); const ok urls.some((u) typeof u string u.startsWith(https://)); return { score: ok ? 1 : 0, metadata: { urls: urls.slice(0, 3) } }; }, }, ]) );这个示例体现了参考文档总结的三条要点selectEvaluatorsExampleType, OutputType([...])提供类型安全。通过把Example与TaskOutput两个泛型参数化evaluate回调中的output.documents、metadata.minDocs等字段访问都受 TypeScript 约束字段拼错或类型不符会在编译期暴露kind: CODE意味着无 LLM 调用快速且确定适合放在每个 example 上高频运行在返回结果里带上metadata有助于调试。如示例中的{ minDocs, count }、{ urls: urls.slice(0, 3) }当某个 example 得分 0 时报告里可以直接看到当时的阈值与命中数而不必重放任务。编写 CODE 评估器时值得注意的防御式写法metadata?.minDocs用typeof number校验后再回退默认值 1output?.documents?.length ?? 0处理任务输出缺失的情况requiredTerms.length 0时直接给 1 分——“没有断言就不扣分”这与后文 LLM 评估器中 “No criteria specified” 直接 PASS 的约定是一致的。LLM-as-Judge 准则评估器evaluators.criteria对于无法用确定代码判定的主观质量“回答是否正确识别了风险最高的用户”参考文档给出的是 LLM-as-Judge 模式通过evaluators.criteria([...])把一组自然语言准则交给 judge 模型逐条打分。从security-solution-evals套件提取的用法const mainCriteriaResult await evaluators .criteria([ The response correctly identifies the top users., The response includes risk scores for each user., The response includes risk levels for each user., ]) .evaluate({ input, output, expected, metadata });关键语义每条 criterion 独立评估judge 对每条准则返回 0 或 1 的分数及解释。准则应当写成可验证的陈述句“包含了 X”“按 Y 排序”而不是模糊形容词否则 judge 的打分方差会变大。把 criteria 包装成可复用评估器参考文档进一步示范了把criteria封装为具名评估器的惯用法——准则本身存放在数据集的expected.criteria中由评估器在运行时取出function createCriteriaEvaluator({ evaluators }: { evaluators: DefaultEvaluators }) { return { name: Criteria, kind: LLM as const, evaluate: async ({ input, output, expected, metadata }: { input: MyExample[input]; output: MyTaskOutput; expected: MyExample[output]; metadata: MyExample[metadata]; }) { const criteria expected.criteria ?? []; if (criteria.length 0) { return { score: 1, label: PASS, explanation: No criteria specified. }; } return evaluators.criteria(criteria).evaluate({ input, expected, output, metadata }); }, }; }这种工厂模式createXxxEvaluator({ evaluators })返回{ name, kind, evaluate }对象的意义在于评估器获得name与kind: LLM标记最终报告中可按名称聚合得分判定逻辑与准则数据分离——准则写在数据集的expected里同一评估器可服务整个数据集的不同 example空准则短路返回 PASS避免对无期望值的示例浪费 judge 调用。工具调用评估器验证 Agent 的轨迹而不仅是回答对 Agent 类功能光看最终文本不够还要验证它是否调用了正确的工具。参考文档从security-solution-evals提取的createToolCallsEvaluator实现了两层断言function createToolCallsEvaluator({ evaluators }: { evaluators: DefaultEvaluators }) { return { name: ToolCalls, kind: LLM as const, evaluate: async ({ input, output, expected, metadata }) { const toolCalls expected.toolCalls ?? []; const steps output.steps ?? []; if (toolCalls.length 0) { return { score: 1, label: PASS, explanation: No tool call assertions. }; } const results []; for (const assertion of toolCalls) { const called steps.some( (s) s.type tool_call s.tool_id assertion.id ); if (!called) { results.push({ score: 0, label: FAIL, explanation: Tool ${assertion.id} was not called., }); continue; } if (assertion.criteria?.length) { const criteriaResult await evaluators .criteria(assertion.criteria) .evaluate({ input, expected: { criteria: assertion.criteria }, output, metadata }); results.push(criteriaResult); } else { results.push({ score: 1, label: PASS, explanation: Tool ${assertion.id} called. }); } } const allPassed results.every((r) r.label PASS); const scores results.map((r) r.score ?? 0); const avg scores.reduce((a, b) a b, 0) / scores.length; return { score: allPassed ? avg : 0, label: allPassed ? PASS : FAIL, explanation: results.map((r) r.explanation).join( ), }; }, }; }实现逻辑值得逐点理解轨迹级检查CODE 部分从任务输出的steps里筛选type tool_call且tool_id匹配断言的步骤确认工具确实被调用过质量级检查LLM 部分若断言附带criteria如“ES|QL 查询应按 risk score 降序”则再委托给evaluators.criteria让 judge 评估工具调用的参数或结果是否符合预期聚合规则所有断言全部 PASS 时得分取各断言分的平均值任何一条 FAIL 则整体 0 分——这是一种“一票否决”的严格聚合无断言短路toolCalls为空时直接 PASS保持与 criteria 评估器一致的约定。配套的数据集写法把断言声明在outputexpected中{ input: { question: Which users have the highest risk scores? }, output: { criteria: [ Return 10 users with the highest risk scores., Return the risk levels of those users., ], toolCalls: [ { id: security.entity_analytics.risk_score, criteria: [The ES|QL query should sort by risk score descending.], }, ], }, }可以看到一条 example 同时驱动了主答案准则criteria与轨迹断言toolCalls两者各自独立评估、互不干扰。RAG 评估器PrecisionK / RecallK / F1K 与 ground truth针对“检索质量”这一 RAG 场景kbn/evals提供了三个指标评估器及一个工厂import { createPrecisionAtKEvaluator, createRecallAtKEvaluator, createF1AtKEvaluator, createRagEvaluators, } from kbn/evals; import type { GroundTruth, RetrievedDoc } from kbn/evals;createRagEvaluators工厂一次性创建三者核心是把“任务原始输出”与“数据集中的 ground truth”解耦为两个抽取函数const ragEvals createRagEvaluators({ k: 5, extractRetrievedDocs: (output) output.documents.map((d) ({ id: d.id, content: d.content })), extractGroundTruth: (expected) expected.groundTruth, });k: 5表示只考察检索结果的前 5 条extractRetrievedDocs负责从任务输出中抽出{ id, content }形式的检索文档列表extractGroundTruth负责从expected中取出 ground truth 映射。数据集中的 ground truth 采用“文档 ID → 相关性分数”的映射形式{ input: { question: How do I set up payments? }, output: { expected: You can start accepting payments using Wix Payments..., groundTruth: { knowledge_base: { doc_hash_abc123: 1, doc_hash_def456: 1, }, }, }, }即每个 example 预先声明“哪些文档对本 query 是相关的值为 1”评估器据此计算前 K 条检索结果命中的精度、召回与 F1。这套设计与经典 IR 评估一致属于确定性的 CODE 型评估不依赖 judge 模型。Trace 评估器从追踪集群读取 token 与延迟指标参考文档的第六节介绍了evaluators.traceBasedEvaluators中预置的五个数值型评估器const { inputTokens, outputTokens, cachedTokens, toolCalls, latency } evaluators.traceBasedEvaluators;它们按当前 example 的 trace ID 到 tracing ES 集群查询 span 并提取指标评估器含义数据来源inputTokens输入 token 数gen_ai.usage.*span 属性outputTokens输出 token 数gen_ai.usage.*span 属性cachedTokens缓存命中 token 数gen_ai.usage.*span 属性toolCalls工具调用 span 数量tool call spanslatency总 span 时长秒span duration运行前提EDOTElastic Developer Observability Testing可观测性追踪链路必须在运行中且TRACING_ES_URL指向一个实际接收 traces 的 ES 实例。若不满足该前提这类评估器拿不到数据本地迭代时应以 CODE 评估器为主。组合多种评估器类型真实的 eval 套件通常同时提交 CODE 与 LLM 两类评估器由执行器对每个 example 逐个运行并在最终报告中聚合分数。参考文档给出的组合示例await executorClient.runExperiment( { datasets: [dataset], task }, [ createCriteriaEvaluator({ evaluators }), createToolCallsEvaluator({ evaluators }), { name: HasResponse, kind: CODE, evaluate: async ({ output }) ({ score: output?.messages?.length 0 ? 1 : 0, }), }, ] );该组合体现了参考文档推荐的分工策略用低成本的 CODE 评估器HasResponse做基础健康检查用 LLM 评估器Criteria、ToolCalls做质量判断二者互不替代——LLM judge 不应承担“有没有输出”这种确定性问题CODE 断言也不应试图判断语义质量。仓库实证kbn-evals-suite-workflows 套件如何应用这些模式参考文档中的模式并非孤立示例仓库中的kbn-evals-suite-workflows评估套件展示了同样的落地方式。在 workflow_creation.spec.ts 中spec 文件从kbn/evals导入selectEvaluators与EvaluationDataset类型通过自定义的evaluatefixture 扩展出evaluateCreateDataset在 fixture 内部调用executorClient.runExperiment({ datasets: [dataset], task }, ...)提交实验——与参考文档 “Combining Multiple Evaluator Types” 一节的骨架完全一致。该套件的 task 会调用chatClient.converse取得messages、steps、errors再从中提取工作流 YAML 作为任务输出供评估器断言。同目录的 evaluators.ts 则展示了评估器工厂在实际套件中的工程化扩展比参考文档更进一步它从kbn/evals导入DefaultEvaluators、Evaluator、Example以及getToolCallSteps、createTrajectoryEvaluator与参考文档中的evaluators.criteria、selectEvaluators出自同一包定义了skipInfraErrors高阶包装器当任务输出中捕获到超时、ECONNREFUSED、5xx 等基础设施错误特征见INFRA_ERROR_PATTERN时让被包装的评估器返回score: null, label: N/A把“环境问题”与“模型质量问题”区分开避免环境抖动拉低均分源码注释明确说明这是 “not a model quality issue”定义了skipNegativeCases对metadata.category negative的反向用例模型应当拒绝的请求返回 N/A避免无意义的负样本污染指标提供了createCriteriaEvaluator、createValidationPassEvaluator、createToolTrajectoryEvaluator、createEfficiencyEvaluator等一组工厂与参考文档 “Wrapping Criteria in a Reusable Evaluator” 的工厂模式一脉相承。该套件的 spec 中还能看到这些包装器被组合使用例如skipInfraErrors(skipNegativeCases(evaluator))这样的洋葱式封装——这正是参考文档模式在真实套件中被复用的直接证据。运行与本地迭代结合 SKILL.md 的 “Running Locally” 一节编写好包含上述评估器的 spec 后可用scripts/evals入口脚本运行# 完整交互流程 node scripts/evals start # 指定被测模型与 judge 模型 node scripts/evals start --model connector-id --judge connector-id # 只跑匹配的单个测试本地迭代推荐 node scripts/evals start --grep my test name # 服务已在运行时直接执行 node scripts/evals run --model connector-id --judge connector-id脚本入口位于 scripts/evals.js。其中--judge参数对应 LLM-as-Judge 评估器所使用的 judge 连接器——使用evaluators.criteria的套件需要单独指定评分模型trace 评估器则要求 EDOT 与TRACING_ES_URL就绪。小结如何选择评估器场景推荐模式类型代价输出结构断言非空、URL 合法、含必备词CODE 评估器 selectEvaluatorsCODE低语义质量回答是否覆盖要点evaluators.criteria或包装成可复用评估器LLM中每次 judge 调用Agent 轨迹是否调用了指定工具/参数正确createToolCallsEvaluator模式steps 检查 criteria 复核CODE LLM中检索质量有 ground truth 文档createRagEvaluatorsPrecision/Recall/F1KCODE低Token 消耗、工具调用数、端到端延迟evaluators.traceBasedEvaluatorsCODE依赖 EDOT低参考文档给出的核心方法论可以概括为能用确定代码判定的绝不动用 LLM judge用 LLM judge 时把准则写成逐条独立、可验证的陈述句通过selectEvaluatorsExampleType, OutputType让类型系统在编译期兜底并在评估器返回值中携带metadata/explanation让每一次 0 分都能追溯到具体证据。掌握了这五点即可在 Kibana 的 evals 体系中编写可维护、可调试的评估套件。【免费下载链接】kibanaYour window into all of your data项目地址: https://gitcode.com/GitHub_Trending/ki/kibana创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表