LLM-as-a-Judge 现在已经成为摘要评估里绕不开的技术方案,但真正用起来之后你会发现,分数只是表象,裁判机制本身才决定结果是否可信。很多人以为把原文和待评估摘要丢给大模型,让它给个 1 到 5 分就够了。实际跑过一轮就会发现,评估维度怎么设计、提示词怎么组织、用打分还是成对比较、采样几次、如何处理长文本和位置偏差,都会显著影响最终结论。这篇文章写给正在做摘要评测、模型对比、RAG 答案质量验证和自动评测体系搭建的开发者。我会先解释为什么传统指标不够用,再拆 LLM 当裁判的三种常见机制,然后按实际落地顺序给出一套可以照着跑的最小验证流程,最后把常见坑和排查顺序一起整理出来。
1. 摘要评估为什么需要“让模型当裁判”
1.1 ROUGE 衡量的是词面重叠,不是摘要好不好
自动摘要、新闻聚合、RAG 答案生成、大模型长文档提炼,这些场景都要回答同一个问题:生成的摘要到底好不好。过去很长一段时间,大家习惯用 ROUGE 这类指标来做判断。ROUGE-1、ROUGE-2、ROUGE-L,本质上是在算候选摘要和参考摘要之间的 n-gram 重叠,或者最长公共子序列。字面重合越高,分数越高。
问题也出在这里。
第一,摘要允许同义改写。原文说“该公司发布了季度财报”,摘要写成“这家企业公布了季度业绩”,意思几乎一样,但 n-gram 重叠可能很低。ROUGE 会把这种合理改写判成低分。
第二,摘要的核心是信息选择和重组,不是逐句复制。两个人写同一个新闻的摘要,重点可能不同,表达可能完全不同。ROUGE 和一个参考摘要对齐时,自然会惩罚那些表达不同但信息正确的摘要。
第三,ROUGE 无法判断幻觉。摘要可以写得非常流畅,但包含原文根本没有的事实。ROUGE 只看字面对齐,对这种情况基本没有辨别能力。如果摘要里的虚构信息恰好用了和参考摘要相似的高频词,ROUGE 甚至可能给出更高分。
所以我的看法是:ROUGE 这类指标更适合做回归监控,判断某次代码改动或模型更新后,生成结果有没有发生大范围漂移。它不适合作为“摘要质量好坏”的最终结论。真正判断质量,还是得回到语义层面,看信息是否忠实、是否覆盖重点、是否连贯。
1.2 LLM-as-a-Judge 把评估从“比对字符串”变成“阅读理解”
LLM-as-a-Judge 的思路很简单:不再比对字符,而是让大语言模型像人一样阅读原始文档和摘要,再按照你给出的维度输出判断。
这套思路解决的实际问题有三个。
一是评估维度可控。你可以让模型分别评估相关性、忠实度、连贯性、信息覆盖,而不是给出一个模糊总分。这样能看出摘要到底在哪一环出问题。
二是可以输出理由。Judge 不只是给一个分数,还能说明为什么扣分。这个 reason 字段在人工复核时非常有用。批量评分之后,你不需要把每条摘要都重新读一遍,只要看 Judge 的理由,就能筛出异常样本。
三是能处理开放性表达。摘要只要意思到位,哪怕用词和原文完全不同,也有机会获得合理评分。这正好补上 ROUGE 的最大短板。
但这里要先把预期降下来。LLM-as-a-Judge 不是一个绝对客观的裁判。它本质上是“另一个模型在特定提示词下的预测结果”。模型会受输入顺序、选项位置、提示词措辞影响,也会有自己的输出偏好。所以真正落地时,重点不是“模型会不会打分”,而是你能不能把评估标准稳定地传达给它,并且知道它错在哪里。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. LLM-as-a-Judge 的三种常见评估机制
2.1 直接打分:适合快速筛选,但分数尺度不稳定
直接打分是最常见的方式。给定原始文档、待评估摘要和评分标准,让模型输出 1 到 5 分或 1 到 10 分,附带一句理由。比如:
text复制原始文本:
...
待评估摘要:
...
请根据相关性、忠实度、连贯性打分,输出 JSON。
优点很直接:单次调用,成本低,容易批量处理。适合快速筛掉明显很差的摘要,也适合做版本回归。模型更新后,同一个测试集跑一轮,看平均分变化,就能发现问题。
缺点也很明显:绝对分数的尺度不稳定。同一个模型在不同批次、不同提示词表达下,对“4 分”的把握可能不一样。今天提示词里写“摘要是否忠实原文”,明天改成“摘要是否包含原意”,分数就可能整体漂移。不同模型之间的分数尺度更没法直接比,A 模型的 4 分可能只相当于 B 模型的 3 分。
我的习惯是:用直接打分时,不要把评分标准写成模糊描述。要在提示词里给出具体锚点。比如“如果摘要包含原文没有的事实,忠实度最高只能给 2 分”“如果核心信息全部保留但表达啰嗦,相关性给 3 到 4 分”。锚点越多,尺度漂移越少。
2.2 成对比较:适合模型对比,但要处理位置偏差
成对比较是另一种常用机制。把摘要 A 和摘要 B 都交给 Judge,让它判断哪个更好,或者两者平局,还要给出理由。比如:
text复制有两个摘要:
摘要 A:...
摘要 B:...
请从忠实度、相关性、连贯性角度判断哪个更好。如果质量接近,输出 tie。
相对判断通常比绝对打分更稳定。因为模型不需要把质量量化成“几分”,只需要做排序。排序是一个相对任务,比绝对打分更符合模型的语言理解习惯。所以做模型 A/B 对比时,成对比较往往比分别打分再比均值更敏感。
代价是调用次数更多。N 个摘要两两比较是 O(N²) 的调用量,实际项目里不会全量做。通常做法是先用直接打分或启发式方法筛掉明显较差的候选,再对剩下的少量候选做成对比较。
成对比较有一个必须处理的偏差:位置偏差。如果摘要 A 永远出现在前面,模型可能更倾向于选 A,或者反过来更倾向选后面那个。这取决于模型自身的习惯。常用做法是交换顺序跑两次,只保留两次结论一致的样本;结论不一致的样本单独人工复核。
2.3 多维度评估和参考引导:适合诊断具体问题
很多摘要问题不是总分能说清的。有的摘要忠实但信息缺失,有的流畅但完全虚构,有的信息齐全但逻辑混乱。这时候需要拆成多个维度分别评分。
一个比较稳的输出结构是:
json复制{
"score": 3.5,
"reason": "整体信息完整,但摘要最后一句包含原文未提及的结论",
"dimensions": {
"忠实度": 2,
"相关性": 4,
"连贯性": 4,
"信息覆盖": 3
}
}
维度拆分的好处是,你能定位问题出现在哪个环节。模型 A 和模型 B 总分可能一样,但 A 输在忠实度,B 输在连贯性,优化方向完全不同。
如果场景里有参考摘要,可以把它作为“参考答案”放进输入。这样能帮助 Judge 对齐信息覆盖度。但要注意,参考摘要只是辅助,不要让 Judge 变成“和参考摘要逐句比较”,否则又回到了 ROUGE 式的词面对齐思路。
三种机制怎么选,我的判断标准是这样的:
- 快速筛选、回归测试:用直接打分。
- 模型版本对比、系统 A/B 测试:用成对比较。
- 定位具体质量问题、构建训练数据:用多维度评分加理由输出。
3. 搭建一套可复现的摘要评估流程
3.1 先确定输入输出和评估维度
开始写代码之前,先把输入输出定义清楚。最小输入单元至少包含四部分:
source_text:原始文档文本。summary:待评估摘要。reference:可选参考摘要。criteria:评估维度和评分标准。
输出建议统一成 JSON,方便后续做统计和分析。不要只存一个总分,要把 reason 和每个维度的分数一起保存。原因很简单:只存总分,出了问题没法回溯;存了 reason,至少能知道 Judge 当时是怎么判断的。
接下来确定模型和采样参数。我在做这类评估时,一般先把 temperature 设为 0 或很低的数值,降低随机性。如果要做稳定性测试或多次采样,再单独把 temperature 调高。还要注意模型上下文长度。原文太长会导致输入被截断,所以要预留足够空间给提示词和输出。如果原文长度接近模型上限,必须提前做处理,否则 Judge 的结论不可信。
3.2 提示词模板和评分标准怎么写
提示词不要写成“请评估摘要质量”这种一句话。分数会很主观,而且换一批样本就容易漂移。比较稳的结构是:
- 先说明角色和目标。
- 分隔输入材料。
- 明确每个维度的定义和评分标准。
- 规定输出格式。
- 加一些限定条件。
一个可以直接改用的模板思路:
text复制你是一个摘要质量评估器。请根据以下维度评估摘要。
原始文本:
...
待评估摘要:
...
评分维度:
1. 忠实度(1-5):摘要是否忠实于原文。如果摘要包含原文没有的事实,这个维度最高只能给 2 分。
2. 相关性(1-5):摘要是否覆盖原文核心信息。遗漏主题句或关键结论时,最高给 3 分。
3. 连贯性(1-5):摘要内部逻辑是否清晰,衔接是否自然。
只输出 JSON:
{"score": 总平均分, "reason": "判断依据", "dimensions": {"忠实度": 0, "相关性": 0, "连贯性": 0}}
注意“如果包含虚构事实,最高只能给 2 分”这种写法。这是评分锚点,能明显减少分数膨胀,也能让 Judge 在推理时更重视事实核查。
3.3 最小运行示例:Python 调用
下面是一段最小示意代码,我通常用这种方式先验证单条输入。实际生产环境要加超时、重试、并发和缓存,这里先把最小流程跑通。
python复制from openai import OpenAI
client = OpenAI(
api_key="your-api-key",
base_url="https://your-endpoint",
)
def evaluate_summary(source_text, summary, criteria, model="gpt-4o-mini"):
prompt = f"""
你是一个摘要质量评估器。请根据给定维度评估摘要。
原始文本:
{source_text}
待评估摘要:
{summary}
评估维度:
{criteria}
只输出 JSON:
{{"score": 总平均分, "reason": "判断依据", "dimensions": {{}}}}
"""
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
temperature=0,
response_format={"type": "json_object"},
)
return response.choices[0].message.content
如果你的 API 不支持 response_format 参数,就删掉这一行,然后在提示词里明确要求“只输出 JSON,不要输出其他内容”。解析时还要做一层兜底,防止模型输出多余的说明文字。
跑之前先确认三件事:API key 能正常调用;原文长度没有超过上下文限制;返回结果可以被 JSON 解析。这三件都确认后,再进入批量。
3.4 成本、并发和结果保存
批量评估前先估算成本。每条评估的大致消耗等于原文长度加摘要长度加提示词长度加输出长度。拿 5 到 10 条样本跑一遍,乘一下总条数,就能预估总体消耗。不要完全不看成本直接跑几千条,特别是在使用商业模型接口时。
并发不要一上来就开很高。很多模型接口有速率限制,批量跑的时候经常出现 429 限流。我的习惯是先串行跑 1 条,确认返回正常;再跑 5 条,观察耗时;再逐步提高并发。这样做的好处是,就算出错,你也能很快定位到是哪一批数据、哪个环节出了问题。
结果保存同样重要。每条调用的原始返回都要落盘,不只是分数。我在实践里会保存原始响应、reason、模型名称、提示词哈希值、输入长度、时间戳。这样后面改提示词或换模型时,能对比历史结果,知道分数变化是因为数据变化,还是因为评估配置变化。
还要加缓存。相同输入重复调用时直接读缓存,能省下不少调用量。批量任务跑一半失败时,有了缓存和断点记录,可以从中断位置继续,而不是全部重跑。
4. 摘要场景里 Judge 最容易踩的坑
4.1 长文本截断让忠实度判断失真
摘要评估依赖对原文的完整理解,但大模型对长文本的注意力并不均匀,位置靠中间的信息容易被忽略。如果原文很长,Judge 很可能只重点看了开头和结尾,得出错误结论。
我遇到过的情况是这样的:摘要里提到一个关键数字,这个数字出现在原文第 3000 个 token 以后。因为输入太长被截断,Judge 认为摘要“包含原文未提及的信息”,判成不忠实。这其实不是模型能力问题,是输入处理问题。
解决顺序可以这样排:
- 优先压缩输入。把原文先做一遍抽取式摘要,或者只取关键的几个段落。
- 如果必须用全文,选择支持更长上下文的模型。
- 在提示词里显式要求“先定位关键实体,再检查摘要中的每个事实是否能在原文找到依据”。
- 把原文切成多个部分,分块判断后再汇总。
判断标准是:如果 Judge 输出的理由里出现“摘要包含原文未提及的信息”,但你自己读原文时能对应上,优先怀疑输入不完整,而不是直接相信这个评价。
4.2 位置偏差、顺序偏差和自偏爱
模型判断会受到输入排列方式的影响。位置偏差指的是,输入材料出现的顺序不同,结论可能不同。顺序偏差在成对比较里更明显:摘要 A 放在前面和放在后面,结果可能不一致。
自偏爱则更隐蔽。某些模型对同系列或同训练风格的输出会给出更高分数。如果拿 A 模型当 Judge 去评估 A 模型的摘要,可能会得到偏乐观的结果。这不是模型的恶意,而是训练数据分布带来的倾向。
应对方式不复杂:
- 成对比较交换顺序跑两次或多次,保留一致结论。
- 做盲评,隐藏模型名称和版本信息。
- 关键结论用不同 Judge 交叉验证。
- 记录每次输入的具体顺序,排查时能看出偏差来源。
不要急着认定“分数没问题”。同一组摘要,换一个 Judge,结论可能完全反转。这种差异本身也是信息。
4.3 流畅但虚构的摘要最容易被误判
摘要里最隐蔽的问题不是语言差,而是语言流畅但事实虚构。模型生成了一段逻辑完整、表达自然的摘要,但内容在原文里根本找不到依据。这种摘要特别容易骗过 Judge,因为 Judge 也是语言模型,同样容易被流畅表达带偏。
对策是把“事实核查”变成显式动作。
一个很有效的提示词写法是:要求 Judge 先列出“摘要中与原文不符的事实列表”,再给分数。哪怕模型列得不完全,这些列表也能帮你做人工复核。另一个做法是先把原文中的关键实体提取出来,比如人名、数字、日期、地点,然后要求 Judge 把摘要中的关键实体与原文逐一对照。
还要注意,不要用一个总分把“流畅”和“忠实”混在一起。分开评估之后,你才能看到一个摘要到底是“读起来顺但内容错了”,还是“内容对但读起来不顺”。这两类问题的修正方法完全不一样。
注意:如果 Judge 对某条摘要打了高分,但这条摘要有明显事实错误,而你直接用了这个分数做模型对比,结论就会被带偏。所以在正式对比前,一定要抽几条人工复核。
5. 结果不能只看分数:如何验证 Judge 本身
5.1 先做小样本一致性检查
拿到 Judge 结果后,不要立刻采信。抽 5 到 10 条样本,自己做一遍人工判断,再和 Judge 结果对比。如果 Judge 认为“优秀”的摘要里有明显幻觉,说明提示词需要调整。如果 Judge 给的理由和分数明显矛盾,说明维度定义或输出格式有问题。
还需要检查稳定性。同一条输入跑 5 次,看分数波动。标准差过大,说明采样参数或提示词不够稳定。一般在 temperature=0 时波动应该很小,但有些接口并不完全保证确定性,所以最好自己记录多次输出,而不是假设“temperature=0 就绝对确定”。
5.2 看分数分布,而不是只看均值
比较模型 A 和模型 B 时,最容易犯的错就是只看平均分。平均分相同,分布可能完全不同。模型 A 可能稳定在 4 分左右,模型 B 可能一半 5 分一半 1 分,平均值一样,但风险特征完全不同。
需要看这几项:
- 分布形状。如果所有分数都集中在 4 到 5 分,说明评分标准太宽松,没有区分度。如果全在 1 到 2 分,说明标准太严。
- 排序一致性。用多个维度和多个模型时,检查模型之间的排名是否稳定。每次跑完排名都变,说明评估体系不可靠。
- 样例级误差。重点看人工判断和 Judge 判断差距大的样本。到底是 Judge 理解错了,还是你自己对标准的要求变了。
有一批人工标注或偏好数据时,可以算排序一致性和准确率。没有人工标注时,至少也要有抽样式人工复核。完全依赖 Judge 分数而没有任何人类判断兜底,风险很高。
5.3 何时用多次采样和投票
如果单次结果波动明显,可以考虑多次采样。同一输入跑 3 到 5 次,取多数结论或平均分。投票能抑制随机性,但成本也会增加。
投票不是万能的。三次结果都不一致时,多数结论也不一定对。这种情况下,问题往往不在采样次数,而在提示词或输入处理。要么维度定义有歧义,要么原文太长,要么输出格式没有约束住模型。正确做法是回到上游排查,而不是通过更多次采样强行稳定。
6. 常见问题排查顺序和落地建议
6.1 按现象分层的排查顺序
我在批量跑 Judge 时,习惯按现象分几条排查路径。假设系统是“输入原文和摘要,输出 JSON 评分”,常见问题可以这样排:
| 现象 | 可能原因 | 优先排查顺序 |
|---|---|---|
| 输出不是 JSON | 提示词没有说明格式,或解析代码太严格 | 1. 看原始返回 2. 检查提示词格式说明 3. 换兼容格式 |
| 分数普遍偏高 | 评分标准太宽松,锚点不足 | 1. 检查维度定义 2. 查看样例分布 3. 增加扣分条件 |
| 分数普遍偏低 | 标准太严,或模型对某个维度理解偏保守 | 1. 检查评分锚点 2. 与人工标注对比 3. 调整标准 |
| 成对比较总选第一个 | 位置偏差 | 1. 交换顺序重跑 2. 多次采样 3. 提示词要求先分析后判断 |
| 输出理由与分数矛盾 | 维度定义有歧义,或输出格式约束不够 | 1. 检查维度定义 2. 检查提示词结构 3. 看原始返回 |
| 同输入每次结果不同 | temperature 未调低,或接口非确定性 | 1. 检查采样参数 2. 加缓存 3. 多次采样投票 |
| 忠实度误判明显 | 原文截断,或模型被流畅表达带偏 | 1. 检查输入长度 2. 检查输入处理 3. 增加事实核查要求 |
排查顺序的逻辑是:先确认输入完整,再检查提示词,再看输出格式,最后才怀疑模型本身。很多问题不是模型不会打分,而是输入或指令没有给到位。
6.2 生产化时要补的几件事
如果只是学习或跑一两次实验,默认配置够用。但如果要把 LLM-as-a-Judge 当作长期评测体系的一部分,至少要补这几件事:
- 固定模型版本和提示词版本。提示词一变,历史分数就不能直接比较。每次修改都要记录版本。
- 保存原始返回。只存分数会让后续排查无从下手。
- 建立小规模人工复核集。每次改提示词后,先跑复核集,对比变化方向。
- 加缓存和失败重试。批量评估不是只跑一次,要能断点继续。
- 控制并发。先测速率限制,再逐步调高,不能一次性拉满。
- 输出统计要有分层能力。按维度、按模型、按输入长度分段统计,才能看出问题集中在哪类样本。
6.3 我的建议:先把小样本跑稳
我最常建议的流程是:拿 10 条有代表性的样本,先人工标好“好、中、差”,让 Judge 跑一遍,看排序是否和人工排序基本一致。一致了,再扩大到 50 条,确认分数分布合理。通过后再进入全量批量。
不要一上来就处理几百上千条摘要。如果提示词有问题,批量跑完才发现,浪费的调用量和时间都不是小数。先把小样本跑稳,后面的批量才值得相信。这个流程看起来慢,但真正到了做结论、做对比、写报告的时候,能省掉大量返工。
我自己再把整个摘要评估流程过了一遍后最大的感受是:Judge 的价值不只是省人工,而是把评估标准从“看的人心里”搬到了“提示词和时间戳都可见的代码里”。分数会变,标准可以不断迭代,只有保住原始记录和人工复核闭环,这套机制才真正可信。
