为什么需要 LLM-as-Judge
想象你要评估一个客服回复的"语气是否友好"。没有精确匹配可用,BLEU 没意义,嵌入相似度区分不出微妙差别。三种选择:
| 方案 | 准确度 | 速度 | 成本 | 可扩展 |
|---|---|---|---|---|
| 人工评审 | ★★★★★ | 慢 | 高 | 差 |
| 训练专用分类器 | ★★★★ | 快 | 一次高后续低 | 好 |
| LLM-as-Judge | ★★★★ | 中 | 中 | 极好 |
| 字面/嵌入指标 | ★★ | 极快 | 低 | 极好 |
Judge 的甜点区:需要"像人一样判断"又要规模化——语气、相关性、事实准确性、安全性这类主观维度。
Judge 的四种范式
① Pointwise — 单条打分
给一个回答打 1-5 分(或 0/1)。最常见。
JUDGE_POINTWISE = """你是一个严格的客服质量评审员。
给下面这条客服回复打分,考察其「专业程度」。
用户问题: {question}
客服回复: {answer}
评分标准(从 1 到 5):
5 — 完美专业,措辞得体,信息准确且完整
4 — 专业,有个别小瑕疵
3 — 合格,但缺少关键信息或有小的用词不当
2 — 不够专业,存在明显问题
1 — 不合格,错误或失礼
请先用 2 句话分析,然后输出 JSON:
{{"reasoning": "...", "score": 1-5}}"""
② Pairwise — A/B 哪个好
两两对比,只问"A 更好 / B 更好 / 平局"。在比较两个 prompt 或两个模型时特别有用。
JUDGE_PAIRWISE = """下面是两个不同的客服回复。判断哪个更好,或平手。
用户问题: {question}
回复 A: {answer_a}
回复 B: {answer_b}
从「准确性」「相关性」「语气」三方面综合判断。
返回 JSON: {{"reasoning": "...", "winner": "A" | "B" | "tie"}}"""
经验
Pairwise 通常比 Pointwise 更稳定——人类给绝对分也不擅长,但比较两样东西相对容易。A/B 迭代选型场景强烈推荐 pairwise。
③ Reference-based — 对照黄金答案
JUDGE_REF = """判断学生答案是否在语义上等价于参考答案。
问题: {question}
参考答案: {reference}
学生答案: {candidate}
忽略措辞差异,只看事实内容是否一致。
返回 JSON: {{"reasoning": "...", "correct": true|false}}"""
④ Rubric — 多维度打分
把一个任务拆成多个维度,每个维度独立打分。对发现"为什么不好"最有用。
JUDGE_RUBRIC = """从以下维度独立评分(每项 1-5):
1. relevance: 是否回答了用户实际问题
2. accuracy: 事实是否正确
3. completeness: 是否覆盖了必要信息
4. tone: 语气是否合适(专业/友好)
5. conciseness: 是否简明(无冗余)
用户问题: {question}
回复: {answer}
JSON 格式:
{{
"relevance": {{"score": 1-5, "reason": "..."}},
"accuracy": {{"score": 1-5, "reason": "..."}},
"completeness": {{"score": 1-5, "reason": "..."}},
"tone": {{"score": 1-5, "reason": "..."}},
"conciseness": {{"score": 1-5, "reason": "..."}}
}}"""
Judge 的常见偏差(Bias)
LLM Judge 不是客观的。有一系列系统性偏差已被学界大量研究:
位置偏好(Position Bias)
Pairwise 时,Judge 偏向第一个出现的选项(或偏向最后一个,因模型而异)。GPT-4 约有 5-10% 位置偏好。
长度偏好(Verbosity Bias)
长回答看起来"更认真",Judge 常给更长的答案打高分,即使信息密度更低。
自恋偏差(Self-enhancement)
Judge 模型偏向自己系列的输出——GPT-4 Judge 会给 GPT-4 答案打更高分。
权威偏差
答案中若出现"根据哈佛研究""数据显示"这类修饰,Judge 倾向给更高分,即使内容虚构。
格式偏好
带 Markdown 标题、项目符号的回答比纯文本得分高,不论内容。
位置偏好的修正
# 双位置评分 — 对每个 pair 跑两次,顺序互换 def judge_pair_debiased(q, a, b): r1 = judge_pairwise(q, a, b) # A 在前 r2 = judge_pairwise(q, b, a) # B 在前 # 一致才算数 if r1 == "A" and r2 == "B": return "A_wins" if r1 == "B" and r2 == "A": return "B_wins" return "tie_or_inconsistent" # 顺序变了结论就变 = Judge 在随机猜
长度偏好的缓解
- 在 prompt 里明确告知:"不要被长度误导,简洁可以是优点"
- 评分前先让 Judge 用相同长度总结两个答案,然后判断
- 加一个独立的 conciseness 维度,让"啰嗦"有代价
自恋偏差的避免
Judge 必须和被评估模型异源。如果你在评估 GPT-4o,Judge 用 Claude 或 Gemini。
好的 Judge Prompt 的 7 条原则
- 角色明确:"你是一个严格的医疗文本审核员" > "请打分"
- 标准可操作:每个分数档给出具体锚点例子,不要只说"好/一般/差"
- 要求先推理再打分:Chain-of-thought 能显著提升 Judge 质量
- 结构化输出:JSON 严格模式,避免解析失败
- 使用 few-shot 例子:给 2-3 个已标注的 case 作为示范
- 维度独立:多维度 rubric 每维分开判,避免互相污染
- 校准引导:"我们标注的 baseline 平均分约 3.5",提示 Judge 不要全打 5
完整实现:一个生产级 Judge
from anthropic import Anthropic import json client = Anthropic() JUDGE_TEMPLATE = """你是客服质量审核专家,严格、公正。 你将看到一个用户问题和一条客服回复,请从 3 个维度评分(1-5)。 评分锚点: - 5 = 典范,可作为范例 - 4 = 良好,小瑕疵 - 3 = 合格,中等水平 - 2 = 不合格,明显问题 - 1 = 严重错误 ## 参考例子 例 1 (accuracy=5): 问: 我的订单多久能到? 答: 您的订单已发货,预计 3-5 个工作日到达,物流单号:SF123456。 例 2 (accuracy=2): 问: 我的订单多久能到? 答: 一般来说很快的,您再等等吧。(缺少具体时间和物流信息) --- 请评估下面这条: 问题: {question} 回复: {answer} ## 输出 先用 2-3 句话说明你的核心判断,然后输出 JSON: {{ "reasoning": "...", "scores": {{ "relevance": {{"score": 1-5, "reason": "..."}}, "accuracy": {{"score": 1-5, "reason": "..."}}, "tone": {{"score": 1-5, "reason": "..."}} }} }}""" def judge(question: str, answer: str) -> dict: rsp = client.messages.create( model="claude-sonnet-4-6", # Judge 用 Claude,被评估的是 GPT max_tokens=800, temperature=0, messages=[{"role": "user", "content": JUDGE_TEMPLATE.format(question=question, answer=answer)}], ) txt = rsp.content[0].text # 粗略提取 JSON 块 start, end = txt.find("{"), txt.rfind("}") return json.loads(txt[start:end+1])
Judge 校准:验证你的 Judge 真的可用
Judge 本身是模型,它可能系统性偏离人类判断。必须校准:
- 挑 50-100 条代表性样本
- 2-3 位人类独立打分,算 inter-annotator κ
- 用同样的 case 跑 Judge,算 Judge 与人的 κ
- 若 Judge-Human κ ≥ 0.6 且接近 Human-Human κ,Judge 可用
- 否则迭代 Judge prompt,直到达标
from sklearn.metrics import cohen_kappa_score human_scores = [4, 3, 5, 2, 4, 3, 5, 4, 1, 3] judge_scores = [4, 4, 5, 2, 4, 3, 4, 5, 2, 3] κ = cohen_kappa_score(human_scores, judge_scores, weights="quadratic") print(f"Judge κ = {κ:.2f}")
发表研究的共识
在大多数主观任务上,GPT-4 Judge 与人类专家的一致性(κ ≈ 0.6-0.7)已经接近人类专家之间的一致性(κ ≈ 0.65-0.8)。也就是说,一个精心调校的 Judge 在多数场景可以替代人类 80% 的工作。
成本控制
Judge 不是免费的。一次完整 eval 可能要几千次 Judge 调用。常见优化:
- 分层:便宜模型做 rubric 粗筛,困难/边界 case 才用 GPT-4 Judge
- 采样:regression 集全跑便宜指标;Judge 只跑 20% 采样
- Prompt caching:Rubric、few-shot 例子都是固定前缀,用缓存省 80% 成本
- Batch API:OpenAI/Anthropic 的 batch API 比实时调用便宜 50%
- 蒸馏:用 Judge 标一批数据,训一个小分类器,替代掉 80% 调用
本章小结
- LLM-as-Judge 四种范式:Pointwise / Pairwise / Reference-based / Rubric
- Pairwise 更稳定;Rubric 最能诊断问题
- 位置 / 长度 / 自恋 / 权威 / 格式——Judge 有一系列系统性偏差
- 位置偏差用"双位置评分"化解;自恋偏差用"Judge 异源"化解
- 好 Judge prompt 的核心:角色、锚点、推理、few-shot、JSON
- Judge 必须用 50-100 条人工样本校准,Judge-Human κ ≥ 0.6 才可用
- 成本控制:分层 + 采样 + 缓存 + Batch API