Chapter 04

工具与前沿:用什么评,以及这个领域正在往哪走

前三章建立了概念、方法、流程——这章给生态(8 个工具怎么选)和走向(2026 年什么稳定、什么在变、什么过时)。

本章你将建立的 schema

  • 每个 eval 框架内核都是同一个手写 judge:一段 prompt + 一份 rubric + 一段解析;框架替你管的是数据集、并发、追踪。
  • 工具生态按两轴定位——库 ↔ 平台、OSS ↔ SaaS;选型先看你要的是单测式断言还是生产 online 监控。
  • 2026 年中的方法学拐点:从比能力转向比可靠性(pass^k、轨迹 eval、judge 校准、HAL),知道哪些做法已被取代。

4.1先手写一个最小 judge,看清机制

一个 LLM-as-a-judge 评估器,剥到底就是三样东西:一段 prompt、一份 rubric(评分标准)、一段把模型回复解析成分数的代码。

为什么先手写

本章后面横评的 8 个工具,没有一个在 judge 这件事上做了魔法。它们包的都是同一个核:把待评样本塞进一段 prompt,附上 rubric,调一次模型,解析出分数。先把这个核手写一遍,后面看任何框架的 GEval / faithfulness / Evaluator 都会还原成同一个形状——差别只在它替你管了什么。

下面是一个示意版(非完整可运行,省略了 SDK 初始化与重试)。读它的目的不是抄来跑,而是看清"judge 到底在做什么"。

minimal_judge.py · 示意 Python
# 示意代码:剥到底的 LLM-as-a-judge。省略 SDK 初始化、重试、并发。
import json, re

RUBRIC = """评估下面这条回复,按 1-5 打分:
5=完全正确且完整  4=正确但有小遗漏  3=部分正确
2=大体错误  1=完全错误或答非所问
只依据【参考答案】判对错,不要被回复的语气或长度影响。"""

JUDGE_PROMPT = """{rubric}

【问题】{input}
【参考答案】{reference}
【待评回复】{output}

输出严格的 JSON:{{"score": <1-5 整数>, "reasoning": "<一句话理由>"}}"""

def judge(input, output, reference, call_model):
    # 1) 把样本 + rubric 拼成一段 prompt
    prompt = JUDGE_PROMPT.format(
        rubric=RUBRIC, input=input, output=output, reference=reference)
    # 2) 调一次模型(call_model 是任意 LLM 客户端)
    raw = call_model(prompt, temperature=0)
    # 3) 解析出结构化分数 —— 框架替你做的容错就加在这一步
    m = re.search(r"\{.*\}", raw, re.DOTALL)
    data = json.loads(m.group(0))
    return int(data["score"]), data["reasoning"]

score, why = judge(
    input="法国的首都是哪里?",
    output="巴黎,它也是法国最大的城市。",
    reference="巴黎",
    call_model=my_llm)            # 你自己的模型调用
print(score, why)                 # 5 "回复给出了正确的首都巴黎"
RUBRIC这就是"评分标准"——把"什么算好"写成模型能读的话。 步骤 2temperature=0 降随机性;但 judge 仍是非确定的,这点回到 §4.4 的 pass^k。 步骤 3解析是最脆的一环——模型偶尔不吐合法 JSON,框架的价值很大一部分就在这里的容错与重试。

把这个 judge 套在一整个数据集上反复跑,就是一个 regression(回归)runner——每次模型或 prompt 改动后,重跑同一批样本看分数有没有掉。这正是 ch03 离线回归集的执行形态:

regression_runner.py · 示意 Python
# 示意:把单个 judge 套到整个数据集 —— 这就是一个回归 runner。
def run_regression(dataset, system_under_test, judge_fn):
    rows = []
    for ex in dataset:                       # dataset: 一批 {input, reference}
        output = system_under_test(ex["input"])   # 跑被测 agent / RAG
        score, why = judge_fn(ex["input"], output, ex["reference"])
        rows.append({"input": ex["input"], "score": score, "why": why})
    avg = sum(r["score"] for r in rows) / len(rows)
    return avg, rows                          # avg 就是这一版的回归分

# 改 prompt / 换模型 / 调检索后重跑,比较 avg 有没有回退(regression)。

这 ~20 行就是整个 eval 工具生态的地基。后面所有框架做的,是在这个 runner 外面套上:数据集版本管理、并发与限流、trace(把每次调用的中间步骤记下来)、多 judge 投票、统计区间。机制没变,变的是工程规模。

想一想

上面的 judge 把 temperature 设成了 0。既然如此,同一条样本跑两次,分数还会变吗?

展开答案(先停 10 秒再点)

仍可能变。temperature=0 只是把采样推向最高概率 token,并不保证确定性——多数生产 API 在这个设置下仍不保证逐字节可复现(浮点累加顺序、批处理、后端版本都会引入抖动)。judge 本身是个 LLM,因此 eval 结果天然带噪声。

这正是 §4.4 要讲的 pass^k 存在的理由:单次跑出的分数不可全信,可靠性要靠多次重复来测。

4.2八个工具横评

认清了内核,选型就从"学哪个 API"变成"要的是哪种封装"。下表把 2026 年中主流的 8 个 eval 工具按同一组维度排开。核心原语(primitive)指这个工具让你直接操作的最小对象——是写一个 assert、定义一个 scorer,还是配一份 YAML。

表 4.1 · 八个 eval 工具横评(截至 2026-06)
工具类型核心原语自带指标何时选它
Ragas OSS 指标函数(对一批样本算分) faithfulness、context_precision / recall、answer_relevancy、noise_sensitivity 评 RAG 的检索 + 生成质量,事实标准的指标库
DeepEval OSS LLMTestCase + assert_test()(阈值不过抛错) GEval 自定义判据、ToolCorrectness、TaskCompletion(agent 维度) 把 eval 当单测塞进 CI(Python 生态)
LangSmith SaaS(LangChain 原生) Dataset / Example + Experiment + Trace + Evaluator heuristic / LLM-judge / pairwise 比较 / 人工标注队列 已用 LangChain / LangGraph,要 trace + eval 一体
Langfuse OSS + 云 通用 Score 对象(NUMERIC / CATEGORICAL / BOOLEAN)挂到 trace / session / dataset-run managed judge 模板、Ragas 集成 自托管 + 生产 online eval(线上实时打分)
Arize Phoenix OSS(OpenTelemetry 原生) Dataset / Experiment / Span 预置 evaluators:Hallucination、QA、Relevance、Toxicity 已用 OTel 标准,tracing 与 eval 同栈
Promptfoo OSS(CLI) promptfooconfig.yaml:providers × prompts × tests,每 test 带 assert 确定性 equals / regex / is-json / cost / latency + model-graded llm-rubric / factuality / context-faithfulness prompt 回归当 CI gate,不想写 Python
Braintrust SaaS(autoevals 开源) Experiment + Scorer(输出 0-1)+ Span / Trace autoevals 库:Factuality、ClosedQA、移植自 Ragas 的 RAG 指标、heuristic(Levenshtein / ExactMatch / JSONDiff) 托管平台 + 现成 scorer 库(TS / Python)
OpenAI Evals OSS JSONL 样本 + YAML 注册 eval + completion fn grader 模板:Match、Includes、model-graded fact / closedqa 跑 / 贡献标准 benchmark

八个名字摊开容易眼花,但它们在两条轴上各就各位:横轴是你写代码还是用现成平台(库 ↔ 平台),纵轴是自己托管还是托管在别人那(OSS ↔ SaaS)。把它们摆进四象限,选型直接落到象限上。

库 library 平台 platform SaaS 托管 OSS 开源 Ragas DeepEval OpenAI Evals Arize Phoenix OTel 原生 Langfuse OSS + 云 Promptfoo CLI LangSmith LangChain 原生 Braintrust autoevals 开源 整合最快的一格
图 4.1八个工具按"库 ↔ 平台 × OSS ↔ SaaS"落位。 注意:eval 库和可观测性(observability)平台正在合并,右上角(SaaS 平台)这一格在快速整合——§4.4 的并购就发生在这里。

四象限给的是"哪一类",下面三段把它落到具体决策。

从手写 judge 映射到框架

回到 §4.1 那段手写 judge。它在三个框架里分别长这样,但内核完全相同:

  • DeepEval 的 GEval:你给一段自然语言判据("回复是否只依据参考答案、不被语气影响"),它内部就是把判据当 rubric 拼进 prompt、调模型、解析分数——和 §4.1 的 RUBRIC + judge() 一一对应。
  • Ragas 的 faithfulness:rubric 被固定成"回复里的每条陈述能否由检索到的 context 支持",prompt 和解析都预置好了。你不写 rubric,因为它替 RAG 场景写死了。
  • LangSmith 的 Evaluator:同一个 judge 被包成一个挂在 Experiment 上的对象,额外帮你记录每次调用的 trace、对接人工标注队列。judge 逻辑没变,多的是数据集与追踪管理。
洞察 · 框架替你管什么

三者本质都是同一个"prompt + rubric + 解析"。框架的价值不在 judge 本身,而在它替你管掉的周边:数据集版本、并发与限流、trace、多 judge 投票、统计区间。选型不是选"谁的 judge 更准",是选"框架该替你管掉哪些周边"。

主轴:先用 OSS 库(Ragas + DeepEval)起步。评 RAG 检索与生成,Ragas 的 faithfulness / context recall 是事实标准,装上就能算。要把 eval 当单测、用阈值卡住 CI,DeepEval 的 assert_test() 不达标直接抛错,和 pytest 无缝。两者都是纯库,零基础设施,本地一条命令跑完——这是绝大多数项目该起步的地方。

何时毕业到托管平台(LangSmith / Langfuse)。当需求从"算个分"变成三件事——要 trace(逐步看 agent 中间调用,对应 ch01 的轨迹层)、要团队协作(共享数据集、人工标注队列、跨实验对比)、要生产 online 监控(线上请求实时打分、按 session 聚合)——纯库就撑不住了,这时上 LangSmith(已在 LangChain 栈里最顺)或 Langfuse(要自托管 + 数据不出域时选它)。不要为了"显得专业"过早上平台;先有回归集,再有平台。

想一想

团队只有 Python 脚本、想把 eval 塞进 CI、坚决不上 SaaS。从 8 个里选哪个?如果团队不写 Python,只想用 YAML 配 prompt 回归呢?

展开答案(先停 10 秒再点)

写 Python:DeepEval——LLMTestCase + assert_test() 就是 pytest 风格,阈值不过抛错,CI 直接红。补充指标可叠 Ragas。

不写 Python:Promptfoo——一份 promptfooconfig.yaml 列 providers × prompts × tests,每条 test 挂 assert(确定性的 equals/regex,或 model-graded 的 llm-rubric),CLI 一跑就是 CI gate。

两者都是 OSS、都不需要 SaaS。分水岭只是"断言写在 Python 里还是 YAML 里"。

4.3前沿之一:agent benchmark 全景(截至 2026-06)

上面是"评自己系统"的工具。另一类东西是公开 benchmark:一批固定任务 + 一个统一指标,用来横向比不同 agent / 模型的能力。读懂它们能让你判断一个模型的"SWE-bench 70%"到底意味着什么,也能借它们的指标设计反哺自己的 eval。

表 4.2 · 主流 agent benchmark(年份 + 测什么 + 关键指标,截至 2026-06)
Benchmark年份测什么关键指标 / 现状
SWE-bench / SWE-bench Verified Princeton 2023 / OpenAI 协作 2024-08(500 条人工校验) 解真实 GitHub issue:给仓库 + issue,改代码让测试通过 % resolved(测试通过率)。2026-06 顶部约 0.94,高位接近饱和
GAIA Meta 2023-11(466 任务) 通用助手任务:多步、需用工具与检索的真实问题 exact-match(答案精确匹配)
τ-bench / τ²-bench Sierra 2024-06 / arXiv 2506.07982 2025-06 tool-agent-user 客服对话:agent 调工具 + 与模拟用户多轮交互 引入 pass^k(k 次全部成功,按 p^k 衰减)——非确定性的标准可靠性指标。τ² 加 dual-control(用户也能用工具)
Terminal-Bench Stanford + Laude,arXiv 2026-01(2.0 于 2025-11,89 任务) Docker 里的真实 shell 任务:在终端里完成运维 / 编译 / 调试 任务完成率,frontier 模型 < 65%
OSWorld / OSWorld-Verified NeurIPS 2024 / 2025-07 computer-use:在真实操作系统里点鼠标、敲键盘完成任务 任务成功率,Claude Opus 4.6 约 0.73(2026-06)
BrowseComp OpenAI 2025-04(1266 条难多跳浏览) 深度网页浏览:需多跳检索 + 信息综合才能答的难题 Deep Research 51.5% vs GPT-4o+tools 1.9%——专门 agent 与通用模型差距巨大
洞察 · 好 benchmark 的设计趋势

把这几个排在一起看年份,趋势很清楚:新 benchmark 越来越强调三件事——多次跑(pass^k,不靠单次撞运气)、报成本(解一道题烧多少 token / 美元)、抗污染(题目不在训练集里,SWE-bench Verified 的人工校验就是为此)。设计自己的 eval 时,这三条同样适用。

想一想

τ-bench 用 pass^k 而不是 pass@1,BrowseComp 让 GPT-4o+tools 只拿到 1.9%。这两个数字分别在提醒读者什么?

展开答案(先停 10 秒再点)

pass^k:客服 agent 必须每次都对,偶尔成功没有意义。pass^k 测"连续 k 次是否全过",把非确定性暴露出来——一个 pass@1=90% 的 agent,pass^8 可能掉到 43%(0.9⁸)。

1.9%:通用模型加几个工具,远不等于一个为深度浏览专门优化的 agent。能力差距来自任务编排、检索策略、长程规划——不是把模型换大就能补上。这也是为什么"模型分高"不等于"agent 好用"。

4.4前沿之二:方法学正在往哪走(最近 6-12 个月)

工具和 benchmark 是表层,底下是方法学在移动。最近 6-12 个月有六条线索,每条都在把 eval 从"测一次能力"推向"测可靠性"。

1 · pass^k 取代单次 pass@1

单次跑(pass@1)掩盖非确定性:"这次 90% 通过"下一次可能挂。pass^k 测同一批任务连跑 k 次是否全部通过——只要有一次失败就不算过。τ-bench(2024-06)把它带进主流,因为客服 agent 的可靠性必须用重复来量。这是 §4.1 末尾那个 temperature=0 仍不确定问题的直接回应。

2 · 轨迹 eval 升为一等公民

过去只看最终答案对不对;现在 agent 走了哪条路(调了哪些工具、顺序如何)本身要被评。LangSmith 在 2025-26 上线 Multi-turn Evals,分三模式——Final-Response(只看终答)、Single-step(看单步动作)、Trajectory(看整条轨迹);配套的 agentevals 库提供参考轨迹匹配器。这把 ch01 讲的轨迹层从概念变成了产品里的一等评估对象。

3 · LLM-as-jury 与 judge 校准

judge 本身会偏:自我偏好(self-preference,NeurIPS 2024)、position / verbosity bias(偏向靠前或更长的回复,IJCNLP 2025)、"Silent Judge" 捷径偏差(judge 走捷径不真正读内容,2025-09)、Judge Reliability Harness(2026)。修复手段在成形——多 judge 组成陪审团(LLM-as-jury)投票降单 judge 偏差、对 judge 跑 IRT(项目反应理论)估其区分度、给 judge 的灵敏度 / 特异度报置信区间。"谁来验证验证者"已写进 ACL 审稿指南。这回链 ch02 的 judge 校准与 judge 偏差。

4 · 从比能力转向比可靠性

最强的机构信号:HAL(Holistic Agent Leaderboard,Princeton,ICLR 2026)暂停了能力排名,转做可靠性(一致性 / 鲁棒性 / 安全)评估,并同时报成本。一个公开榜单主动放弃"谁分最高"的排法,本身就是"准确率不够"这个判断的最强背书。

5 · error-analysis-first / eval-driven 之争

Hamel Husain 与 Shreya Shankar 的《LLM Evals: Everything You Need to Know》(2026-01-15)主张:先人工读 trace,为读到的真实错误现写 evaluator,而不是先搬一套通用指标。这条路线把 eval 的起点从"指标库"挪到"看数据",回链 ch03 的错误分析。

6 · 工具层合并(eval × observability)

2026 年初一连串并购印证了图 4.1 右上角那一格的整合:OpenAI 收购 Promptfoo(约 $86M)、Langfuse 被 ClickHouse 收购、Braintrust 完成 $80M B 轮。模式趋同——OSS 版本管 PR 级(开发期回归 gate),商业版本管生产 / 合规(线上监控、审计、团队协作)。

把这六条按"还在不在动"分三桶,读者一眼就知道哪些可以放心学、哪些要追、哪些别碰。

稳定 · 放心学 四层评估模型 LLM-as-a-judge 离线回归集 SWE-bench / GAIA 在变 · 6-12 月要追 pass^k 轨迹 eval LLM-as-jury HAL:转向 可靠性 + 成本 工具层并购 已被取代 · 别学 BLEU / ROUGE 评开放式生成 单次 pass@1 demo 凭感觉 盲信榜单 头部分数
图 4.2三桶:把本教程涉及的 eval 做法按"还在不在动"分类。 注意:中间一桶(在变)全是最近 6-12 个月的方向,主题都指向同一件事——从比能力转向比可靠性。
已被取代 · 别学这些

BLEU / ROUGE 评开放式生成——它们是 n-gram 重叠度量,对语义等价无能("巴黎"与"法国首都"几乎零重叠却同义),回链 ch02 的语义等价问题。开放式回复别再用它们当主指标。

单次 pass@1——掩盖非确定性,用 pass^k 取代。

凭 demo 感觉评判——三五条手试样本不构成 eval,撞运气而非测量。

盲信 leaderboard 头部分数——高位 benchmark 普遍饱和 + 受数据污染影响(SWE-bench 顶部已约 0.94),头部名次的区分度很低,看趋势别看绝对排名。

想一想

一个 agent 团队报告"线上 90% 通过率"。为什么资深工程师不会照单全收?至少给两个理由。

展开答案(先停 10 秒再点)

理由一:单次 pass@1 掩盖非确定性。90% 是单次跑的均值,agent 是非确定的——同一批任务再跑一遍可能是 85%,关键路径上"偶尔挂"在生产里就是事故。要看 pass^k。

理由二:数据集可能已污染或不代表线上分布。如果这 90% 来自一个公开 / 老旧测试集,模型可能见过题;或者测试集分布和真实流量不一致,线下高分线上照样翻车。

理由三(加分):没有报成本与轨迹——90% 是怎么达成的?烧了多少 token、走了多少弯路?HAL 暂停能力排名转报可靠性 + 成本,正是因为单一通过率说明不了问题。

§本章 self-check

先合上教程,把你能想到的答案写在纸上或编辑器里。 写完再点开答案对照——直接点开等于把这一节当再读一遍。

  1. 把"任何 eval 框架都是同一个手写 judge 的封装"这句话说清楚:手写 judge 的三要素是什么?框架额外替你管的是什么?
  2. 团队已经全栈用 LangGraph,需要逐步追踪 agent 的中间调用并对轨迹打分。从 8 个工具里选哪个?理由是什么?(这是一道选型判别题)
  3. pass^k 和 pass@1 的差别是什么?为什么 τ-bench 这类客服 agent benchmark 必须用 pass^k?
  4. 列出图 4.2 "已被取代"桶里的四项,并各用一句话说明它被什么取代或为什么不可信。
答案(先做完再展开)
  1. 三要素:① 一段 prompt、② 一份 rubric(把"什么算好"写成模型能读的标准)、③ 一段把模型回复解析成结构化分数的代码。框架额外管:数据集版本、并发与限流、trace、多 judge 投票、统计区间——judge 内核不变,变的是工程规模。
  2. 选 LangSmith。它是 LangChain / LangGraph 原生,trace 与 eval 一体;且 2025-26 已上 Trajectory 模式专门对整条轨迹打分。已在该栈里时它最顺;若要自托管 + 数据不出域,则换 Langfuse。
  3. pass@1 测单次是否通过,pass^k 测连跑 k 次是否全部通过(有一次失败即不算过)。客服 agent 必须每次都对,单次成功无意义;pass^k 把非确定性暴露出来,是非确定系统的标准可靠性指标。
  4. ① BLEU / ROUGE 评开放式生成——被 LLM-as-judge / 语义指标取代,n-gram 重叠对语义等价无能;② 单次 pass@1——被 pass^k 取代,掩盖非确定性;③ demo 凭感觉——不是测量,撞运气;④ 盲信榜单头部分数——高位饱和 + 数据污染使区分度低,看趋势不看绝对名次。
进阶挑战 · 刚好够不着

给你自己的 judge 加一层 jury,并量化它值不值

拿 §4.1 的手写 judge,把它扩成 LLM-as-jury:用三个不同模型各打一次分,取多数票(或中位数)当最终分。问题是——你怎么证明这个 jury 比单 judge 更可靠,而不是只是更贵?设计一个最小实验来回答。

提示(卡住再展开)

先要一小批带人工金标签的样本(比如 50 条,人来定 1-5 分)。分别让单 judge 和三模型 jury 跑这批,各自和人工标签算一致性(如 Cohen's κ 或相关系数)。jury 的一致性要显著高于最好的单 judge,才算"值"。再把每条的成本记下来,画一张"一致性增益 vs 成本增量"——回链 §4.3 的"报成本"和 ch02 的校准:jury 不是无脑加 judge,是要用金标签证明区分度真的提升了。