第 23 章:通用验证——Universal Verification
第 23 章:通用验证——Universal Verification
"验证"看起来是一堆散落的具体任务:核对引用、检查幻觉、评审回复、给 agent 打分。但它们在结构上是同一件事——给一段产物、一组要求,返回一个布尔或分数。把这件事抽象成可复用的能力,你就同时拿到了评测、回归门和线上护栏。本章讲怎么把验证做成通用能力,以及怎么验证"验证者"自己。
验证的两副面孔:Verifier 与 Judge
同一个词"验证",在工程里其实分两种用法,混用会带来麻烦。
Verifier 针对一条明确的、可拆解的要求做布尔核实:这段回答有没有引用?有没有承诺做不到的事?引用的来源真的支持这个结论吗?它的要求是一张可枚举的清单,每条发一个 Noul,答案可解释、可逐条复盘。
Judge 则是对一段产物做整体评判,输出一个分数或一个排序:这条回答整体质量如何、这几份简历谁更强。它给出的是整体印象,便于比较,但"为什么是 7 分"更难说清。
区别决定了用法。Verifier 最关键的性质是可复现——同一条要求,今天判真明天不该判假;Judge 最关键的性质是与人类评级一致(校准)——你给的 0.8 分,必须基本对应人类打出的水平。两者都建立在第 2 章的三种输出上:Verifier 用 Noul,Judge 用 Score。
def verify_reply(reply: str, context: str) -> dict:
d = client.systemone(
state=f"资料:{context}\n\n回复:{reply}",
questions={
"grounded": {"type": "noul",
"question": "回复里的每个事实性断言都能在资料中找到依据吗?"},
"no_overclaim": {"type": "noul",
"question": "回复是否避免了下游无法兑现的承诺?"},
"has_citation": {"type": "noul",
"question": "涉及的结论是否标注了可核验的来源?"},
},
instructions="你是事实核查员。任何找不到依据的断言都判否,不要替它找理由。",
)
return {k: {"value": v.value, "p": v.probability} for k, v in d.items()}一次调用把三条要求一起核实,各带概率。要拆、要加,改的是 questions 里的清单,而不是去改提示词——这就是"可复用能力"和"一次性提示词"的区别。
把验证做成可复用的能力
真正的价值在于:同一个 Verifier,可以同时服务三个地方。
flowchart TB
V["统一 Verifier
要求清单 + 阈值"] --> E["离线评测
跑基准、比分数"]
V --> C["CI 回归门
版本升级、改配置时拦截"]
V --> G["线上护栏
对生成结果放行 / 转人工"]
E --> M["与人类标注对齐
测校准"]
C --> D["变更检测
含义变了没"]
G --> R["放行 / 升级"]一旦验证被抽象成"输入 state + 一张要求清单,输出一组带概率的判定",评测、回归、护栏就不再是三套代码,而是同一套能力的三次调用。这也解释了为什么决策层特别适合做验证:它的输出封闭、概率显式,天生就是为了被阈值和断言接住的。
决策层的回归测试
当你改了提示词、改了标签集、或者升级了模型版本,怎么知道没有把原来的判断弄坏?生成模型的输出是自由文本,很难写断言;决策层的输出是封闭的概率分布,可以像测普通函数一样测。
三条纪律:
锁版本。 生产用 jev-1.13 这样的具体版本,而不是 jev-latest。行为可复现,是一切的起点。
对概率做区间断言,而不是等值断言。 同一条 state 调两次,choice 可能一致,但概率有细微浮动。断言"落在某个区间",而不是"等于某个数"。
def test_refund_intent_frozen_cases():
for case in load_fixtures("refund_intent.jsonl"):
d = client.systemone(state=case["state"], questions={"intent": INTENT_Q})
top = d["intent"]
assert top.choice == case["expected"], case["id"]
p = top.probabilities[case["expected"]]
lo, hi = case["p_range"]
assert lo <= p <= hi, f"{case['id']}: P={p:.3f} 越出 [{lo}, {hi}]"监控分布漂移。 线上每条判定都记账,观察答案分布有没有整体偏移。社区里的 Tiltmeter 就是一个 /v1/systemone 代理:它记录每次答案的概率,在没有标签的情况下,当 jev-latest 切换了版本、某个问题的答案发生漂移(用卡方检验的 PSI 度量)、答案开始堆积在某个阈值附近、或估计准确率下滑时告警。另一个工具 jevcal 更进一步:在你自己的标注数据上为每个问题拟合一个「达到目标准确率所需的置信阈值」,在留出集上验证,报告还有多少流量必须升级给 LLM,并在模型更新把锁定阈值弄坏时让 CI 失败。
jevcal 和 Tiltmeter 合起来说明一件事:决策层的回归测试不是测"模型答得对不对",而是测"阈值和分布还稳不稳"。 这比测生成模型的输出要结构化得多。
详解一:Vals AI 的独立评测
第三方评测最值得看,因为它通常不受厂商叙事影响。Vals AI 在 400 条 claim-verification 问题上,让 Jev 匹配上了 GPT-6 Astra 的 97.5%,而成本约为它的 1/500;但在一个由 12 个任务组成的 LegalBench 切片上,Jev 排名垫底,且在把预算调到 1% 时错误率为 1.6%。
这不是"Jev 全面胜出"的故事,恰恰相反——它是一份诚实的验证报告该有的样子。同一个 Verifier,在结构清晰的核实任务上和前沿模型打平、成本低两个半数量级;在需要更厚法律常识的任务上垫底。评测的价值不是给你一个"好/坏"的结论,而是把这种分化暴露出来,让你知道该把哪类要求交给它、哪类不该。想用 Jev 做通用验证,第一件事就是接受这种分化,并据此划定适用范围。
一个更近距离的对照:Convex Decision Evals
Vals AI 展示的是"分化的边界",Convex Decision Evals 展示的则是"同一条基准上的成本—能力对照"。它拿 108 道经核验的四选一题(关于 Convex 后端平台,题目里不给文档也不给工具,每题打乱选项问 3 次,随机猜中率 25%),让 jev-1.13 和 14 个 LLM 一起作答。结果:Jev 84.6%,中位延迟 199 毫秒,整轮 $0.0088;而名列第一的模型是 98.0%、2.12 秒、$1.59。
把四个数放在一起读:在这类偏"事实问答"的任务上,Jev 的准确率落后约 13 个百分点,但延迟低约 10 倍、成本低约 180 倍。这不是"谁更强"的答案,而是一条取舍曲线——当你的验证场景对错误不敏感、却对吞吐和成本敏感时,这条曲线就把结论写在脸上了。每一道题的回答、概率和原始请求/响应都公开在一个 explorer 里,可以复查。
详解二:jev-regress-bench 的变更检测
验证不止用于"判对错",也用于"判有没有变"。jev-regress-bench 处理的是一类很实际的场景:你改了一条 agent 的配置,它批准的答案里,哪些是含义变了、哪些只是措辞变了?
它用一次 Choice(same / fact_differs / action_differs / specificity_differs)来做这个区分。在 109 组前/后对照(ground truth 由每条配置规则对答案做了什么推导而来)上,Jev 抓全了全部 19 个真实变更,误报 13 次;对比之下,一个"标记符→嵌入→LLM"的流水线误报 33 次,单独的 LLM judge 误报 19 次。
这个例子把"决策层当回归门"具象化了:它要判的不是"答案本身对不对",而是"答案相对上一版有没有实质变化"。这类判定用生成模型做,你既拿不到稳定的概率,也很难定义"变了";用决策层做,它就是一个四分类问题,答案可断言、可记账。
详解三:LangChain 的 Agent 评测
把决策层当 judge,最看重的是一致性。LangChain 在 Can Jev Be a Better Agent Evaluator? 里把 Jev 与 LLM judge 放在准确率、可复现性、延迟、成本四个维度上比较,结论是:对在线评测而言,Jev 是更便宜、也更一致的 judge。他们的另一篇 Building a Harness with Jev 讲了怎么把 Jev 作为决策层织进 agent harness。
"更一致"是关键。线上评测里,一个答案在两次运行之间抖动的 judge,比没有 judge 还糟——你会追着一个不存在的回归跑。同类工具还有 jev-judge(对 RAG 忠实度、幻觉检测、agent 安全性跑声明式测试套件,单次判定 $0.00004、亚 100 毫秒)和 pytest-jev(对一条回复的每个自然语言断言发一个 Noul,p ≥ 0.8 判过;在它的 12 个示例测试里,与 Claude Sonnet 5 的裁决一致,但耗时 5.3 秒对 27.1 秒、成本 $0.00017 对 $0.0192)。classifier-bench 则在 2,321 条标注用例、31 个任务的冻结语料上比 Jev、OpenAI Decisions 和 LLM 的延迟与登记价成本。它们的共同点是:验证被做成了一条可重复的流水线,而不是每次现写提示词。
judgekit 把这条思路做成了声明式结构:判定任务用 YAML 描述,可以原生跑在 Jev 上、也可以回落到任意 OpenAI 兼容后端;它把低置信的判定在 0.7 处升级给更大的模型,在 130 个样例里以 9% 的升级率抓全了 3/3 个误判,并在冻结的 120 条人工标注垃圾邮件集上把准确率从 60.0% 提到 68.3%(τ=0.10),还公开了中文场景的成本—准确率数字(97.7% @ ¥0.105/千次判定)。这类工具的意义一致:置信阈值不是提示词里的一个形容词,而是流水线里一个可调、可测、可回归的参数。
用 Jev 评估 Jev:校准与自评
验证者自己的概率,也要被验证。你问 Verifier"这条对不对",它说 P(true)=0.9——如果它只对了 70%,这个 0.9 就是假的,阈值策略全塌。衡量这个的标准指标是 ECE(期望校准误差),越接近 0 越好。
社区里有一批项目就在做这件事,而且不少是独立复现。poorjev 在普通零样本 NLI 模型上实现 Jev 的接口,用温度缩放加 conformal abstention 让置信度变诚实,报告了交叉验证下 ECE 从 0.170 降到 0.071。Verdict 是一个 118M 的多语 bi-encoder,用温度缩放加 split conformal 弃答集,公开套件上 ECE 0.01–0.03。ruling 从任意 MLX checkpoint 的 logits 里读出 Choice/Score/Noul,重放 Jev 已公开的 256 条判定,得到 231 对 238(McNemar p = 0.21)——统计上分不出差异。jev-ood-calibration 则做了更细的测量:在 900 条规则生成的、模型不可能见过的支持工单加三个公开基准上,发布每条原始响应与对照噪声下限的 ECE,并指出误校准的方向按类型不同——Choice 和 Score 偏自信,Boolean 偏不自信。
但真正要记住的是这条分界:类型安全(不会输出非法结果)不等于校准(概率准不准)。 一个广为流传的质疑就点在这里——"Jev 不能输出非法结果,但可靠性曲线在哪?"(更尖锐的版本甚至直接主张"Jev 无法被校准")。ASSAY-001 是一份预注册的独立检查,在 Banking77 / CLINC150 上验 Jev 的校准与类型安全,给出的就是分裂的结论。jev-ood-calibration 之类的项目之所以要把原始响应全部公开,正是因为这条曲线只能靠独立复现来建立——Jev Decision Index 就在追踪 70 个公开复现。
评测侧的对照也指向同一件事。Jevals.com 让 Jev 和六个 LLM 回答同一批 Noul/Choice/Score 问题,再对每条答案与人工标签比对(PubMedQA、Banking77、HelpSteer2,每项 300 条 × 5 次运行):Jev 在 PubMedQA 的是/否上与第一名并列、价格是那个 LLM 的 1/28,在 Banking77 上并列第二,而在 HelpSteer2 上没有任何模型超过标签的基率。最后这条尤其值得停一下——它说明有些"评测任务"本身就是噪声,评测的第一价值是让你发现这一点,而不是给模型排个座次。
小结
- 验证有两种用法:Verifier 用 Noul 逐条核实可枚举的要求,重可复现;Judge 用 Score 做整体评判,重与人类评级一致。
- 把验证抽象成"state + 要求清单 → 带概率的判定",同一套能力就能同时服务离线评测、CI 回归门和线上护栏。
- 决策层的回归测试靠三件事:锁具体版本、对概率做区间断言(而非等值)、监控分布漂移(如 Tiltmeter 的 PSI)与阈值(如 jevcal 的 CI 门)。
- 独立评测会揭示分化:Vals AI 上 Jev 在 claim-verification 上匹配 GPT-6 Astra 的 97.5% 且成本约 1/500,却在 LegalBench 切片垫底——分化本身就是评测产物。
- 决策层适合当在线 judge,因为它的判定更一致也更便宜:LangChain 得出这个结论,jev-judge 是 $0.00004/次、pytest-jev 用 $0.00017 对齐了 LLM 的裁决。
- 类型安全不等于校准:poorjev 把 ECE 从 0.170 压到 0.071,Verdict 在 0.01–0.03,但校准曲线必须靠独立复现建立,且误校准方向按类型不同。
判定判得多、判得省,也验证得住之后,最后一个问题是:这些判定在整个智能体里该插在哪、怎么管。下一章收束全书——Harness Engineering。