LLM 评估框架


文档摘要

LLM 评估框架 本节摘要:精确匹配与 F1 漏掉语义等价,人工评审无法规模化,LLM-as-judge 是生产答案——但要配上足够的校准才能信任这个数字。你的 RAG 系统答「June 29th, 2007」,金标准是「June 29, 2007」,精确匹配给 0、F1 约 75%、人会给 100%;再乘以一万条用例,再乘以每次改检索器、分块、提示、模型,你需要一个懂含义、规模便宜、不在回归上撒谎、能暴露正确失败模式的评估器。

LLM 评估框架

本节摘要:精确匹配与 F1 漏掉语义等价,人工评审无法规模化,LLM-as-judge 是生产答案——但要配上足够的校准才能信任这个数字。你的 RAG 系统答「June 29th, 2007」,金标准是「June 29, 2007」,精确匹配给 0、F1 约 75%、人会给 100%;再乘以一万条用例,再乘以每次改检索器、分块、提示、模型,你需要一个懂含义、规模便宜、不在回归上撒谎、能暴露正确失败模式的评估器。2026 有三个框架把持这个问题:RAGAS 给出 RAG 四维(忠实度、答案相关、上下文精确、上下文召回)配 NLI+LLM-judge 后端;DeepEval 是「LLM 的 pytest」,G-Eval、任务完成、幻觉、偏见指标原生融入 CI/CD;G-Eval 是一种方法(也是 DeepEval 的指标)——带思维链、自定义准则、0~1 评分的 LLM-as-judge。三者都靠 LLM-as-judge,本节讲透这个方法及其外围的信任层:为何它工作(GPT-4o-mini 约 0.003 美元/条,千样本回归不到 5 美元),为何它会静默失败(评判者偏置、JSON 解析失败、模型版本漂移),以及为何在拿到与人标注的 Spearman 相关 >0.7 之前绝不要信任原始评分。

对应原课程:Phase 5 · Lesson 27 · llm-evaluation-frameworks(原英文 phases/05-nlp-foundations-to-advanced/27-llm-evaluation-frameworks/docs/en.md)。前置依赖:第 13 节(问答系统)、第 14 节(信息检索)。

学习目标

阅读完本节,你应当能够:

  1. 说清 RAG 四维(忠实度、答案相关、上下文精确、上下文召回)各自问什么、用什么后端。
  2. 从零实现基于 NLI 的忠实度与基于假设问题生成的答案相关度。
  3. G-Eval 定义自定义准则,并把 DeepEval 接成 pytest CI 门。
  4. 识别 LLM-as-judge 的静默失败(评判者偏置、JSON 解析、版本漂移),并用校准建立信任。

一、问题与直觉

你的 RAG 系统答:「June 29th, 2007.」金标准是:「June 29, 2007.」精确匹配 0 分,F1 约 75%,人会打 100%。

再乘以一万条测试用例。再乘以每次对检索器、分块、提示、模型的改动。你需要一个懂含义、规模便宜、不在回归上撒谎、能暴露正确失败模式的评估器。

2026 有三个框架把持这个问题:

  • RAGAS(Retrieval-Augmented Generation ASsessment):四个 RAG 指标(忠实度、答案相关、上下文精确、上下文召回),配 NLI + LLM-judge 后端。研究支撑、轻量。
  • DeepEval:LLM 的 pytest。G-Eval、任务完成、幻觉、偏见指标。原生 CI/CD。
  • G-Eval:一种方法(也是 DeepEval 的指标)——带思维链、自定义准则、0~1 评分的 LLM-as-judge。

三者都靠 LLM-as-judge。本节为这个方法及其外围信任层建立直觉。

LLM-as-judge:用一个 LLM 在评分量表(rubric)下给输出打分,取代静态指标。给定 (查询, 上下文, 答案),提示一个评判 LLM:「按忠实度打 0~1」,返回分数。

为何它工作:LLM 以极低成本逼近人类判断。GPT-4o-mini 约 0.003 美元/条,千样本回归评估不到 5 美元。

为何它会静默失败:

  1. 评判者偏置:评判者偏好更长的答案、同模型家族的答案、与提示风格匹配的答案。
  2. JSON 解析失败:坏的 JSON → NaN 分数 → 静悄悄被排除出聚合。RAGAS 用户都懂这痛。要用 try/except + 显式失败模式把关。
  3. 跨模型版本漂移:升级评判者会改每个指标。冻结评判者模型 + 版本。

RAG 四维:

指标 问题 后端
忠实度 答案里每条论断是否来自检索上下文? 基于 NLI 的蕴含
答案相关 答案是否回应了问题? 从答案生成假设问题,与真问题对比
上下文精确 检索块里,相关的占多少? LLM-judge
上下文召回 检索是否返回了所需的一切? 对金答案的 LLM-judge

G-Eval:定义一个自定义准则:「答案是否引用了正确来源?」框架自动扩成思维链评估步骤,再打 0~1。适合 RAGAS 覆盖不到的领域专用质量维度。

💡 校准:在与人类标签建立相关之前,绝不要信任原始评判分数。跑 100 个手标样例,绘制评判 vs 人,算 Spearman rho。若 rho < 0.7,你的评判 rubric 还需打磨。

二、从零实现

第 1 步:用 NLI 做忠实度(RAGAS 风格)

from typing import Callable from transformers import pipeline nli = pipeline("text-classification", model="MoritzLaurer/DeBERTa-v3-large-mnli-fever-anli-ling-wanli", top_k=None) # `llm` 是任何可调用对象:提示字符串 -> 生成字符串。 # 例:llm = lambda p: client.messages.create(model="claude-haiku-4-5", ...).content[0].text LLM = Callable[[str], str] def atomic_claims(answer: str, llm: LLM) -> list[str]: prompt = f"""Break this answer into simple factual claims (one per line): {answer} """ return llm(prompt).splitlines() def faithfulness(answer: str, context: str, llm: LLM) -> float: claims = atomic_claims(answer, llm) if not claims: return 0.0 supported = 0 for claim in claims: result = nli({"text": context, "text_pair": claim})[0] entail = next((s for s in result if s["label"] == "entailment"), None) if entail and entail["score"] > 0.5: supported += 1 return supported / len(claims)

把答案拆成原子论断,逐条对检索上下文做 NLI,忠实度 = 被支持的比例。

第 2 步:答案相关度

import numpy as np from sentence_transformers import SentenceTransformer # encoder: 任何实现 .encode(texts, normalize_embeddings=True) -> ndarray 的模型 # 例:encoder = SentenceTransformer("BAAI/bge-small-en-v1.5") def answer_relevance(question: str, answer: str, encoder, llm: LLM, n: int = 3) -> float: prompt = f"Write {n} questions this answer could be the answer to:\n{answer}" generated = [line for line in llm(prompt).splitlines() if line.strip()][:n] if not generated: return 0.0 q_emb = np.asarray(encoder.encode([question], normalize_embeddings=True)[0]) g_embs = np.asarray(encoder.encode(generated, normalize_embeddings=True)) sims = [float(q_emb @ g_emb) for g_emb in g_embs] return sum(sims) / len(sims)

若答案暗示的问题与所问的不同,相关度就掉。

第 3 步:G-Eval 自定义指标

from deepeval.metrics import GEval from deepeval.test_case import LLMTestCaseParams, LLMTestCase metric = GEval( name="Correctness", criteria="The answer should be factually accurate and match the expected output.", evaluation_steps=[ "Read the expected output.", "Read the actual output.", "List factual claims in the actual output.", "For each claim, mark supported or unsupported by the expected output.", "Return score = fraction supported.", ], evaluation_params=[LLMTestCaseParams.INPUT, LLMTestCaseParams.ACTUAL_OUTPUT, LLMTestCaseParams.EXPECTED_OUTPUT], ) test = LLMTestCase(input="When was the first iPhone released?", actual_output="June 29th, 2007.", expected_output="June 29, 2007.") metric.measure(test) print(metric.score, metric.reason)

评估步骤就是 rubric。显式步骤比隐式的「打 0~1」更稳。

第 4 步:CI 门

import deepeval from deepeval.metrics import FaithfulnessMetric, ContextualRelevancyMetric def test_rag_system(): cases = load_regression_cases() faith = FaithfulnessMetric(threshold=0.85) rel = ContextualRelevancyMetric(threshold=0.7) for case in cases: faith.measure(case) assert faith.score >= 0.85, f"faithfulness regression on {case.id}" rel.measure(case) assert rel.score >= 0.7, f"relevancy regression on {case.id}"

作为 pytest 文件发布,每个 PR 上跑,在回归上挡合并。

第 5 步:从零手搓评估

code/main.py。纯标准库的忠实度近似(答案论断与上下文的重叠)与相关度近似(答案 token 与问题 token 的重叠)。非生产用,展示形状。

三、框架对比

陷阱

  • 无校准:与人标只有 0.3 相关的评判者就是噪声。发布前必须有校准跑。
  • 自评:用同一 LLM 生成又评判,会把分数抬高 10~20%。评判用不同模型家族。
  • 两两评判的位置偏置:评判者偏好先呈现的选项。总随机化顺序并两边都跑。
  • 原始聚合藏失败:均值 0.85 常藏住 5% 的灾难性失败。总检查最低分位数。
  • 金数据集腐烂:未版本化、随时间漂移的评估集破坏纵向比较。每次改动都给数据集打标签。
  • LLM 成本:规模上,评判调用主导成本。用达到校准阈值的最便宜模型:GPT-4o-mini、Claude Haiku、Mistral-small。

2026 的栈:

用例 框架
RAG 质量监控 RAGAS(4 指标)
CI/CD 回归门 DeepEval + pytest
自定义领域准则 DeepEval 内的 G-Eval
在线实时流量监控 RAGAS 无参考模式
人在环抽检 LangSmith 或 Phoenix 配标注 UI
红队 / 安全评估 Promptfoo + DeepEval

💡 典型栈:RAGAS 监控、DeepEval 做 CI、G-Eval 做新维度。三者都跑,它们有用的分歧。

四、可复用产物

保存为 outputs/skill-eval-architect.md:

--- name: eval-architect description: Design an LLM evaluation plan with calibrated judge and CI gates. version: 1.0.0 phase: 5 lesson: 27 tags: [nlp, evaluation, rag] --- Given a use case (RAG / agent / generative task), output: 1. Metrics. Faithfulness / relevance / context-precision / context-recall + any custom G-Eval metrics with criteria. 2. Judge model. Named model + version, rationale for cost vs accuracy. 3. Calibration. Hand-labeled set size, target Spearman rho vs human > 0.7. 4. Dataset versioning. Tag strategy, change log, stratification. 5. CI gate. Thresholds per metric, regression-window logic, bottom-quantile alert. Refuse to rely on a judge untested against ≥50 human-labeled examples. Refuse self-evaluation (same model generates + judges). Refuse aggregate-only reporting without bottom-10% surfacing. Flag any pipeline where judge upgrade lands without parallel baseline eval.

五、练习

  1. 基础:在 10 条已知含幻觉的 RAG 例上用 RAGAS,验证忠实度指标能逐条抓到。
  2. 进阶:手标 50 条 QA 答案的 0~1 正确性,用 G-Eval 打分,测评判与人之间的 Spearman rho。
  3. 挑战:用 DeepEval 搭一个 pytest CI 门,故意让检索器回归,验证门失败,再通过对最低 10% 的阈值检查加底部分位数告警。

本节要点回顾

  1. 精确匹配与 F1 漏语义等价,人工不可规模化:LLM-as-judge 是生产答案,但要配校准。
  2. RAGAS 四维无参考:忠实度、答案相关、上下文精确、上下文召回,NLI+LLM-judge 后端。
  3. 忠实度 = 原子论断被蕴含比例:拆答案成原子论断,逐条对上下文 NLI。
  4. 答案相关 = 假设问题相似度:从答案生成假设问题,与真问题比嵌入相似。
  5. G-Eval 是带思维链的自定义评判:显式评估步骤比隐式「打 0~1」更稳。
  6. DeepEval 是 LLM 的 pytest:原生 CI/CD,做回归门,挡合并。
  7. 静默失败三种:评判者偏置(偏好长答案/同家族)、JSON 解析失败变 NaN、模型版本漂移。
  8. 校准是信任的前提:对 100 条手标注算 Spearman rho,rho<0.7 则 rubric 需打磨。
  9. 自评抬高 10~20%:评判用不同模型家族;两两评判要随机化顺序两边跑。
  10. 聚合藏灾难:均值 0.85 可能藏 5% 灾难,总检查最低分位数;评判模型要冻结版本。

下一节,我们把评估视角推到极限——进入「长上下文评估」,看「迷失在中间」、针插草堆、RULER 与 LongBench 如何测一个模型在十万 token 窗口里到底记住了多少。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U