LLM-as-Judge 实战:用大模型自动评测输出质量

当你把大模型接进生产环境,第一个绕不开的问题就是:怎么知道它生成的内容到底好不好?人工逐条看既不经济也不可规模化。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 用一次推理的代价,把模型输出的质量从”靠感觉”变成”可度量、可回归”。落地关键是把评分标准写具体、控制三类典型偏差、并把评测接进持续流程。它与人工抽检、规则校验互补而非替代。当你准备系统评估生成质量时,这套方法能让迭代从盲人摸象变成有数据支撑的闭环。

上一篇 ArgoCD GitOps 实战:K8s 声明式持续部署
下一篇 lazygit 实战:终端里的 Git 可视化操作