用 LLM 给 LLM 的输出打分(LLM-as-Judge,「让大模型当裁判」)已是评测、reward model、RLHF、Agent 自评的默认基础设施。但裁判不是一把公正的尺子——它系统性地被表面伪影带偏,还偏爱自己。今天讲清楚:这些偏差从哪来、为什么「让模型判对错」在原理上仍成立、以及怎么在机制层面把裁判校准回来。
想象一个 code reviewer,本该只看代码质量,却无意识地给「排在前面的那个 PR」或「行数更多的那个 PR」盖章通过。这不是他懒——是他的判断被与质量无关的表面特征污染了。更贴近你的场景:一个本不该依赖 join 顺序的查询计划器,却因为你把表 A 写在前面就换了执行计划——结果依赖了它不该依赖的输入排布。LLM 裁判正是这样。
你想让裁判回答「A 和 B 哪个答案更好」。理想裁判只看质量。但 Zheng et al. 2023(提出 MT-Bench 的那篇)系统测出三类偏差:
机制根源在于 next-token 预测:模型从训练语料里学到了大量虚假相关——「靠前的选项」「更长的文本」在人类标注数据里恰好常常也是被选中的那个,模型把这种相关误当成了因果。于是这些信号泄漏进了它的「质量判断」。
这就是为什么裸用单次 LLM 打分不可信:你测的可能是「谁排前面」而不是「谁更好」。机制层面的第一步修正是顺序对称化——两个顺序都跑一遍,只有两次结论一致才算数。
from anthropic import Anthropic client = Anthropic() # 需要 ANTHROPIC_API_KEY def judge(question, first, second): # 只返回赢家标签 A / B prompt = f"问题:{question}\n\n[答案A]{first}\n\n[答案B]{second}\n\n只回 A 或 B:" r = client.messages.create(model="claude-opus-4-8", max_tokens=2, messages=[{"role":"user","content":prompt}]) return r.content[0].text.strip() # 顺序对称化:两个顺序都问,检测位置偏差 v1 = judge(q, ans_x, ans_y) # X 在前 v2 = judge(q, ans_y, ans_x) # Y 在前(标签会镜像) winner_1 = "X" if v1=="A" else "Y" winner_2 = "Y" if v2=="A" else "X" if winner_1 == winner_2: print("稳健赢家:", winner_1) else: print("位置偏差!判为平局或需人工复核") # 不一致 = 别信
让写代码的同一个人给自己的代码写单元测试——他会正好测他已经想到的那些情况,而漏掉自己的盲区,因为 bug 和测试共享同一个心智模型。分布式里更精确:主库和从库如果跑同一份有 bug 的固件,故障是相关的——从库无法当主库的独立校验,因为它俩会在同一个地方一起错。当「生成答案的模型」和「当裁判的模型」是同一个(或同门),就是这种同故障域。
Zheng et al. 观察到 GPT-4 当裁判时,给自己的输出约高 10% 的胜率。这不只是「自恋」。Panickssery et al. 2024(《LLM Evaluators Recognize and Favor Their Own Generations》)给出了机制:
这直接引出 错误趋同(correlated errors):如果裁判和被评者共享架构/训练数据,它们的盲区是重叠的——裁判恰好看不见生成者犯的那类错,因为它自己也会那样错。这时裁判给出的「通过」是虚假的安全感:不是「答案对」,而是「两个同款模型一起错到了同一个地方」。用同一个模型做「生成 + 自评」,本质上就是让固件 bug 给自己签发健康证明。
# 测量自我偏好:同一批答案,比较「自评」和「他评」的分歧 def win_rate_for(judge_model, my_ans, other_ans, q): wins = 0 for a, b, question in zip(my_ans, other_ans, q): v = judge_with(judge_model, question, a, b) # 已做顺序对称化 wins += (v == "mine") return wins / len(q) # 自己当裁判 vs 换一个不同家族的模型当裁判 self_rate = win_rate_for("model-X", x_ans, y_ans, q) # X 评 X 的答案 neutral = win_rate_for("model-Z", x_ans, y_ans, q) # 中立第三方评 print(f"自评胜率 {self_rate:.2f} vs 中立 {neutral:.2f}") # 若 self_rate 显著 > neutral → 存在自我偏好,别用自评当结论
既然模型有这么多偏差、还不能完美生成,凭什么信它当裁判?答案藏在一个你熟的直觉里:验证一个解,通常比找到这个解容易——这就是 P vs NP 的日常版。检查一道数独填得对不对是秒判,从头解出来却很难。后端里同理:写一个 assert / 校验函数比写出正确的实现便宜得多;一个 linter 能抓出它自己根本写不出来的正确代码里的错。「验证比生成容易」这条鸿沟,就是 LLM-as-Judge 能成立的地基。
把它形式化:生成-验证鸿沟(Generation-Verification Gap, GV-Gap) = 用模型自己的验证分数去重新加权它的一批生成后,性能提升了多少。直觉是:模型直接采样一个答案的准确率是 p_gen;但如果它生成 N 个、再用「验证能力」挑出最好的那个,准确率能升到 p_ver。GV-Gap = p_ver − p_gen,衡量的是模型「审」的精度超过「写」的精度多少。
这条鸿沟正是 Best-of-N、reward model、self-refine、o1 式推理全都依赖的引擎:先大量生成,再用验证信号筛/排序。Song et al. 2024(《Mind the Gap: Examining the Self-Improvement Capabilities of LLMs》,arXiv 2412.02674)把 GV-Gap 提为自我改进的核心度量,并发现它的一个变体随预训练算力单调增长——模型越大,「会审」相对「会写」的优势越明显。
但鸿沟不是普适的。对足够难的推理题,模型验证不了自己的错——它审自己的盲区时,GV-Gap 塌到 0 甚至为负(这就是 self-refine 常常「越改越糟」的原因)。GV-Gap 何时 > 0,正是「LLM-as-Judge 何时可信」的边界:鸿沟大 → 裁判有用;鸿沟塌陷 → 退化成上一张卡的错误趋同。
# 估计 GV-Gap:生成 vs 「自我验证选优」两种准确率之差 def gv_gap(model, tasks, N=8): p_gen, p_ver = 0, 0 for t in tasks: cands = [generate(model, t.q) for _ in range(N)] # 生成基线:随便取第一个的正确率 p_gen += t.is_correct(cands[0]) # 验证选优:让模型给每个候选打分,取最高分那个 scores = [verify_score(model, t.q, c) for c in cands] best = cands[scores.index(max(scores))] p_ver += t.is_correct(best) n = len(tasks) return p_ver/n - p_gen/n # >0 才说明「审」比「写」强,裁判才有意义
别信单节点。分布式的老智慧:用跨故障域的多副本投票(quorum)抵御相关故障——N-version programming 让不同团队独立实现同一规格,再对结果投票,因为独立实现不会在同一处一起错。把「不同家族的 LLM」当成不同故障域的副本,让它们各自打分再聚合——这就是把前三张卡的偏差用多样性抵消掉。另外还要「校准仪表盘」:裁判说的「9 分」若不对应真实 90% 的正确率,这个数字就是坏的量程。
单裁判把位置偏差、冗长偏差、自我偏好、错误趋同全占了。两个机制层面的解法:
注意多样性是前提:如果陪审团全是同门模型(甚至同一模型跑三次),错误趋同没解决——三个副本一起错,投票只是把同一个偏差投了三遍。要的是去相关,不是数量。
# 多样性陪审团:不同家族模型各打分,聚合投票 JURY = ["claude-opus-4-8", "gpt-judge", "gemini-judge"] # 关键:不同家族 def panel_verdict(q, ans_a, ans_b): votes = [] for m in JURY: # 每个裁判都做顺序对称化,消位置偏差 v1 = judge_with(m, q, ans_a, ans_b) v2 = judge_with(m, q, ans_b, ans_a) if v1 == v2: # 两个顺序一致才计票 votes.append(v1) if not votes: return "tie" # 全员位置不稳 → 判平局 # 多数投票:不同故障域的偏差在这里相互抵消 return max(set(votes), key=votes.count)