当你把大模型接进生产环境,第一个绕不开的问题就是:怎么知道它生成的内容到底好不好?人工逐条看既不经济也不可规模化。LLM-as-Judge(大模型裁判)用更强的模型当”评委”,对模型输出自动打分,把原本主观的质量判断变成可量化、可回归的指标。本文带你从原理到代码,落地一套自动评测流水线。
为什么需要自动评测
传统做法依赖人工抽检或简单的正则、关键词规则。前者无法规模化,后者只能判断”有没有”,判断不了”好不好”。像摘要质量、回答相关性、代码是否正确、语气是否得体这类语义问题,必须靠模型的理解能力才能评估。LLM-as-Judge 把评估本身也交给模型,代价只是一次推理调用,却能同时覆盖相关性、准确性、连贯性、安全性等多个维度,这正是它能工程化的关键。尤其在 RAG、摘要、客服问答这类场景,输出千变万化,单靠线上指标(点击率、留存)很难定位到单次生成的质量问题,自动评测就成了低成本、高频率的反馈抓手。
LLM-as-Judge 的核心原理
思路其实很简单:准备”待评测内容 + 评测标准 + 评分指引”,包成一个结构化 prompt 发给裁判模型,让它输出分数与理由。裁判模型通常选比你线上模型更强的版本——例如线上用 7B,裁判就用 70B 或 GPT 级模型。最关键的技巧是把评分标准写具体:”1 到 5 分,5 分表示完全正确且表达清晰”,远比”请打个分”可靠。需要提醒的是,裁判模型也不是越贵越好,关键是和线上模型拉开能力代差;两者过于接近时,裁判的区分度会明显下降,评出来的分数几乎没有区分意义。
为了避免裁判偷懒,实践中要求它先给理由再给分,并把分数约束成固定格式便于解析。把评测提示词当作代码一样对待,也是和上下文工程一脉相承的工程纪律。
快速上手:最小可运行示例
下面是一个不依赖任何框架的最小实现:把问题、回答和评分要求拼成 prompt,调用裁判模型,解析它返回的 JSON。
import requests, os
API = "https://api.your-llm.com/v1/chat/completions"
def judge(question, answer):
prompt = f"""你是一名严格的技术评审。
请对下面的回答打分(1-5,5 为最佳)并给出理由。
【问题】{question}
【回答】{answer}
只输出 JSON:{{"score": int, "reason": str}}"""
r = requests.post(API, json={
"model": "judge-pro",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0,
}, headers={"Authorization": f"Bearer {os.environ['LLM_KEY']}"})
return r.json()["choices"][0]["message"]["content"]
print(judge("什么是数据库索引?", "索引是加速查询的数据结构。"))
评测维度与评分量表
评什么,比怎么评更重要。下面是一张常用的维度表,覆盖从事实到安全的五个层面,每个维度都应给出清晰的锚点描述,让裁判理解”5 分”和”3 分”到底差在哪。
| 维度 | 含义 | 低分示例 |
|---|---|---|
| 相关性 | 回答是否切题 | 问性能却答语法,相关性低 |
| 准确性 | 事实是否正确 | 把 1970 说成 1971 |
| 连贯性 | 语言是否通顺 | 逻辑断裂、大量重复 |
| 安全性 | 是否含有害内容 | 出现越狱或歧视表述 |
| 格式合规 | 是否满足格式要求 | 要求 JSON 却返回散文 |
进阶:多维度结构化打分
单分数信息量有限。更常见的是让裁判一次性返回多个维度的分数,再聚合分析。把输出约束成 JSON,配合 response_format 或后置解析,可以稳定地拿到结构化结果。
def judge_struct(question, answer):
prompt = f"""请对回答做多维度评分,只输出 JSON:
{{
"relevance": 1-5,
"accuracy": 1-5,
"coherence": 1-5,
"reason": "一句话说明评分依据"
}}
【问题】{question}
【回答】{answer}"""
# 调用裁判模型并解析 JSON;解析失败时重试或记 None
return call_llm_json(prompt)
控制偏差:裁判也会偏心
LLM 裁判不是完美的,常见三类系统性偏差。位置偏差指把候选放前面更容易得高分,解决办法是随机或双向排列后取平均;自我偏好指裁判偏爱”自己风格”的输出,可换一个不同家族的模型当裁判;冗长偏好指更长的回答常被误判为更好,应在评分标准里明确”长度不计入评分”。
| 偏差类型 | 表现 | 对策 |
|---|---|---|
| 位置偏差 | 顺序影响分数 | 双向排列取平均 |
| 自我偏好 | 偏爱同风格输出 | 换不同家族裁判 |
| 冗长偏好 | 越长分越高 | 标准中声明不计长度 |
| 尺度漂移 | 同标准分数忽高忽低 | temperature=0 + 固定示例 |
与人工、规则评测的对比
LLM-as-Judge 不是要取代人工,而是补上”大规模语义评估”这块短板。三种方式各擅胜场,组合使用最稳。
| 方式 | 成本 | 规模 | 适用场景 |
|---|---|---|---|
| 人工评测 | 高 | 低 | 上线前抽样校准 |
| 规则评测 | 低 | 中 | 格式 / 关键词硬校验 |
| LLM-as-Judge | 中 | 高 | 语义质量大规模回归 |
生产化落地建议
下面是一个把单条评测扩展成批处理的骨架:捕获异常、聚合平均,并只在拿到有效分数时计入统计。
from statistics import mean
def batch_judge(qa_pairs):
rows = []
for q, a in qa_pairs:
try:
j = judge_struct(q, a)
rows.append(j)
except Exception:
rows.append({"relevance": None})
scores = [r["relevance"] for r in rows if r.get("relevance")]
return {"avg_relevance": mean(scores), "n": len(scores)}
生产化时还要注意四点:第一,抽样人工复核,定期用人工标注校准裁判一致性(计算简单相关系数);第二,把评测接进 CI,每次模型升级跑回归,分数明显下滑就拦截;第三,评测提示词和裁判模型版本一起纳入版本管理;第四,成本上,裁判调用也消耗 token,可只对困难样本或抽样启用,相关权衡可参考我们关于推理成本优化的讨论。LLM-as-Judge 衡量的是”相对质量”,最终仍要以业务指标为准。如果你要进一步量化智能体的真实能力,它也可以作为底层打分器。把评测链路本身接进Langfuse 可观测,还能追踪每次评测的成本与分布。
另外,评测集本身要随业务持续演进。一个常见的反模式是评测集长期不更新,导致分数虚高却与真实用户脱节。建议每月从线上真实样本里抽一批,人工标注后补充进评测集,让指标始终贴着真实分布;同时保留历史评测结果,才能看出模型迭代到底是在进步还是退步。
小结
LLM-as-Judge 用一次推理的代价,把模型输出的质量从”靠感觉”变成”可度量、可回归”。落地关键是把评分标准写具体、控制三类典型偏差、并把评测接进持续流程。它与人工抽检、规则校验互补而非替代。当你准备系统评估生成质量时,这套方法能让迭代从盲人摸象变成有数据支撑的闭环。




