27届大模型面试准备(二十):评测体系全攻略——Benchmark、数据污染、LLM-as-Judge 与 Arena 对战

📅 2026/8/9 6:28:12
27届大模型面试准备(二十):评测体系全攻略——Benchmark、数据污染、LLM-as-Judge 与 Arena 对战
27届大模型面试准备二十评测体系全攻略——Benchmark、数据污染、LLM-as-Judge 与 Arena 对战上一篇《模型量化全攻略》结尾留了个问题量化之后到底掉了多少点靠什么来回答答案就是评测体系。这一篇是本系列第二十篇也是把前面所有技术串起来的一篇——无论是 RAG、长上下文、后训练还是量化最终都要面对同一个拷问你怎么证明它变好了评测看起来是最没技术含量的环节实际上是大厂面试里区分度最高的题目之一因为它直接暴露一个人有没有真正把模型送上过线。本文按评测的三层结构 → 静态 Benchmark 与它的崩塌 → 数据污染 → LLM-as-Judge → Arena 与 Elo → 业务评测体系搭建展开结尾给面试速答和高频追问清单。一、先建立框架评测的三层结构面试被问你怎么评测大模型最忌讳上来就报菜名MMLU、GSM8K、C-Eval。正确姿势是先给结构大模型评测的三层结构 第三层 业务评测 端到端指标、A/B 实验、人工标注、线上反馈 决策层 回答这次迭代能不能上线 ▲ │ 真实分布成本高样本少 第二层 能力评测 MMLU / GSM8K / HumanEval / 长文本 / 指令遵循 诊断层 回答模型在哪类能力上强、哪类弱 ▲ │ 标准化可比但易污染 第一层 基础指标 PPL、Loss、token 级准确率 冒烟层 回答模型有没有训崩/量化崩三层的关系是逐层放大、逐层可信度提升、逐层成本上升。第一层几分钟出结果但只能判死活第三层要几天但直接决定上线。大部分候选人只会讲第二层讲不出第一层的用途和第三层的设计这就是差距。一个必须说清楚的原则评测指标的选择要匹配决策场景。选基座模型看第二层判断训练是否正常看第一层决定要不要发版看第三层。用第二层的分数去决定发版是最常见的工程错误。二、静态 Benchmark还剩多少价值2.1 主流 Benchmark 分类图谱知识类 MMLU / MMLU-Pro / C-Eval / CMMLU / GPQA └─ 多选题为主考记得住多少 推理类 GSM8K(小学数学) / MATH(竞赛数学) / BBH / DROP └─ 考多步推理对 CoT 敏感 代码类 HumanEval / MBPP / LiveCodeBench / SWE-bench └─ 用单测通过率(passk)判分客观性最强 长文本 LongBench / RULER / 大海捞针(NIAH) / InfiniteBench └─ 考上下文利用率见第十三篇 指令遵循 IFEval / MT-Bench / AlpacaEval └─ 考听不听话、格式约束能否满足 Agent ToolBench / BFCL(函数调用) / AgentBench / WebArena └─ 考工具调用与多步任务见第十八篇 安全 AdvBench / HarmBench / TruthfulQA └─ 考越狱抵抗与幻觉见第十六篇(B系列)2.2 passk唯一真正客观的指标代码类评测之所以最可信是因为有编译器和单测这个绝对裁判。passk 的无偏估计公式要会写对每题采样 n 个候选n ≥ k其中 c 个通过单测 ⎡ C(n-c, k) ⎤ passk E ⎢ 1 - ───────── ⎥ ⎣ C(n, k) ⎦ 直觉C(n-c,k)/C(n,k) 是抽 k 个全是错的概率import numpy as np def pass_at_k(n: int, c: int, k: int) - float: n: 总采样数, c: 通过数, k: 目标 k。无偏估计避免直接用 1-(1-p)^k 的偏差。 if n - c k: return 1.0 # 用连乘避免大数阶乘溢出 return 1.0 - np.prod(1.0 - k / np.arange(n - c 1, n 1)) # 用法每题采样 n20统计通过数再对全体题目求平均 scores [pass_at_k(20, c, k1) for c in per_task_correct_counts] print(pass1 , np.mean(scores))注意面试陷阱直接用1-(1-c/n)^k是有偏的样本量小的时候偏差明显必须用上面的组合数形式。2.3 Benchmark 正在失效的四个原因这部分是高分回答区。原因一数据污染。测试集大量出现在预训练语料里模型是背过答案而非会做题。下一节详述。原因二饱和。GSM8K 上顶尖模型都在 95% 以上剩下的 5% 大部分是标注错误指标已经无法区分模型。这叫天花板效应。应对是升级到更难的版本MATH、AIME、GPQA-Diamond。原因三格式敏感性。同一个模型选项顺序打乱、prompt 模板换一个MMLU 分数能波动好几个点。这说明测的是对特定格式的适应性而非真实能力。同一模型在 MMLU 上的分数波动来源 ┌────────────────────┬──────────────┐ │ 选项顺序 (ABCD 轮换) │ ±2 ~ 4 点 │ │ few-shot 数量 0/5 │ ±3 ~ 6 点 │ │ 答案提取正则 │ ±1 ~ 5 点 │ │ 是否允许 CoT │ ±5 ~ 15 点 │ └────────────────────┴──────────────┘ → 所以跨论文比较分数几乎没有意义 必须自己在统一 harness 下重跑原因四能力与体验脱节。MMLU 高不代表用户觉得好用。用户体验取决于回答的组织、语气、拒答边界、追问处理这些多选题一点都测不到。面试可以这样收尾静态 benchmark 现在的定位更像回归测试而不是能力度量——用来确保这次改动没把已有能力搞坏而不是用来证明模型有多强。真正证明能力要靠 Arena 和业务评测。三、数据污染怎么检测、怎么防3.1 污染的三种形态形态 描述 严重度 ───────────────────────────────────────────────────── 输入污染 测试集的题目出现在训练语料 中 标签污染 题目 标准答案成对出现 高 改写污染 语义相同但表述不同翻译/同义改写 高且难检测改写污染最麻烦字符串匹配查不出来但模型确实见过等价内容。3.2 四种检测方法方法一N-gram 重叠。最基础也是 GPT-3/PaLM 等论文的标准做法。def ngram_contamination(test_text: str, train_corpus_index, n: int 13) - bool: 13-gram 是业界常用阈值GPT-3 用 13-gramLlama 用 8-gram。 train_corpus_index 是预建的 n-gram 哈希集合布隆过滤器更省内存。 toks test_text.split() grams [ .join(toks[i:i n]) for i in range(len(toks) - n 1)] if not grams: return False hit sum(1 for g in grams if g in train_corpus_index) return hit / len(grams) 0.05 # 超过 5% 的 n-gram 命中即判污染局限只能查字面重叠对翻译和改写无效而且需要能访问训练语料——评测闭源模型时根本做不到。方法二困惑度对比法。如果模型在测试集上的 PPL 显著低于同分布的新鲜数据说明可能背过。取测试集 D_test 与同来源但发布时间晚于模型截止日期的 D_fresh 若 PPL(D_test) PPL(D_fresh)且难度相当 → 疑似污染方法三选项顺序扰动顺序敏感性检验。一个巧妙的思路如果模型是真理解把正确答案从 A 挪到 D 不该有影响如果是背下了答案是 A打乱后准确率会暴跌。def order_sensitivity_probe(model, question, options, gold_idx): 把选项做多种轮换看准确率方差。方差极大 → 疑似记忆而非推理。 import itertools, random accs [] for _ in range(8): perm list(range(len(options))) random.shuffle(perm) shuffled [options[i] for i in perm] new_gold perm.index(gold_idx) pred model.choose(question, shuffled) accs.append(int(pred new_gold)) return sum(accs) / len(accs) # 与原始准确率差距过大即为红旗方法四时间切分最可靠。用模型训练截止日期之后发布的题目做评测。LiveCodeBench、AIME 当年真题、LiveBench 都是这个思路。这是目前公认最干净的做法也是面试的加分答案。3.3 工程上怎么防训练前做去污把所有已知评测集的 n-gram 建索引从训练语料中剔除命中样本。自建私有测试集且永不上网这是最实在的一条。业务侧自己标 500~2000 条只在内网使用不发布、不进任何语料。金丝雀字符串canary在测试集文件里嵌入一段随机 UUID之后就可以直接问模型你见过这串字符吗来探测是否被训练进去。BIG-bench 就用了这个技巧。定期换血私有测试集每季度替换 20~30%防止长期使用被间接泄漏比如通过 API 日志。四、LLM-as-Judge便宜但危险开放式生成任务没有标准答案人工评又太贵于是用强模型当裁判成为主流。但它的坑非常多面试官最爱问的就是你怎么保证裁判是公正的。4.1 三种裁判范式单点打分 (Pointwise) 给一个回答打 1-10 分 优点可扩展能算绝对分 缺点分数漂移严重裁判倾向给 7-8 分 两两对比 (Pairwise) A 和 B 哪个更好 优点判断更稳人类一致性最高 缺点O(n²) 次比较 参考答案打分 (Reference-based) 给定标准答案再判 优点最准 缺点需要标准答案成本高工程上的共识能用 pairwise 就别用 pointwise。人类和模型在二选一上都远比打绝对分稳定。4.2 五种已知偏差与对应校正这是本节的核心也是面试的高分点。偏差表现校正方法位置偏差系统性偏好排在前面或后面的回答交换 A/B 各判一次只有两次判断一致才计数不一致记平局长度偏差偏好更长的回答哪怕废话多控制长度分布或用 AlpacaEval 2.0 的长度校正回归自我偏好GPT-4 偏爱 GPT-4 生成的文本用第三方模型做裁判或多裁判投票格式偏差偏好带 markdown 列表、加粗的回答评分标准里显式声明不因排版加分权威偏差回答里出现引用、数字就更信要求裁判逐条核实事实而非整体印象位置偏差的校正代码def pairwise_judge_debiased(judge, question, ans_a, ans_b): 双向判定消除位置偏差两次结论一致才算数否则判平局。 v1 judge(question, firstans_a, secondans_b) # - first|second|tie v2 judge(question, firstans_b, secondans_a) # 顺序交换 # 把第二次的结论映射回 A/B 语义 map2 {first: B, second: A, tie: tie} r1 {first: A, second: B, tie: tie}[v1] r2 map2[v2] if r1 r2: return r1 return tie # 不一致 裁判不可靠保守判平局4.3 裁判 Prompt 的设计要点一个能用的裁判 prompt 至少要有五个部分1. 角色与任务 你是严格的评审判断哪个回答更好 2. 明确的评分维度 正确性 完整性 相关性 表达给出优先级 3. 反偏差声明 不要因为回答更长或排版更好而加分 4. 强制先分析后结论 要求逐维度对比最后一行才给结论CoT 提升一致性 5. 结构化输出格式 固定 JSON便于解析JUDGE_PROMPT 你是严格公正的评审专家。请判断以下两个回答哪个更好。 [用户问题] {question} [回答 A] {ans_a} [回答 B] {ans_b} 评分维度按优先级从高到低 1. 事实正确性 —— 有无事实错误、编造内容 2. 完整性 —— 是否覆盖问题的所有子问题 3. 相关性 —— 有无答非所问、无关铺陈 4. 表达清晰度 —— 逻辑是否连贯 严格遵守 - 不得因回答更长而给更高评价冗长啰嗦应扣分 - 不得因使用 markdown 排版而加分 - 不得因回答风格与你自身相似而偏袒 - 必须先逐维度分析再给结论 输出严格遵循以下 JSON不要有其他内容 {{analysis: {{correctness: ..., completeness: ..., relevance: ..., clarity: ...}}, verdict: A 或 B 或 tie}}4.4 怎么验证裁判本身可信这是面试最容易被追问、也最容易答不上来的一步。答案是用人工标注做校准算一致性。1) 抽 200~500 条样本让 3 位标注员独立标注 2) 先算人类之间的一致性Fleiss Kappa这是天花板 3) 再算 LLM 裁判与人类多数意见的一致率 / Cohens Kappa 4) 判定标准 LLM-人类一致率 ≥ 人类-人类一致率 - 5% → 裁判可用 否则改 prompt / 换裁判模型 / 改用 pairwisefrom sklearn.metrics import cohen_kappa_score # human_major: 人工多数投票结果; llm_votes: LLM 裁判结果 kappa cohen_kappa_score(human_major, llm_votes) # Kappa 参考0.8 极好, 0.6~0.8 可用, 0.4~0.6 勉强, 0.4 不可用 print(fJudge-Human Kappa {kappa:.3f})关键认知LLM 裁判的上限是人类标注的一致性水平。如果一个任务连人类标注员之间都只有 60% 一致比如这个文案更有创意吗那就不该指望 LLM 裁判给出可信结论这类任务应该走 A/B 实验用行为数据说话。五、Arena 与 Elo用群体对战排名5.1 为什么需要 Arena静态 benchmark 测的是固定题目Arena如 LMSYS Chatbot Arena让真实用户提任意问题、盲评两个模型的回答。它的优势是题目分布贴近真实使用、无法被针对性优化、天然抗污染。5.2 Elo 与 Bradley-TerryElo 的更新公式要会写期望胜率: E_A 1 / (1 10^((R_B - R_A)/400)) 分数更新: R_A ← R_A K × (S_A - E_A) S_A ∈ {1, 0.5, 0} K 通常取 4~32K 大则收敛快但抖动大def elo_update(ra: float, rb: float, score_a: float, k: float 16.0): score_a: A 胜1, 平0.5, 负0。返回更新后的 (ra, rb)。 ea 1.0 / (1.0 10 ** ((rb - ra) / 400.0)) eb 1.0 - ea return ra k * (score_a - ea), rb k * ((1 - score_a) - eb)但在线 Elo 有个致命问题结果依赖对战顺序。同一批对战记录换个顺序喂进去排名可能不同。所以 LMSYS 实际用的是Bradley-Terry 模型做最大似然估计——它是顺序无关的且能给置信区间。BT 模型: P(i 胜 j) exp(β_i) / (exp(β_i) exp(β_j)) 用逻辑回归拟合全部对战记录求 β再线性映射到 Elo 尺度 再用 bootstrap 重采样得到 95% 置信区间import numpy as np from sklearn.linear_model import LogisticRegression def bt_ratings(battles, models): battles: [(winner_idx, loser_idx), ...]返回 Elo 尺度分数。 n len(models) X np.zeros((len(battles), n)) y np.ones(len(battles)) for r, (w, l) in enumerate(battles): X[r, w], X[r, l] 1.0, -1.0 lr LogisticRegression(fit_interceptFalse, C1.0, max_iter1000) lr.fit(X, y) # 映射到 Elo 尺度400/ln(10) ≈ 173.72基准 1000 return dict(zip(models, lr.coef_[0] * 173.72 1000))5.3 Arena 的局限面试要能辩证地说-偏好 ≠ 正确。用户投票会偏好自信、详尽、排版好的回答即使有事实错误。Arena 高分模型不一定更准确。-题目分布偏娱乐化。真实 Arena 里大量是闲聊、写诗、脑筋急转弯专业领域覆盖不足。-可被刷榜。通过风格微调更长、更多列表、更热情能显著提升 Arena 名次而实际能力不变。这也是为什么 LMSYS 后来引入了风格控制style control后的榜单。-长尾能力测不到。Arena 测不出 128K 长文本、复杂工具调用这类低频但关键的能力。六、搭一套业务评测体系前面都是通用能力怎么测面试真正想听的是你们自己的系统怎么测。给一套可直接照搬的方案。6.1 整体架构┌─────────────────────────────────────────────────┐ │ 离线评测流水线CI 触发 │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ 回归集 │ │ 能力集 │ │ 安全/红队集 │ │ │ │ 300 条 │ │ 500 条 │ │ 200 条 │ │ │ │ 必须全过 │ │ 看趋势 │ │ 拦截率≥阈值 │ │ │ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │ └────────────┼───────────────┘ │ │ 规则判分 LLM 裁判 │ └──────────────────┬──────────────────────────────┘ │ 通过 ▼ ┌─────────────────────────────────────────────────┐ │ 灰度 / A-B 实验线上 1%~10% 流量 │ │ 行为指标: 采纳率、重问率、会话轮次、人工转接率 │ │ 质量指标: 抽样人工标注 200 条/天 │ │ 成本指标: 单会话 token 成本、P95 延迟 │ └─────────────────────────────────────────────────┘6.2 三类测试集的分工集合规模来源判分方式卡点规则回归集300历史 badcase 修复后沉淀规则/精确匹配为主一条都不能挂挂了直接阻断发布能力集500真实流量分层采样LLM 裁判 pairwise相对上版胜率 ≥ 50%含平局安全集200红队 公开越狱库规则 分类器拦截率不得低于上版回归集是最有价值的资产。每修一个线上 badcase就把它连同期望行为固化成一条用例。半年下来这套集合的业务针对性远超任何公开 benchmark。6.3 落地代码骨架from dataclasses import dataclass from typing import Callable, Literal import json, statistics dataclass class TestCase: id: str kind: Literal[regression, capability, safety] query: str context: dict | None None expect: dict | None None # 规则判分用关键词、正则、JSON schema baseline_answer: str | None None # pairwise 判分用上一版答案 def rule_score(case: TestCase, answer: str) - bool: 规则判分覆盖必含关键词、禁词、JSON 合法性三类硬约束。 exp case.expect or {} if must_include in exp: if not all(k in answer for k in exp[must_include]): return False if must_not_include in exp: if any(k in answer for k in exp[must_not_include]): return False if exp.get(json_schema): try: json.loads(answer) except Exception: return False return True def run_suite(cases: list[TestCase], model: Callable, judge: Callable) - dict: report {regression: [], capability: [], safety: []} for c in cases: ans model(c.query, c.context) if c.kind in (regression, safety): report[c.kind].append({id: c.id, pass: rule_score(c, ans)}) else: v pairwise_judge_debiased(judge, c.query, ans, c.baseline_answer) report[capability].append({id: c.id, verdict: v}) reg_pass all(x[pass] for x in report[regression]) saf_rate statistics.mean([x[pass] for x in report[safety]]) wins sum(x[verdict] A for x in report[capability]) ties sum(x[verdict] tie for x in report[capability]) n max(len(report[capability]), 1) return { regression_all_pass: reg_pass, # 硬卡点 safety_pass_rate: round(saf_rate, 4), # 硬卡点 capability_winrate: round((wins 0.5 * ties) / n, 4), gate: reg_pass and saf_rate 0.98 and (wins 0.5 * ties) / n 0.5, }6.4 统计显著性别忘了500 条样本上胜率 52% 和 48% 有区别吗必须算显著性否则就是在噪声里做决策。from scipy import stats def winrate_significance(wins: int, losses: int, ties: int): 去掉平局做二项检验sign test。p0.05 才认为有真实差异。 n wins losses if n 0: return 1.0, 0.5 p stats.binomtest(wins, n, 0.5, alternativetwo-sided).pvalue return p, wins / n # 经验想检出 5 个点的胜率差异大约需要 400~800 条有效对比样本一个实用经验值要记住要稳定检出 5 个百分点的胜率差异大约需要 400~800 条有效样本。这个数字在面试里说出来会很加分因为它说明你真的做过。七、面试速答Q你会怎么评测一个大模型A分三层。第一层基础指标PPL/Loss只用来判断训练或量化有没有崩几分钟出结果。第二层能力评测用标准 benchmark 做能力画像和回归防护覆盖知识、推理、代码、长文本、指令遵循、Agent、安全七个维度。第三层业务评测才是发版决策依据包括自建回归集、能力集、安全集三套离线数据加上线上 A/B 实验的行为指标。关键原则是指标选择要匹配决策场景——用 MMLU 分数决定要不要发版是典型的工程错误。Q为什么现在大家都说 benchmark 不可信了A四个原因。一是数据污染测试集大量泄漏进预训练语料模型是背过而非会做。二是饱和GSM8K 这类已经普遍 95% 以上剩余误差主要是标注噪声失去区分度。三是格式敏感换个 prompt 模板、打乱选项顺序分数能波动好几个点说明测的是格式适应性而非真实能力。四是能力与体验脱节多选题测不出回答组织、拒答边界、追问处理这些真正影响用户感受的东西。所以 benchmark 现在更适合当回归测试用而不是能力度量。Q怎么检测数据污染A四种手段。N-gram 重叠13-gram 命中率超 5% 判污染是基础做法但只能查字面重叠且需要访问训练语料。困惑度对比法看模型在测试集和同分布新鲜数据上的 PPL 差异。选项顺序扰动是个巧妙的黑盒方法——真理解的模型不该对答案位置敏感打乱后准确率暴跌说明是记忆。最可靠的是时间切分只用模型训练截止日期之后发布的题目LiveCodeBench、LiveBench 都是这个思路。工程上防污染靠训练前 n-gram 去污、自建永不上网的私有测试集、埋 canary 字符串、以及定期换血。QLLM-as-Judge 有哪些偏差怎么校正A五种主要偏差。位置偏差偏好特定位置的回答校正方法是 A/B 交换各判一次两次一致才计数不一致记平局。长度偏差偏好更长回答靠控制长度分布或做长度校正回归。自我偏好偏爱同源模型生成的文本用第三方裁判或多裁判投票。格式偏差偏好 markdown 排版在 prompt 里显式声明不因排版加分。权威偏差见到数字引用就更信要求逐条核实而非整体印象。另外能用 pairwise 就别用 pointwise因为绝对打分的漂移远大于二选一。Q怎么知道你的 LLM 裁判本身是可靠的A必须用人工标注做校准。抽 200~500 条让三位标注员独立标注先算人类之间的 Fleiss Kappa 作为天花板再算 LLM 裁判与人类多数意见的 Cohens Kappa。判定标准是 LLM 与人类的一致率不低于人类之间一致率减 5 个点。Kappa 大于 0.6 才算可用。核心认知是 LLM 裁判的上限就是人类标注的一致性水平——如果连人类都只有 60% 一致这类主观任务就不该用 LLM 裁判应该走 A/B 实验用真实行为数据说话。QArena 的 Elo 是怎么算的有什么问题AElo 用期望胜率E_A 1/(110^((R_B-R_A)/400))和更新式R ← R K(S-E)。但在线 Elo 的结果依赖对战顺序同样的数据换个顺序排名可能变。所以 LMSYS 实际用 Bradley-Terry 模型做最大似然估计它顺序无关再用 bootstrap 给置信区间。Arena 的局限是用户偏好不等于正确性会偏好自信详尽的回答哪怕有错题目分布偏娱乐化专业领域覆盖不足可以通过风格微调刷榜所以后来引入了风格控制榜单长文本、复杂工具调用这类低频关键能力完全测不到。Q模型量化后怎么验证效果A三层递进。第一层 PPL 冒烟只判有没有崩。第二层跑标准 benchmark重点关注对量化最敏感的推理和代码任务——PPL 只掉 0.1GSM8K 可能掉 5 到 10 个点。第三层是业务数据端到端评测如果是 Agent 场景必须专门统计 JSON 结构化输出合法率和工具调用参数准确率量化后这两个指标劣化往往比 PPL 明显得多而它们直接决定线上能不能用。评测时还要控制变量用同一套 harness、同样的采样参数否则对比没有意义。Q500 条测试样本上新版胜率 52%能发版吗A不能直接下结论要先算统计显著性。去掉平局做二项检验如果 p 值大于 0.0552% 和 50% 在统计上无差异这就是在噪声里做决策。经验值是要稳定检出 5 个百分点的胜率差异大约需要 400 到 800 条有效对比样本。如果确实要发正确做法是先看回归集和安全集这两个硬卡点是否全过然后走小流量灰度用线上行为指标采纳率、重问率、人工转接率来做最终判断这些指标的样本量足够大结论更可信。八、高频追问清单passk 为什么不能直接用1-(1-p)^k无偏估计的推导思路是什么如果 MMLU 涨了 3 点但线上用户满意度下降你怎么排查自建评测集时如何做分层采样才能代表线上真实分布LLM 裁判用同一个模型既当选手又当裁判会有什么后果Bradley-Terry 相比在线 Elo 的优势具体在哪置信区间怎么算长文本能力128K该怎么设计评测大海捞针为什么不够Agent 类任务的评测和普通问答有什么本质区别中间步骤要不要评如何评测 RAG 系统检索和生成的问题怎么归因区分下一篇 B19 详述幻觉率该怎么量化有哪些自动化方法各自的假阳性问题是什么多模态模型的评测和纯文本相比多了哪些挑战评测成本太高怎么办有哪些用小样本估计大样本结论的方法如果 CI 里的评测流水线跑一次要 6 小时你会怎么优化至此 A 系列前二十篇覆盖了从架构、训练、对齐到推理、量化、评测的完整链路。下一阶段会转向更前沿的主题MoE 架构细节、推理时扩展test-time scaling、强化学习新范式GRPO 等。B 系列今天的两篇B19 RAG 评估、B20 智能体可观测性刚好和本篇形成呼应——本篇讲怎么评模型那两篇讲怎么评系统。