Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第三章:评估体系设计

本章系统性地讲解如何设计 AI 系统的评估体系——从指标选择到数据集构建。

评估体系的整体框架

三层评估架构

graph TB
    subgraph "离线评估"
        A1[Benchmark评估] --> A2[Golden Set评估]
        A2 --> A3[自动化评分]
    end
    
    subgraph "在线评估"
        B1[A/B测试] --> B2[用户行为分析]
        B2 --> B3[实时监控]
    end
    
    subgraph "人工评估"
        C1[专家评审] --> C2[用户反馈]
        C2 --> C3[标注修正]
    end
    
    A3 --> D[综合质量报告]
    B3 --> D
    C3 --> D
    
    D --> E[模型优化决策]

建议权重:

评估流程闭环

graph LR
    A[数据准备] --> B[执行评估]
    B --> C[结果分析]
    
    A --> A1[Golden Set]
    A --> A2[Boundary]
    A --> A3[Adversarial]
    B --> B1[批量执行]
    B --> B2[模型调用]
    B --> B3[评分计算]
    C --> C1[得分统计]
    C --> C2[问题定位]
    C --> C3[改进建议]
    
    C -->|持续迭代| A

指标体系设计

指标分类框架

类别指标适用场景特点
准确性Exact Match, F1分类、抽取确定性比较
语义相似BLEU, ROUGE, Semantic Sim生成、翻译参考对比
模型评估G-Eval, PrometheusLLM输出模型作为裁判
任务完成Task Success RateAgent系统功能验证
用户体验Satisfaction, Engagement产品级主观反馈

指标选择方法论

选择指标的决策树:

graph TB
    A[任务类型?] --> B{有参考答案?}
    
    B -->|Yes| C[参考匹配类指标]
    B -->|No| D[模型评估类指标]
    
    C --> C1[Exact Match - 精确匹配]
    C --> C2[BLEU/ROUGE - 文本相似]
    C --> C3[Semantic Sim - 语义相似]
    
    D --> D1[G-Eval - GPT-4评分]
    D --> D2[Prometheus - 专用评估模型]
    D --> D3[Human Eval - 人工评审]

具体场景指标推荐:

场景推荐指标原因
QA问答Exact Match + Semantic Sim有参考答案,需语义理解
翻译BLEU + Comet专业翻译评估指标
代码生成Pass Rate + Syntax Check可执行验证
创意写作G-Eval + Human Review无标准答案,需主观评价
RAG检索Recall + MRR + NDCG检索质量标准指标
Agent任务Task Success Rate端到端验证

指标组合策略

单一指标不足以反映真实质量,需要组合:

组合设计原则

  1. 至少包含一个客观指标(可量化)
  2. 至少包含一个主观指标(语义/体验)
  3. 安全类场景必须包含安全指标
  4. 权重根据业务优先级调整

组合示例:客服 AI 评估

evaluation:
  metrics:
    - name: answer_accuracy
      type: semantic_similarity
      weight: 0.3
      threshold: 0.8
    
    - name: response_relevance
      type: g_eval  # GPT-4评分
      weight: 0.25
      threshold: 7  # 1-10分
    
    - name: safety_check
      type: rule_based
      weight: 0.25
      rules: [no_harmful_content, no_pii_leak]
    
    - name: user_satisfaction
      type: feedback_score
      weight: 0.2
      source: user_rating

评估数据集构建

Golden Set 设计原则

Golden Set 是评估的核心数据集,需要精心设计:

Golden Set 定义

Golden Set = 精选的高质量代表案例集

  • 数量:100-500个(根据场景复杂度)
  • 质量:人工审核,确保准确性
  • 代表性:覆盖典型场景和关键边界
  • 版本化:锁定版本,用于基线对比

构建流程:

graph LR
    A[场景分析] --> B[案例收集]
    B --> C[案例筛选]
    C --> D[答案标注]
    D --> E[质量审核]
    E --> F[版本锁定]
    
    F --> G[Golden Set v1.0]
步骤方法注意事项
场景分析分析用户真实需求避免遗漏高频场景
案例收集从日志、问卷、专家收集保证多样性
案例筛选选取代表性案例控制数量
答案标注专家撰写标准答案硔保答案质量
质量审核多人交叉审核消除标注偏差
版本锁定Git版本管理不可随意修改

多层数据集架构

graph TB
    A[Golden Set<br/>100-500案例<br/>高质量标注] --> B[Boundary Set<br/>50-100<br/>边界案例]
    A --> C[Adversarial Set<br/>30-50<br/>攻击案例]
    B --> D[Diversity Set<br/>语义变体<br/>自动生成]
数据集类型数量目的构建方法
Golden Set100-500基线评估人工精选标注
Boundary Set50-100边界测试专家设计极端案例
Adversarial Set30-50安全测试攻击性案例设计
Diversity Set可扩展覆盖性测试模型生成变体

数据集版本管理

# 数据集版本化示例
class DatasetVersion:
    """
    评估数据集版本管理
    """
    def __init__(self, name: str, version: str):
        self.name = name
        self.version = version
        self.locked = False
        self.checksum = None
    
    def lock(self):
        """锁定版本,生成checksum"""
        self.locked = True
        self.checksum = compute_hash(self.data)
        # 记录到版本历史
        save_version_record(self.name, self.version, self.checksum)
    
    def verify(self):
        """验证数据完整性"""
        current_hash = compute_hash(self.data)
        return current_hash == self.checksum

版本管理重要性

每次评估必须使用相同版本的数据集 数据集变更 = 评估基线变更 需要明确记录变更原因和影响

评估执行流程

执行架构

graph TB
    A[评估请求] --> B[数据加载器]
    B --> C[评估引擎]
    
    C --> D1[模型调用器]
    D1 --> D2[响应收集]
    D2 --> D3[评分计算]
    
    D3 --> E[结果聚合]
    E --> F[报告生成]
    F --> G[可视化展示]
    
    subgraph "并行执行"
        D1 --> P1[Case 1]
        D1 --> P2[Case 2]
        D1 --> P3[Case N]
    end

执行配置示例

evaluation_config:
  dataset: golden_set_v1.2
  model: 
    name: gpt-4-turbo
    temperature: 0.3
    max_tokens: 1000
  
  evaluators:
    - type: semantic_similarity
      model: text-embedding-3
    - type: g_eval
      criteria: [accuracy, relevance, coherence]
    
  execution:
    parallel: true
    batch_size: 10
    retry: 3
    timeout: 30s
    
  output:
    format: json
    path: results/eval_2024_01_15.json
    include:
      - scores
      - raw_outputs
      - latency

结果分析与报告

评估结果应包含:

内容说明用途
总体得分综合质量分数基线对比
分项得分各指标得分问题定位
案例详情每个案例结果深入分析
失败案例未达标案例列表优化重点
分布统计得分分布、置信区间稳定性分析
版本对比与历史版本对比回归评估

报告设计原则

  1. 一页概览:总体结论一目了然
  2. 可钻取:从总览到细节层层深入
  3. 可对比:与历史版本、竞品对比
  4. 可行动:明确的优化建议

人工评估集成

为什么需要人工评估

graph TB
    A[自动化评估局限] --> B[语义理解边界]
    A --> C[主观质量判断]
    A --> D[新问题发现]
    
    B --> E[需要人工校验]
    C --> E
    D --> E
自动评估局限人工评估补充
语义相似≠实际有用用户真实体验判断
无法发现新模式问题专家直觉发现问题
指标设计可能有偏差人工校准指标
安全问题复杂多变专家安全审查

Human-in-the-Loop 设计

graph TB
    subgraph 自动评估
        A[执行评估] --> B[得分计算]
    end
    
    subgraph 人工评估
        C[抽样送审] --> D[专家评分]
    end
    
    A --> E[初筛结果]
    B --> E
    E --> F[低分标记]
    
    C --> G[深度审核]
    D --> G
    G --> H[校准评分]
    
    F --> I[综合报告]
    H --> I

抽样策略:

策略适用场景比例建议
随机抽样常规评估5-10%
低分优先问题深入分析所有低于阈值的案例
边界案例覆盖性验证全部边界案例
新模式发现新问题抽样 + 专家直觉选择

实战:构建客服 AI 评估系统

场景背景

某电商平台需要评估其 AI 客服系统的质量,覆盖以下场景:

  • 咨询类:产品信息、价格、库存查询
  • 操作类:订单查询、退货申请、修改地址
  • 投诉类:质量问题、物流投诉、服务投诉

评估系统完整实现

# evaluation_system/customer_service_eval.py
import asyncio
from typing import Dict, List
from dataclasses import dataclass
from datetime import datetime

@dataclass
class TestCase:
    """评估测试案例"""
    id: str
    category: str  # 咨询/操作/投诉
    input: str
    reference: str  # 标准答案
    criteria: List[str]  # 评估标准
    priority: str  # high/medium/low

@dataclass
class EvalResult:
    """评估结果"""
    case_id: str
    output: str
    scores: Dict[str, float]
    overall_score: float
    passed: bool
    latency_ms: int
    timestamp: datetime

class CustomerServiceEvaluator:
    """
    客服 AI 评估系统
    支持多种评估维度
    """
    
    def __init__(self, config: Dict):
        self.config = config
        self.semantic_evaluator = SemanticSimilarityEvaluator()
        self.g_evaluator = GEvalEvaluator()
        self.safety_checker = SafetyChecker()
        self.task_checker = TaskCompletionChecker()
    
    async def evaluate_case(self, case: TestCase, model_output: str) -> EvalResult:
        """
        评估单个案例
        """
        scores = {}
        
        # 1. 语义相似度评估
        scores["semantic_sim"] = await self.semantic_evaluator.evaluate(
            model_output, case.reference
        )
        
        # 2. G-Eval 多维度评估
        g_scores = await self.g_evaluator.evaluate(
            input=case.input,
            output=model_output,
            criteria=["relevance", "accuracy", "tone", "actionable"]
        )
        scores["g_eval"] = g_scores
        
        # 3. 安全性检查
        safety_result = await self.safety_checker.check(model_output)
        scores["safety"] = 1.0 if safety_result.safe else 0.0
        scores["safety_issues"] = safety_result.issues
        
        # 4. 任务完成度检查(针对操作类)
        if case.category == "操作":
            task_result = await self.task_checker.check(
                case.input, model_output, case.criteria
            )
            scores["task_completion"] = task_result.score
        
        # 计算综合得分
        weights = {
            "semantic_sim": 0.25,
            "g_eval_overall": 0.35,
            "safety": 0.25,  # 安全必须有
            "task_completion": 0.15
        }
        
        overall = self._compute_overall(scores, weights)
        passed = overall >= self.config["threshold"] and scores["safety"] == 1.0
        
        return EvalResult(
            case_id=case.id,
            output=model_output,
            scores=scores,
            overall_score=overall,
            passed=passed,
            latency_ms=0,  # 由执行层填充
            timestamp=datetime.now()
        )
    
    def _compute_overall(self, scores: Dict, weights: Dict) -> float:
        """加权计算综合得分"""
        total = 0.0
        total_weight = 0.0
        
        # 语义相似度
        total += scores["semantic_sim"] * weights["semantic_sim"]
        total_weight += weights["semantic_sim"]
        
        # G-Eval
        g_overall = scores["g_eval"]["overall"]
        total += g_overall * weights["g_eval_overall"]
        total_weight += weights["g_eval_overall"]
        
        # 安全性
        total += scores["safety"] * weights["safety"]
        total_weight += weights["safety"]
        
        # 任务完成度(如有)
        if "task_completion" in scores:
            total += scores["task_completion"] * weights["task_completion"]
            total_weight += weights["task_completion"]
        
        return total / total_weight if total_weight > 0 else 0.0

Golden Set 构建示例

# datasets/golden_set_v1.0.yaml
metadata:
  name: "customer_service_golden_set"
  version: "1.0"
  created: "2024-01-10"
  checksum: "sha256:abc123..."
  total_cases: 150
  
categories:
  consultation: 60  # 咨询类
  operation: 50     # 操作类
  complaint: 40     # 投诉类

cases:
  # 咨询类案例
  - id: "cons_001"
    category: "consultation"
    priority: "high"
    input: "这款手机的电池容量是多少?"
    reference: "这款手机的电池容量为5000mAh,支持快充功能,正常使用可续航2天。"
    criteria:
      - "必须回答电池容量"
      - "可以补充续航信息"
      
  - id: "cons_002"
    category: "consultation"
    priority: "high"
    input: "你们有蓝色的款式吗?"
    reference: "这款产品有蓝色款式,目前库存充足,您可以在商品详情页选择颜色。"
    criteria:
      - "确认是否有该颜色"
      - "提供库存状态"
      
  # 操作类案例
  - id: "oper_001"
    category: "operation"
    priority: "high"
    input: "帮我查询订单12345的状态"
    reference: "订单12345目前状态为已发货,预计明天送达。物流单号:SF12345678。"
    criteria:
      - "返回订单状态"
      - "提供物流信息"
      
  - id: "oper_002"
    category: "operation"
    priority: "high"
    input: "我要申请退货,订单号是12345"
    reference: "好的,我来帮您申请退货。请确认退货原因:1.质量问题 2.不满意 3.其他。确认后将在3天内处理。"
    criteria:
      - "引导退货流程"
      - "询问退货原因"
      - "说明处理时间"
      
  # 投诉类案例
  - id: "comp_001"
    category: "complaint"
    priority: "high"
    input: "你们的产品太差了,用了两天就坏了!"
    reference: "非常抱歉给您带来不好的体验。请您提供具体问题描述,我们会尽快为您处理,可以选择退货或换货。"
    criteria:
      - "表达歉意"
      - "询问具体问题"
      - "提供解决方案"
      
  - id: "comp_002"
    category: "complaint"
    priority: "high"
    input: "物流太慢了,等了一周还没到!"
    reference: "抱歉让您久等了。我来查询物流状态,如果确实异常,可以为您催促或申请补偿。"
    criteria:
      - "表达理解"
      - "主动查询状态"
      - "提供补偿选项"

评估报告生成

# evaluation_system/report_generator.py
class ReportGenerator:
    """
    评估报告生成器
    """
    
    def generate(self, results: List[EvalResult], config: Dict) -> Dict:
        """
        生成完整评估报告
        """
        # 总体统计
        total = len(results)
        passed = sum(1 for r in results if r.passed)
        avg_score = sum(r.overall_score for r in results) / total
        
        # 分类别统计
        category_stats = self._group_by_category(results)
        
        # 失败案例分析
        failed_cases = [r for r in results if not r.passed]
        failure_patterns = self._analyze_failure_patterns(failed_cases)
        
        # 性能统计
        latency_stats = self._compute_latency_stats(results)
        
        return {
            "summary": {
                "total_cases": total,
                "passed": passed,
                "pass_rate": passed / total,
                "avg_score": avg_score,
                "threshold": config["threshold"],
            },
            "category_breakdown": category_stats,
            "failure_analysis": {
                "count": len(failed_cases),
                "patterns": failure_patterns,
                "top_failed": sorted(failed_cases, key=lambda r: r.overall_score)[:5],
            },
            "performance": latency_stats,
            "recommendations": self._generate_recommendations(category_stats, failure_patterns),
            "timestamp": datetime.now(),
        }
    
    def _group_by_category(self, results: List[EvalResult]) -> Dict:
        """按类别统计"""
        from collections import defaultdict
        stats = defaultdict(list)
        
        for r in results:
            # 从 case_id 提取类别
            category = r.case_id.split("_")[0]
            stats[category].append(r)
        
        return {
            cat: {
                "count": len(items),
                "avg_score": sum(i.overall_score for i in items) / len(items),
                "pass_rate": sum(1 for i in items if i.passed) / len(items),
            }
            for cat, items in stats.items()
        }
    
    def _analyze_failure_patterns(self, failed: List[EvalResult]) -> List[Dict]:
        """分析失败模式"""
        patterns = []
        
        for r in failed:
            scores = r.scores
            
            # 识别失败原因
            if scores.get("safety", 1.0) < 1.0:
                patterns.append({
                    "type": "safety_violation",
                    "case_id": r.case_id,
                    "details": scores.get("safety_issues", []),
                })
            elif scores.get("semantic_sim", 1.0) < 0.5:
                patterns.append({
                    "type": "semantic_mismatch",
                    "case_id": r.case_id,
                    "score": scores["semantic_sim"],
                })
            elif scores.get("g_eval", {}).get("overall", 0) < 0.6:
                patterns.append({
                    "type": "quality_low",
                    "case_id": r.case_id,
                    "details": scores["g_eval"],
                })
        
        return patterns

评估报告输出示例

┌─────────────────────────────────────────────────────────────┐
│              Customer Service AI 评估报告                     │
│                    2024-01-15 10:30                          │
├─────────────────────────────────────────────────────────────┤
│  总体概览                                                    │
│  ────────────────────────────────────────────────           │
│  总案例数: 150    通过数: 127    通过率: 85.3%               │
│  平均得分: 0.82   阈值: 0.75                                 │
├─────────────────────────────────────────────────────────────┤
│  分类统计                                                    │
│  ────────────────────────────────────────────────           │
│  │ 类别    │ 案例数 │ 平均得分 │ 通过率 │                   │
│  │ 咨询类  │   60   │   0.85   │ 90.0% │                   │
│  │ 操作类  │   50   │   0.78   │ 80.0% │                   │
│  │ 投诉类  │   40   │   0.79   │ 82.5% │                   │
├─────────────────────────────────────────────────────────────┤
│  失败分析                                                    │
│  ────────────────────────────────────────────────           │
│  失败案例数: 23                                              │
│                                                             │
│  失败模式分布:                                               │
│  │ 模式          │ 数量 │ 占比 │                          │
│  │ 安全违规      │   2  │ 8.7% │                          │
│  │ 语义不匹配    │   8  │ 34.8%│                          │
│  │ 质量评分低    │  13  │ 56.5%│                          │
│                                                             │
│  Top 5 失败案例:                                             │
│  │ comp_003 │ 0.45 │ 投诉类 │ 语气不当           │        │
│  │ oper_015 │ 0.52 │ 操作类 │ 任务未完成         │        │
│  │ cons_022 │ 0.58 │ 咨询类 │ 信息不准确         │        │
├─────────────────────────────────────────────────────────────┤
│  优化建议                                                    │
│  ────────────────────────────────────────────────           │
│  1. 投诉类案例得分偏低,建议优化语气和安抚策略               │
│  2. 操作类存在任务未完成情况,建议优化流程引导               │
│  3. 安全违规案例需重点关注,加强安全约束                     │
└─────────────────────────────────────────────────────────────┘

小结

评估体系设计是 AI Harness 的核心:

组成部分关键要点
指标体系多维组合,匹配场景
数据集Golden Set为核心,多层覆盖
执行流程自动化、可追溯、可对比
人工集成抽样审核,校准评分
实战落地完整代码实现、报告可视化

设计 Checklist

✅ 指标是否覆盖关键质量维度? ✅ Golden Set是否锁定版本? ✅ 执行流程是否自动化可复现? ✅ 结果是否可对比历史版本? ✅ 是否集成人工评估环节? ✅ 是否有完整报告和优化建议?


下一章,我们将深入探讨 AI 测试的具体方法论。