跳转到内容

如何校准 LLM 作为一个评判者

在本指南中,你将学习如何使用 Ragas 系统地评估和校准一个作为评判者的 LLM 指标,使其与人类专家的判断保持一致。

  • 为评判者校准构建一个可复用的评估流程
  • 分析评判者和人类标签之间的不一致模式
  • 迭代评判者提示以提高与专家决策的一致性

为什么首先要校准你的 LLM 评判者?

在运行评估实验之前,将你的 LLM 评判者校准到你的特定用例非常重要。一个未校准的评判者就像一个指向错误方向的指南针——你根据它的指导所做的每一次改进都会让你离目标越来越远。将评判者校准以匹配专家的判断,可以确保你正在改进真正重要的事情。这个校准步骤是可靠评估的基础。

真正的价值:审视你的数据

虽然构建一个校准过的 LLM 评判者很有用,但真正的商业价值来自于系统地分析你的数据并理解失败模式。评判者校准过程迫使你深入检查边缘案例,澄清评估标准,并揭示关于什么因素使响应好或坏的见解。把评判者看作一个扩展你分析能力的工具,而不是替代品。

设置你的环境

我们创建了一个简单的模块,你可以安装和运行,这样你就可以专注于理解评估过程,而不是创建应用程序。

uv pip install "ragas[examples]"
export OPENAI_API_KEY="your-api-key-here"

完整代码

你可以在这里查看评判者校准评估流程的完整代码。

理解数据集

我们将使用 EvalsBench 数据集,其中包含专家注释的 LLM 对商业问题的响应示例。每一行包括

  • question:提出的原始问题
  • grading_notes:一个好的响应中应该涵盖的关键点
  • response:LLM 生成的响应
  • target:人类专家的二元判断(通过/失败)

下载数据集

# Create datasets folder and download the dataset
mkdir -p datasets
curl -o datasets/benchmark_df.csv https://raw.githubusercontent.com/vibrantlabsai/EvalsBench/main/data/benchmark_df.csv

加载并检查数据集

import pandas as pd
from ragas import Dataset

def load_dataset(csv_path: str = None) -> Dataset:
    """Load annotated dataset with human judgments.

    Expected columns: question, grading_notes, response, target (pass/fail)
    """
    path = csv_path or "datasets/benchmark_df.csv"
    df = pd.read_csv(path)

    dataset = Dataset(name="llm_judge_alignment", backend="local/csv")

    for _, row in df.iterrows():
        dataset.append({
            "question": row["question"],
            "grading_notes": row["grading_notes"],
            "response": row["response"],
            "target": (row["target"]),
        })

    return dataset

# Load the dataset
dataset = load_dataset()
print(f"Dataset loaded with {len(dataset)} samples")

数据集中的样本行

问题 (question) 评分说明 (grading_notes) response 目标 (target)
在 A 轮投资之前,确定一家科技创业公司投前估值的关键方法有哪些?它们有何不同? DCF方法:!未来现金流!,需要预测;可比公司分析:类似公司的倍数;VC方法:收入 x 倍数 - 投后估值;*创始人股份重要*;战略买家支付更高。 在 A 轮投资之前确定一家科技创业公司的投前估值是关键一步... (涵盖了 DCF、可比公司分析、VC 方法) 通过 (pass)
在订阅式商业模式中,初创公司应优先考虑哪些关键指标和策略来有效管理和降低客户流失率? 流失率:!每月监控,<5%为理想。*留存策略*:吸引用户,改善上手体验。CAC & LTV:平衡在3:1+。反馈循环:尽早实施。*客户支持*:主动响应,至关重要。 在订阅式商业模式中管理和降低客户流失率至关重要... (缺少具体的指标和策略) 失败 (fail)

数据集包含了对同一问题的多个响应——有些通过,有些失败。这有助于评判者学习可接受和不可接受响应之间的细微差别。

理解你的基准真相

评判者校准的质量完全取决于你的基准真相标签的质量。在生产场景中,需要让一位**首席领域专家**参与——这个人的判断对你的用例至关重要(例如,心理健康 AI 的心理学家,法律 AI 的律师,或支持聊天机器人的客户服务总监)。他们一致的判断成为你的评判者校准的黄金标准。你不需要给每个例子都打上标签——一个有代表性的样本(100-200个涵盖不同场景的例子)就足以进行可靠的校准。

理解评估方法

在本指南中,我们评估数据集中已有的响应,而不是生成新的响应。这种方法确保了评估运行之间的结果可复现,让我们能够专注于评判者校准,而不是响应生成。

评估工作流程是:数据集行 (问题 + 响应) → 评判者 → 与人类目标比较

定义评估指标

对于评判者校准,我们需要两个指标

主要指标:accuracy (LLM 评判者) - 评估响应并返回通过/失败的决定及原因。

校准指标:judge_alignment - 检查评判者的决定是否与人类专家的裁决相匹配。

设置评判者指标

定义一个简单的基准评判者指标,根据评分说明来评估响应

from ragas.metrics import DiscreteMetric

# Define the judge metric with a simple baseline prompt
accuracy_metric = DiscreteMetric(
    name="accuracy",
    prompt="Check if the response contains points mentioned from the grading notes and return 'pass' or 'fail'.\n\nResponse: {response}\nGrading Notes: {grading_notes}",
    allowed_values=["pass", "fail"],
)

校准指标

校准指标将评判者的决定与人类的裁决进行比较

from ragas.metrics.discrete import discrete_metric
from ragas.metrics.result import MetricResult

@discrete_metric(name="judge_alignment", allowed_values=["pass", "fail"])
def judge_alignment(judge_label: str, human_label: str) -> MetricResult:
    """Compare judge decision with human label."""
    judge = judge_label.strip().lower()
    human = human_label.strip().lower()

    if judge == human:
        return MetricResult(value="pass", reason=f"Judge={judge}; Human={human}")

    return MetricResult(value="fail", reason=f"Judge={judge}; Human={human}")

实验函数

实验函数协调整个评估流程——用评判者评估响应并衡量校准度

from typing import Dict, Any
from ragas import experiment
from ragas.metrics import DiscreteMetric
from ragas_examples.judge_alignment import judge_alignment  # The metric we created above

@experiment()
async def judge_experiment(
    row: Dict[str, Any],
    accuracy_metric: DiscreteMetric,
    llm,
):
    """Run complete evaluation: Judge → Compare with human."""
    # Step 1: Get response (in production, this is where you'd call your LLM app)
    # For this evaluation, we use pre-existing responses from the dataset
    app_response = row["response"]

    # Step 2: Judge evaluates the response
    judge_score = await accuracy_metric.ascore(
        question=row["question"],
        grading_notes=row["grading_notes"],
        response=app_response,
        llm=llm,
    )

    # Step 3: Compare judge decision with human target
    alignment = judge_alignment.score(
        judge_label=judge_score.value,
        human_label=row["target"]
    )

    return {
        **row,
        "judge_label": judge_score.value,
        "judge_reason": judge_score.reason,
        "alignment": alignment.value,
        "alignment_reason": alignment.reason,
    }

运行基准评估

执行评估流程并收集结果

import os
from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas_examples.judge_alignment import load_dataset

# Load dataset
dataset = load_dataset()
print(f"Dataset loaded with {len(dataset)} samples")

# Initialize LLM client
openai_client = AsyncOpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
llm = llm_factory("gpt-4o-mini", client=openai_client)

# Run the experiment
results = await judge_experiment.arun(
    dataset,
    name="judge_baseline_v1_gpt-4o-mini",
    accuracy_metric=accuracy_metric,
    llm=llm,
)

# Calculate alignment rate
passed = sum(1 for r in results if r["alignment"] == "pass")
total = len(results)
print(f"✅ Baseline alignment: {passed}/{total} passed ({passed/total:.1%})")
📋 输出 (基准 v1)
2025-10-08 22:40:00,334 - Loaded dataset with 160 samples
2025-10-08 22:40:00,334 - Initializing LLM client with model: gpt-4o-mini
2025-10-08 22:40:01,858 - Running baseline evaluation...
Running experiment: 100%|████████████████████████| 160/160 [04:35<00:00,  1.72s/it]
2025-10-08 22:44:37,149 - ✅ Baseline alignment: 121/160 passed (75.6%)

初步性能分析

评估会生成全面的 CSV 结果,包含所有输入(问题、评分说明、响应)、人类目标、评判者的决定与理由,以及校准度比较。

分析错误和失败模式

运行基准评估后,我们可以分析不一致的模式,以了解评判者在哪些地方与人类专家意见不合。

基准性能:75.6% 的校准度 (160 个中有 121 个正确)

让我们检查一下错误分布

📋 代码
import pandas as pd

# Load results
df = pd.read_csv('experiments/judge_baseline_v1_gpt-4o-mini.csv')

# Analyze misalignments
false_positives = len(df[(df['judge_label'] == 'pass') & (df['target'] == 'fail')])
false_negatives = len(df[(df['judge_label'] == 'fail') & (df['target'] == 'pass')])

print(f"False positives (judge too lenient): {false_positives}")
print(f"False negatives (judge too strict): {false_negatives}")

📋 输出

False positives (judge too lenient): 39
False negatives (judge too strict): 0

关键观察: 所有 39 个不一致 (24.4%) 都是假阳性——即评判者认为是“通过”但人类专家认为是“失败”的案例。基准评判者过于宽松,漏掉了那些忽略了评分说明中关键概念的响应。

失败案例样本

以下是评判者错误地将缺少关键概念的响应评为通过的例子

评分说明 人类标签 评判者标签 缺少了什么
*估值上限*,$,投后估值关键。清算优先权:1x+ 常见。反稀释:*完全稀释 vs. 加权平均*。董事会席位:1-2 个投资者代表。ESOP:10-20%。 失败 (fail) 通过 (pass) 响应全面讨论了所有要点,但人类标注者因细微遗漏将其标记为失败
*对估值的影响*:可扩展性潜力,开发成本,集成难度。!开源 vs 专有问题。!技术债务风险。讨论 AWS/GCP/Azure... 失败 (fail) 通过 (pass) 缺少对投后估值影响的具体讨论
历史 vs. 预测收入;自上而下 & 自下而上方法;*增长势头证据*;!无偏见的假设;12-24个月项目... 失败 (fail) 通过 (pass) 缺少对增长势头证据的明确提及

错误中的常见模式

  1. 评分说明中缺少 1-2 个特定概念,但涵盖了其他概念
  2. 隐含 vs 显式覆盖 - 评判者接受了隐含的概念,但我们希望是明确提及
  3. 缩写词未正确解码(例如,“mkt demand” = 市场需求,“post-$” = 投后估值)
  4. 忽略了关键标记 - 用 *! 标记的点通常是必不可少的

改进评判者提示

根据错误分析,我们需要创建一个改进的提示,该提示能够

  1. 理解评分说明中使用的缩写
  2. 识别关键标记 (*, !, 特定数字)
  3. 要求所有概念都存在,而不仅仅是大多数
  4. 接受语义等价物(同一概念的不同措辞)
  5. 平衡严格性 - 不过于宽松也不过于严格

创建改进的 v2 提示

定义带有全面评估标准的增强型评判者指标

from ragas.metrics import DiscreteMetric

# Define improved judge metric with enhanced evaluation criteria
accuracy_metric_v2 = DiscreteMetric(
    name="accuracy",
    prompt="""Evaluate if the response covers ALL the key concepts from the grading notes. Accept semantic equivalents but carefully check for missing concepts.

ABBREVIATION GUIDE - decode these correctly:

• Financial: val=valuation, post-$=post-money, rev=revenue, ARR/MRR=Annual/Monthly Recurring Revenue, COGS=Cost of Goods Sold, Opex=Operating Expenses, LTV=Lifetime Value, CAC=Customer Acquisition Cost
• Business: mkt=market, reg/regs=regulation/regulatory, corp gov=corporate governance, integr=integration, S&M=Sales & Marketing, R&D=Research & Development, acq=acquisition
• Technical: sys=system, elim=elimination, IP=Intellectual Property, TAM=Total Addressable Market, diff=differentiation
• Metrics: NPS=Net Promoter Score, SROI=Social Return on Investment, proj=projection, cert=certification

EVALUATION APPROACH:

Step 1 - Parse grading notes into distinct concepts:

- Separate by commas, semicolons, or line breaks
- Each item is a concept that must be verified
- Example: "*Gross Margin* >40%, CAC, LTV:CAC >3:1" = 3 concepts

Step 2 - For each concept, check if it's addressed:

- Accept semantic equivalents (e.g., "customer acquisition cost" = "CAC")
- Accept implicit coverage when it's clear (e.g., "revenue forecasting" covers "historical vs forecasted rev")
- Be flexible on exact numbers (e.g., "around 40%" acceptable for ">40%")

Step 3 - Count missing concepts:

- Missing 0 concepts = PASS
- Missing 1+ concepts = FAIL (even one genuinely missing concept should fail)
- Exception: If a long list (10+ items) has 1 very minor detail missing but all major points covered, use judgment

CRITICAL RULES:

1. Do NOT require exact wording - "market demand" = "mkt demand" = "demand analysis"

2. Markers (* or !) mean important, not mandatory exact phrases:
   - "*traction evidence*" can be satisfied by discussing metrics, growth, or validation
   - "!unbiased assumptions" can be satisfied by discussing assumption methodology

3. Numbers should be mentioned but accept approximations:
   - "$47B to $10B" can be "$47 billion dropped to around $10 billion"
   - "LTV:CAC >3:1" can be "LTV to CAC ratio of at least 3 to 1" or "3x or higher"

4. FAIL only when concepts are genuinely absent:
   - If notes mention "liquidation prefs, anti-dilution, board seats" but response only has board seats → FAIL
   - If notes mention "scalability, tech debt, IP" but response never discusses technical risks → FAIL
   - If notes mention "GDPR compliance" and response never mentions GDPR or EU regulations → FAIL

5. PASS when ALL concepts present:
   - All concepts covered, even with different wording → PASS
   - Concepts addressed implicitly when clearly implied → PASS
   - Minor phrasing differences → PASS
   - One or more concepts genuinely absent → FAIL

Response: {response}

Grading Notes: {grading_notes}

Are ALL distinct concepts from the grading notes covered in the response (accepting semantic equivalents and implicit coverage)?""",
    allowed_values=["pass", "fail"],
)

使用 LLM 优化提示

在你清楚地识别出错误模式后,你可以使用 LLM 来优化提示。你也可以使用 LLM 来识别错误,但要确保审查它们,使其与基准真相标签保持一致。你还可以使用像 Cursor、Claude Code 这样的编码代理,或像 DSPy 这样的框架来系统地优化评判者提示。

使用改进的提示重新运行评估

使用增强的 v2 提示再次运行评估(设置与基准相同,只需更换指标)

# Use the same dataset and LLM setup from the baseline evaluation above
results = await judge_experiment.arun(
    dataset,
    name="judge_accuracy_v2_gpt-4o-mini",
    accuracy_metric=accuracy_metric_v2,  # ← Using improved v2 prompt
    llm=llm,
)

passed = sum(1 for r in results if r["alignment"] == "pass")
total = len(results)
print(f"✅ V2 alignment: {passed}/{total} passed ({passed/total:.1%})")
📋 输出 (改进的 v2)
2025-10-08 23:42:11,650 - Loaded dataset with 160 samples
2025-10-08 23:42:11,650 - Initializing LLM client with model: gpt-4o-mini
2025-10-08 23:42:12,730 - Running v2 evaluation with improved prompt...
Running experiment: 100%|██████████| 160/160 [04:39<00:00,  1.75s/it]
2025-10-08 23:46:52,740 - ✅ V2 alignment: 139/160 passed (86.9%)

显著改进! 校准度从 75.6% 增加到 86.9%。

如果你需要进一步迭代

  • 分析剩余的错误以识别模式(它们是假阳性还是假阴性?)
  • 在标注标签的同时,也标注你的理由——这将有助于改进 LLM 评判者,你也可以将这些作为少样本示例添加。
  • 使用更智能的模型 - 像 GPT-5 或 Claude 4.5 Sonnet 这样能力更强的模型通常作为评判者表现更好
  • 利用 AI 助手 - 本指南是使用 Cursor AI 代理来分析失败并迭代提示创建的。你可以使用 AI 编码代理(Cursor、Claude 等)或像 DSPy 这样的框架来系统地优化评判者提示
  • 当校准度在 2-3 次迭代中趋于平稳或达到你的业务阈值时停止

你取得了什么成就

你已经使用 Ragas 构建了一个系统的评估流程,该流程

  • 用明确的指标衡量评判者与专家判断的一致性
  • 通过结构化的错误分析识别失败模式
  • 通过可复现的实验跟踪评估运行中的改进

这个校准过的评判者成为你可靠 AI 评估的基础。有了一个你可以信任的评判者,你现在可以自信地评估你的 RAG 流程、代理工作流或任何 LLM 应用程序——因为你知道指标的改进会转化为质量的真正提升。