人工智能实践(语言智能)
第8讲:LLM as Judge

8.2 Judge 技术

Prompt 工程、rubric 设计、few-shot、chain-of-judges、结构化输出、自一致性与集成

Judge Prompt 的解剖结构

一个生产可用的 Judge Prompt 不是一句"请打分"能搞定的。它通常由五块组成:

每一块都有独立的设计权衡,下面逐一展开。

Rubric 设计:让 Judge 打分可复现

Rubric(评分标准)是 Judge 可靠性的第一要件。没有 rubric 的 Judge 就像没有 SOP 的人工标注员——每个人对"5 分"的理解都不同。一个好的 rubric 应当包含:

  1. 评分维度(Dimensions):至少 3–5 个正交维度,避免一维打分的信息坍缩。
  2. 每个维度的量表(Scale):每档对应可观测的行为描述
  3. 边界案例:明确 "3 分" 和 "4 分" 之间的分界。
  4. 评分顺序:先易后难,先客观后主观。

示例:中英翻译质量 Rubric

以下 rubric 用于 实验,将中文翻译为英文的质量评估。每档都给出行为描述而不是抽象形容词。

维度1 分3 分5 分
忠实度(Faithfulness)主要信息错误或遗漏核心信息正确,次要信息有遗漏或偏差所有信息准确完整地传达
流畅度(Fluency)母语者难以理解可读但存在语法或搭配问题接近母语水平,自然流畅
术语(Terminology)关键术语错译术语基本正确但不统一所有术语准确且一致
风格(Style)文体完全错配文体大致合适但不精确文体与原文完美匹配

Few-shot 锚定

零样本 Judge 的分数分布往往偏高——LLM 倾向给 "还不错" 的回答打 8 分以上。加入 2–3 个 few-shot 示例(覆盖高分、中分、低分三档)可显著压缩分数分布提高区分度

示例 1(5 分):
原文:北京大学是中国顶尖的综合性大学。
译文:Peking University is one of China's top comprehensive universities.
评分:忠实度=5, 流畅度=5, 术语=5, 风格=5
理由:信息完整,语法自然,"Peking University" 是官方译名。

示例 2(2 分):
原文:北京大学是中国顶尖的综合性大学。
译文:Beijing school is top in China.
评分:忠实度=2, 流畅度=2, 术语=1, 风格=2
理由:"school" 错译为"大学",漏译"综合性",用词过于口语化。

Few-shot 示例本身会引入偏差。务必覆盖所有分数档位,并让示例与待评估任务的分布匹配(同一领域、同一长度区间)。

结构化输出:别让 Judge 自由发挥

让 Judge 输出自由文本然后用正则抓分数是Judge 工程最常见的事故源。永远要求 JSON 输出,并在本地做 schema 校验:

import json
from pydantic import BaseModel, Field, ValidationError

class TranslationScore(BaseModel):
    faithfulness: int = Field(ge=1, le=5)
    fluency: int = Field(ge=1, le=5)
    terminology: int = Field(ge=1, le=5)
    style: int = Field(ge=1, le=5)
    overall: int = Field(ge=1, le=5)
    rationale: str = Field(min_length=20, max_length=500)

def parse_judge_output(raw: str) -> TranslationScore | None:
    try:
        data = json.loads(raw.strip().removeprefix("```json").removesuffix("```"))
        return TranslationScore(**data)
    except (json.JSONDecodeError, ValidationError) as e:
        return None  # 触发重试或回退

现代 LLM 都支持 结构化输出模式(OpenAI response_format、Claude tool use、Qwen response_format),能硬性约束输出为合法 JSON。能用就用。

Chain-of-Judges:先推理再打分

G-Eval 的核心发现是让 Judge 先写 CoT 再给分能显著提升与人类的相关性。2025 年 EvalPlanner 与 J1 进一步把"推理"作为一等公民:

对应的 Prompt 片段:

请按以下三步评估:

Step 1 (评估计划): 列出你将考察的 3-5 个维度。
Step 2 (逐维度分析): 对每个维度,引用原文和译文的具体片段给出证据。
Step 3 (综合评分): 基于上述证据,给出各维度和总体分数。

最终输出 JSON,格式如下:
{"plan": [...], "analysis": [...], "scores": {...}, "rationale": "..."}

自一致性(Self-Consistency)

受 Wang et al. (2023) 在推理任务上的启发,Judge 也可以用多次采样投票提升稳定性:

s^=median{s(1),s(2),,s(k)}\hat{s} = \text{median}\left\{ s^{(1)}, s^{(2)}, \ldots, s^{(k)} \right\}

其中 s(i)s^{(i)} 是第 ii 次采样得到的分数(T[0.3,0.7]T \in [0.3, 0.7],采样 k=35k=3 \sim 5 次)。对 Pairwise 投票则取多数票;若投票比例接近 50:50,标记为"不确定"样本交给人工复核。

成本-收益权衡k=3k=3 采样的噪声已显著下降,k5k \ge 5 边际收益递减。在预算紧张时只对边界案例做多次采样(自适应自一致性)。

多轮交叉:对付位置偏差

对 Pairwise 评估,交换 A/B 位置重跑一次是几乎零成本的偏差缓解手段:

def robust_pairwise(judge, question, resp_a, resp_b):
    """运行两次并对冲位置偏差"""
    v1 = judge(question, resp_a, resp_b)  # A 在前
    v2 = judge(question, resp_b, resp_a)  # B 在前
    
    if v1 == "A" and v2 == "B":
        return "A_wins"          # 两次都选第一个 => 实际是 A 胜
    elif v1 == "B" and v2 == "A":
        return "B_wins"
    elif v1 == v2:
        return "position_bias"   # 两次都选同一位置 => 有位置偏差
    else:
        return "tie"

MT-Bench 论文报告:加入 swap 后,位置偏差从 15–25% 下降到 5% 以下。详见 偏差与缓解

Judge 集成(Judge Ensemble)

不同 Judge 模型的偏差方向不同——GPT-4 偏长、Claude 偏结构化、Qwen 偏中文表达力。用多个异构 Judge 投票可以平均掉各自偏差:

集成策略说明何时用
多数投票N 个 Judge 选多数Pairwise,N 奇数
分数加权平均按 Judge 与人类的历史相关性加权Pointwise
分歧触发人工Judge 不一致时交给人工高风险场景
级联(cascade)先便宜 Judge 过筛,不确定样本再上强 Judge大规模评测

本节小结

技术解决什么问题代价
RubricJudge 口径不一Prompt 变长
Few-shot分数分布偏高Token 成本 + 示例偏差
结构化输出解析失败需校验重试
Chain-of-Judges浅层判断、相关性低推理成本 2–3 倍
自一致性单次采样噪声推理成本 kk
位置交换位置偏差推理成本 2 倍
Judge 集成单 Judge 系统偏差成本 × Judge 数

技术再多,最终都要靠与人类标注的相关性来验证。下一节我们系统看看 Judge 的各种偏差与缓解策略。