LLM评估Skill llm-evaluation

该技能用于实施全面的LLM应用评估策略,包括自动指标计算、人工反馈收集和基准测试。适用于测试LLM性能、测量AI应用质量、建立评估框架等场景。关键词:LLM评估、自动指标、人工评估、A/B测试、基准测试、AI应用质量。

AI应用 0 次安装 0 次浏览 更新于 3/16/2026

name: llm-evaluation description: 使用自动指标、人工反馈和基准测试实施LLM应用的全面评估策略。用于测试LLM性能、测量AI应用质量或建立评估框架。

LLM评估

掌握LLM应用的全面评估策略,从自动指标到人工评估和A/B测试。

何时使用此技能

  • 系统测量LLM应用性能
  • 比较不同模型或提示
  • 部署前检测性能回归
  • 验证提示更改的改进
  • 建立对生产系统的信心
  • 建立基线并随时间跟踪进展
  • 调试意外模型行为

核心评估类型

1. 自动指标

快速、可重复、可扩展的评估使用计算分数。

文本生成:

  • BLEU: N-gram重叠(翻译)
  • ROUGE: 面向召回(摘要)
  • METEOR: 语义相似度
  • BERTScore: 基于嵌入的相似度
  • Perplexity: 语言模型置信度

分类:

  • Accuracy: 正确百分比
  • Precision/Recall/F1: 类特定性能
  • Confusion Matrix: 错误模式
  • AUC-ROC: 排名质量

检索(RAG):

  • MRR: 平均倒数排名
  • NDCG: 标准化折扣累积增益
  • Precision@K: 前K个相关
  • Recall@K: 前K个覆盖率

2. 人工评估

手动评估难以自动化的质量方面。

维度:

  • Accuracy: 事实正确性
  • Coherence: 逻辑流
  • Relevance: 回答问题
  • Fluency: 自然语言质量
  • Safety: 无有害内容
  • Helpfulness: 对用户有用

3. LLM-as-Judge

使用更强的LLM评估较弱模型的输出。

方法:

  • Pointwise: 评分单个响应
  • Pairwise: 比较两个响应
  • Reference-based: 与黄金标准比较
  • Reference-free: 无地面实况判断

快速开始

from llm_eval import EvaluationSuite, Metric

# 定义评估套件
suite = EvaluationSuite([
    Metric.accuracy(),
    Metric.bleu(),
    Metric.bertscore(),
    Metric.custom(name="groundedness", fn=check_groundedness)
])

# 准备测试用例
test_cases = [
    {
        "input": "法国的首都是什么?",
        "expected": "巴黎",
        "context": "法国是欧洲的一个国家。巴黎是其首都。"
    },
    # ... 更多测试用例
]

# 运行评估
results = suite.evaluate(
    model=your_model,
    test_cases=test_cases
)

print(f"总体准确率: {results.metrics['accuracy']}")
print(f"BLEU分数: {results.metrics['bleu']}")

自动指标实现

BLEU分数

from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction

def calculate_bleu(reference, hypothesis):
    """计算参考和假设之间的BLEU分数。"""
    smoothie = SmoothingFunction().method4

    return sentence_bleu(
        [reference.split()],
        hypothesis.split(),
        smoothing_function=smoothie
    )

# 使用
bleu = calculate_bleu(
    reference="猫坐在垫子上",
    hypothesis="一只猫正坐在垫子上"
)

ROUGE分数

from rouge_score import rouge_scorer

def calculate_rouge(reference, hypothesis):
    """计算ROUGE分数。"""
    scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True)
    scores = scorer.score(reference, hypothesis)

    return {
        'rouge1': scores['rouge1'].fmeasure,
        'rouge2': scores['rouge2'].fmeasure,
        'rougeL': scores['rougeL'].fmeasure
    }

BERTScore

from bert_score import score

def calculate_bertscore(references, hypotheses):
    """使用预训练BERT计算BERTScore。"""
    P, R, F1 = score(
        hypotheses,
        references,
        lang='en',
        model_type='microsoft/deberta-xlarge-mnli'
    )

    return {
        'precision': P.mean().item(),
        'recall': R.mean().item(),
        'f1': F1.mean().item()
    }

自定义指标

def calculate_groundedness(response, context):
    """检查响应是否基于提供的上下文。"""
    # 使用NLI模型检查蕴含
    from transformers import pipeline

    nli = pipeline("text-classification", model="microsoft/deberta-large-mnli")

    result = nli(f"{context} [SEP] {response}")[0]

    # 返回响应被上下文蕴含的置信度
    return result['score'] if result['label'] == 'ENTAILMENT' else 0.0

def calculate_toxicity(text):
    """测量生成文本的毒性。"""
    from detoxify import Detoxify

    results = Detoxify('original').predict(text)
    return max(results.values())  # 返回最高毒性分数

def calculate_factuality(claim, knowledge_base):
    """根据知识库验证事实声明。"""
    # 实现取决于您的知识库
    # 可以使用检索 + NLI,或事实检查API
    pass

LLM-as-Judge模式

单输出评估

def llm_judge_quality(response, question):
    """使用GPT-4判断响应质量。"""
    prompt = f"""在1-10的尺度上评估以下响应的:
1. 准确性(事实正确)
2. 有帮助性(回答问题)
3. 清晰度(写得好且易懂)

问题: {question}
响应: {response}

以JSON格式提供评分:
{{
  "accuracy": <1-10>,
  "helpfulness": <1-10>,
  "clarity": <1-10>,
  "reasoning": "<简要解释>"
}}
"""

    result = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}],
        temperature=0
    )

    return json.loads(result.choices[0].message.content)

成对比较

def compare_responses(question, response_a, response_b):
    """使用LLM法官比较两个响应。"""
    prompt = f"""比较这两个对问题的响应,并确定哪个更好。

问题: {question}

响应 A: {response_a}

响应 B: {response_b}

哪个响应更好,为什么?考虑准确性、有帮助性和清晰度。

以JSON回答:
{{
  "winner": "A" 或 "B" 或 "tie",
  "reasoning": "<解释>",
  "confidence": <1-10>
}}
"""

    result = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}],
        temperature=0
    )

    return json.loads(result.choices[0].message.content)

人工评估框架

注释指南

class AnnotationTask:
    """人类注释任务的结构。"""

    def __init__(self, response, question, context=None):
        self.response = response
        self.question = question
        self.context = context

    def get_annotation_form(self):
        return {
            "question": self.question,
            "context": self.context,
            "response": self.response,
            "ratings": {
                "accuracy": {
                    "scale": "1-5",
                    "description": "响应是否事实正确?"
                },
                "relevance": {
                    "scale": "1-5",
                    "description": "它回答问题吗?"
                },
                "coherence": {
                    "scale": "1-5",
                    "description": "它逻辑一致吗?"
                }
            },
            "issues": {
                "factual_error": False,
                "hallucination": False,
                "off_topic": False,
                "unsafe_content": False
            },
            "feedback": ""
        }

评分者间一致性

from sklearn.metrics import cohen_kappa_score

def calculate_agreement(rater1_scores, rater2_scores):
    """计算评分者间一致性。"""
    kappa = cohen_kappa_score(rater1_scores, rater2_scores)

    interpretation = {
        kappa < 0: "差",
        kappa < 0.2: "轻微",
        kappa < 0.4: "公平",
        kappa < 0.6: "中等",
        kappa < 0.8: "实质性",
        kappa <= 1.0: "几乎完美"
    }

    return {
        "kappa": kappa,
        "interpretation": interpretation[True]
    }

A/B测试

统计测试框架

from scipy import stats
import numpy as np

class ABTest:
    def __init__(self, variant_a_name="A", variant_b_name="B"):
        self.variant_a = {"name": variant_a_name, "scores": []}
        self.variant_b = {"name": variant_b_name, "scores": []}

    def add_result(self, variant, score):
        """为变体添加评估结果。"""
        if variant == "A":
            self.variant_a["scores"].append(score)
        else:
            self.variant_b["scores"].append(score)

    def analyze(self, alpha=0.05):
        """执行统计分析。"""
        a_scores = self.variant_a["scores"]
        b_scores = self.variant_b["scores"]

        # T-检验
        t_stat, p_value = stats.ttest_ind(a_scores, b_scores)

        # 效应大小(Cohen's d)
        pooled_std = np.sqrt((np.std(a_scores)**2 + np.std(b_scores)**2) / 2)
        cohens_d = (np.mean(b_scores) - np.mean(a_scores)) / pooled_std

        return {
            "variant_a_mean": np.mean(a_scores),
            "variant_b_mean": np.mean(b_scores),
            "difference": np.mean(b_scores) - np.mean(a_scores),
            "relative_improvement": (np.mean(b_scores) - np.mean(a_scores)) / np.mean(a_scores),
            "p_value": p_value,
            "statistically_significant": p_value < alpha,
            "cohens_d": cohens_d,
            "effect_size": self.interpret_cohens_d(cohens_d),
            "winner": "B" if np.mean(b_scores) > np.mean(a_scores) else "A"
        }

    @staticmethod
    def interpret_cohens_d(d):
        """解释Cohen's d效应大小。"""
        abs_d = abs(d)
        if abs_d < 0.2:
            return "可忽略"
        elif abs_d < 0.5:
            return "小"
        elif abs_d < 0.8:
            return "中"
        else:
            return "大"

回归测试

回归检测

class RegressionDetector:
    def __init__(self, baseline_results, threshold=0.05):
        self.baseline = baseline_results
        self.threshold = threshold

    def check_for_regression(self, new_results):
        """检测新结果是否显示回归。"""
        regressions = []

        for metric in self.baseline.keys():
            baseline_score = self.baseline[metric]
            new_score = new_results.get(metric)

            if new_score is None:
                continue

            # 计算相对变化
            relative_change = (new_score - baseline_score) / baseline_score

            # 标记如果有显著下降
            if relative_change < -self.threshold:
                regressions.append({
                    "metric": metric,
                    "baseline": baseline_score,
                    "current": new_score,
                    "change": relative_change
                })

        return {
            "has_regression": len(regressions) > 0,
            "regressions": regressions
        }

基准测试

运行基准

class BenchmarkRunner:
    def __init__(self, benchmark_dataset):
        self.dataset = benchmark_dataset

    def run_benchmark(self, model, metrics):
        """在基准上运行模型并计算指标。"""
        results = {metric.name: [] for metric in metrics}

        for example in self.dataset:
            # 生成预测
            prediction = model.predict(example["input"])

            # 计算每个指标
            for metric in metrics:
                score = metric.calculate(
                    prediction=prediction,
                    reference=example["reference"],
                    context=example.get("context")
                )
                results[metric.name].append(score)

        # 聚合结果
        return {
            metric: {
                "mean": np.mean(scores),
                "std": np.std(scores),
                "min": min(scores),
                "max": max(scores)
            }
            for metric, scores in results.items()
        }

资源

  • references/metrics.md: 全面指标指南
  • references/human-evaluation.md: 注释最佳实践
  • references/benchmarking.md: 标准基准
  • references/a-b-testing.md: 统计测试指南
  • references/regression-testing.md: CI/CD集成
  • assets/evaluation-framework.py: 完整评估框架
  • assets/benchmark-dataset.jsonl: 示例数据集
  • scripts/evaluate-model.py: 自动评估运行器

最佳实践

  1. 多个指标: 使用多样化指标进行全面视图
  2. 代表性数据: 在真实世界、多样化例子上测试
  3. 基线: 总是比较基线性能
  4. 统计严谨性: 使用适当的统计测试进行比较
  5. 持续评估: 集成到CI/CD管道中
  6. 人工验证: 结合自动指标与人工判断
  7. 错误分析: 调查失败以理解弱点
  8. 版本控制: 随时间跟踪评估结果

常见陷阱

  • 单一指标痴迷: 优化一个指标而以其他指标为代价
  • 小样本大小: 从太少例子中得出结论
  • 数据污染: 在训练数据上测试
  • 忽略方差: 不考虑统计不确定性
  • 指标不匹配: 使用与业务目标不一致的指标