模型评估与 LLM-as-a-Judge
本教程共 45 篇 · 第 38 篇 · 更新于 2026-08-16 · 约 8 分钟阅读
本节目标:搞清模型评估的维度和工具,理解 LLM-as-a-Judge 的原理、裁判模型选型与评估流程,学会把评估接入开发流程。
38.1 为什么模型输出需要评估
LLM 的输出天生不确定。同一个问题,换一次调用结果就变。这让测试和上线都很难办。
传统指标不好使。BLEU、ROUGE 靠字符串重叠算分,适合翻译和摘要场景。现在的回答讲语义、讲上下文,字面不一样意思可能一样,它们量不出这种质量。
人工评估准,但贵且慢。大规模评测要雇人、要培训、要校准,根本跑不起来。需要一个又快又便宜的办法。
38.2 评估维度
先明确”质量”指什么。官方文档提到五类常见维度:
- 相关性:回答是否回应了问题
- 事实准确性:陈述是否真实
- 忠实度:回答是否忠于提供的上下文
- 指令遵循:是否按要求完成,比如格式、语气
- 连贯与清晰:整体是否通顺、有条理
不同场景权重不同。RAG 问答重相关性和忠实度,客服机器人重指令遵循。评估前先定维度,否则分数没有意义。
生产环境还会加内容安全维度,比如毒性、偏见检测。这不在 Spring AI 内置评估器的范围内,但选评估方案时要一起考虑。
维度要能转成可判定的标准。相关性可以问”回答是否在讲上下文里有的内容”,指令遵循可以查”格式是否合规”。标准写清楚,评估结果才一致。人工打分和模型打分,用同一套标准。
38.3 Evaluator API 回顾
第 37 章用过 Evaluator,这里把接口看全。核心就一个方法:
@FunctionalInterface
public interface Evaluator {
EvaluationResponse evaluate(EvaluationRequest evaluationRequest);
}
EvaluationRequest 装三样东西:
public class EvaluationRequest {
private final String userText; // 用户原始输入
private final List<Content> dataList; // 上下文数据,如 RAG 检索结果
private final String responseContent; // 模型生成的回答
}
评估结果统一装进 EvaluationResponse,isPass() 告诉你是过还是不过。
Spring AI 内置两个评估器。RelevancyEvaluator 判断回答和上下文是否相关,默认模板让模型回答 YES 或 NO。FactCheckingEvaluator 把上下文和论断分别作为 document、claim 交给模型,判断论断是否被上下文支持。
两个评估器都支持自定义模板。不换模板时用构造器直接建,写法与第 37 章一致:
RelevancyEvaluator evaluator = new RelevancyEvaluator(ChatClient.builder(chatModel));
想换模板,用官方提供的 builder 方法 .promptTemplate(),模板必须保留三个占位符:query、response、context:
PromptTemplate customTemplate = PromptTemplate.builder()
.template("""
判断回答是否基于给定上下文,回答 YES 或 NO。
Query: {query}
Response: {response}
Context: {context}
Answer:
""")
.build();
RelevancyEvaluator evaluator = RelevancyEvaluator.builder()
.chatClientBuilder(ChatClient.builder(chatModel))
.promptTemplate(customTemplate)
.build();
模板里可以加自己的评判规则,占位符不能丢。占位符是评估器和模板之间的接口。
Note评估用的模型可以和生成模型不同,通常应该不同。评估任务简单,用不着旗舰模型。
38.4 LLM-as-a-Judge:让模型当裁判
内置评估器解决具体问题。更系统的方案是 LLM-as-a-Judge,字面意思:让 LLM 当裁判,给其他模型(或自己)的输出打分。
这不是拍脑袋。研究显示,优秀的裁判模型与人类判断的一致性最高可达 85%,比人类之间的一致性(81%)还高。
为什么有效?评估比生成容易。 生成要同时满足一堆约束,评估只需要检查现成文本的特定属性。批评比创作简单,检查问题比预防问题简单。
两种评估模式
直接打分(Direct Assessment)。 裁判按给定标准给单个回答打分,比如 1-4 分。分数低就带上反馈重新生成,这就是自改进(self-refinement)。
成对比较(Pairwise Comparison)。 裁判从两个候选回答里选更好的,常用于 A/B 测试。
直接打分适合日常质量把关,成对比较适合对比两个模型或两版提示词。
裁判模型怎么选
通用模型(GPT-4、Claude)能当裁判,但专用裁判模型表现更好。Hugging Face 上有 Judge Arena 排行榜(huggingface.co/spaces/AtlaAI/judge-arena),专门跟踪各模型在裁判任务上的表现。
选型要点:
- 优先专用裁判模型,而不是顺手拿主力模型
- 生成和评估用不同模型,避免”自己评自己”的偏误
- 打分任务 temperature 设为 0,保证结果稳定
- 提示词用整数分制,配几个示例,约束输出格式
裁判模型也会有自己的偏误。研究提到自恋偏误(arXiv:2410.21819):模型倾向于给自己或同类模型的输出打高分;还有长度偏误(Zheng et al., 2023):更长的回答更容易得高分。生成和评估用不同模型,是抵消这些偏误最直接的手段。
评估流程:打分-反馈-重试
Spring AI 用 Recursive Advisor(第 6 章)实现评估循环。流程是:生成回答 → 裁判打分 → 不达标就把反馈拼回提示词重试 → 直到达标或达到次数上限。
官方 demo 里,生成用 Claude,评估用 Ollama 上的专用裁判模型:
ChatClient chatClient = ChatClient.builder(anthropicChatModel) // 生成模型
.defaultTools(new MyTools())
.defaultAdvisors(
SelfRefineEvaluationAdvisor.builder()
.chatClientBuilder(ChatClient.builder(ollamaChatModel)) // 评估模型
.maxRepeatAttempts(15)
.successRating(4)
.order(0)
.build())
.build();
var answer = chatClient.prompt("巴黎现在天气怎么样?").call().content();
裁判的打分结果通过结构化输出解析成记录:
@JsonClassDescription("评估响应记录,表示评估的结果。")
public record EvaluationResponse(int rating, String evaluation, String feedback) {}
循环里每轮先调 callAdvisorChain.copy(this).nextCall(request) 走子链,再拿结果让裁判打分。打分低于 successRating,就把 feedback 拼进用户消息重试。
结构化输出在这里很关键。打分结果解析成记录后,rating 直接和 successRating 比较,feedback 直接拼进重试请求。整个循环不用手写解析逻辑。
运行时会看到这样的日志:
Evaluation failed on attempt 1, evaluation: The response contains unrealistic
temperature data, feedback: The temperature of -255°C is physically impossible...
Evaluation passed on attempt 2, evaluation: Excellent response with realistic weather data
NoteRecursive Advisor 是实验特性,只支持非流式调用。重试会放大模型调用成本,必须设置
maxRepeatAttempts防止死循环。
与 RAG 评估的关系
第 37 章的 RAG 评估,本质是 LLM-as-a-Judge 的应用场景。RelevancyEvaluator 看相关性,FactCheckingEvaluator 看忠实度,都是用模型判断模型。
区别在范围。RAG 评估只关心”回答是否贴合检索上下文”,LLM-as-a-Judge 是通用框架,可以评估任何维度、任何场景。
落地时分层:回归测试用评估器自动把关,高风险内容用事实核查逐条过滤,批量质量用裁判模型打分加人工抽检。三层配合,质量才可控。
38.5 把评估做成自动化测试
评估器最有价值的地方,是能当测试断言用。构造一份”问题-上下文”的测试集,逐条跑评估:
@ParameterizedTest
@MethodSource("testCases")
void evaluateAnswers(String question, String context) {
String answer = chatClient.prompt(question).call().content();
EvaluationResponse response = evaluator.evaluate(
new EvaluationRequest(question, List.of(new Document(context)), answer));
assertThat(response.isPass()).isTrue();
}
测试集规模不用大,三五十条覆盖主要场景就够。挂进 CI,每次改提示词、换模型、调检索参数,都能立刻知道效果有没有回退。
Note评估测试要调用模型,会花钱。本地用 Ollama 小模型跑,成本可以压得很低。
38.6 评估最佳实践
- 用专用裁判模型,别拿主力模型凑合
- 生成与评估分离,降低偏误
- temperature 设为 0,保证打分稳定
- 提示词用整数分制、给示例
- 高风险决策保留人工复核
38.7 小结
模型评估先定维度,再选工具。Evaluator 接口统一评估入口,内置相关性、事实核查两个评估器。LLM-as-a-Judge 用模型当裁判,配合自改进循环,质量把关就能自动化。裁判模型要专用、要独立、要稳定。