第三章:评估体系设计
本章系统性地讲解如何设计 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, Prometheus | LLM输出 | 模型作为裁判 |
| 任务完成 | Task Success Rate | Agent系统 | 功能验证 |
| 用户体验 | 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 | 端到端验证 |
指标组合策略
单一指标不足以反映真实质量,需要组合:
组合示例:客服 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 = 精选的高质量代表案例集
- 数量: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 Set | 100-500 | 基线评估 | 人工精选标注 |
| Boundary Set | 50-100 | 边界测试 | 专家设计极端案例 |
| Adversarial Set | 30-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
结果分析与报告
评估结果应包含:
| 内容 | 说明 | 用途 |
|---|---|---|
| 总体得分 | 综合质量分数 | 基线对比 |
| 分项得分 | 各指标得分 | 问题定位 |
| 案例详情 | 每个案例结果 | 深入分析 |
| 失败案例 | 未达标案例列表 | 优化重点 |
| 分布统计 | 得分分布、置信区间 | 稳定性分析 |
| 版本对比 | 与历史版本对比 | 回归评估 |
人工评估集成
为什么需要人工评估
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为核心,多层覆盖 |
| 执行流程 | 自动化、可追溯、可对比 |
| 人工集成 | 抽样审核,校准评分 |
| 实战落地 | 完整代码实现、报告可视化 |
✅ 指标是否覆盖关键质量维度? ✅ Golden Set是否锁定版本? ✅ 执行流程是否自动化可复现? ✅ 结果是否可对比历史版本? ✅ 是否集成人工评估环节? ✅ 是否有完整报告和优化建议?
下一章,我们将深入探讨 AI 测试的具体方法论。