揭开 AI Agent 评估的神秘面纱

揭开 AI Agent 评估的神秘面纱

来源: Anthropic Engineering Blog
作者: Anthropic Engineering Team
发布日期: 2026 年 1 月 8 日
类型: 技术指南
阅读时间: 约 14 分钟

概述

本文全面解析 AI Agent 评估方法,包括评估指标设计、测试用例构建、评估流程实施和结果解读。我们分享了 Anthropic 内部使用的评估框架,涵盖了从单元测试到端到端评估的多层次评估策略,以及如何设计可靠、可重复、有意义的评估体系。


为什么评估很重要

评估的目的

能力评估

  • Agent 能完成什么任务?
  • 任务完成的质量如何?
  • 在什么条件下会失败?

性能评估

  • 任务执行速度如何?
  • 资源消耗是多少?
  • 并发能力如何?

可靠性评估

  • 失败率是多少?
  • 错误类型有哪些?
  • 恢复能力如何?

评估的挑战

挑战 描述 解决方案
主观性 质量评估难以量化 使用多评审者、明确标准
变异性 相同输入不同输出 多次运行取平均
复杂性 任务涉及多步骤 分层评估
成本 评估耗时耗力 自动化评估

评估指标设计

核心指标

任务完成率 (Task Completion Rate)

1
2
3
4
def calculate_completion_rate(tasks, results):
"""计算任务完成率"""
completed = sum(1 for r in results if r.success)
return completed / len(tasks) * 100

执行质量分数 (Quality Score)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def calculate_quality_score(result: TaskResult) -> float:
"""计算质量分数 (0-100)"""
weights = {
'correctness': 0.4, # 正确性
'efficiency': 0.2, # 效率
'completeness': 0.2, # 完整性
'safety': 0.2 # 安全性
}

score = (
result.correctness_score * weights['correctness'] +
result.efficiency_score * weights['efficiency'] +
result.completeness_score * weights['completeness'] +
result.safety_score * weights['safety']
)
return score * 100

执行时间 (Execution Time)

  • P50: 中位数执行时间
  • P95: 95% 的执行时间低于此值
  • P99: 99% 的执行时间低于此值

Token 效率 (Token Efficiency)

1
2
3
4
5
6
7
def calculate_token_efficiency(result: TaskResult) -> float:
"""计算 Token 使用效率"""
expected_tokens = estimate_expected_tokens(result.task)
actual_tokens = result.tokens_used

# 效率 = 预期 / 实际 (越高越好,上限 1.0)
return min(expected_tokens / actual_tokens, 1.0)

复合指标

Agent 能力指数 (Agent Capability Index)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def calculate_agent_capability_index(results: list[TaskResult]) -> float:
"""计算 Agent 能力指数 (0-100)"""
metrics = {
'completion_rate': calculate_completion_rate(results),
'avg_quality': np.mean([r.quality_score for r in results]),
'token_efficiency': np.mean([r.token_efficiency for r in results]),
'safety_score': np.mean([r.safety_score for r in results])
}

# 加权平均
weights = {
'completion_rate': 0.35,
'avg_quality': 0.35,
'token_efficiency': 0.15,
'safety_score': 0.15
}

index = sum(metrics[k] * weights[k] for k in metrics)
return index

测试用例设计

测试分类

按难度分级

1
2
3
4
5
class TaskDifficulty(Enum):
BASIC = "基础" # 简单、直接的任务
INTERMEDIATE = "中等" # 需要多步骤
ADVANCED = "高级" # 复杂、需要推理
EXPERT = "专家" # 需要专业知识和创造性

按领域分类

1
2
3
4
5
6
class TaskDomain(Enum):
CODING = "编程"
WRITING = "写作"
ANALYSIS = "分析"
RESEARCH = "研究"
CUSTOMER_SERVICE = "客服"

测试用例模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
@dataclass
class EvalTestCase:
"""评估测试用例"""

# 基本信息
id: str
name: str
description: str

# 分类
difficulty: TaskDifficulty
domain: TaskDomain

# 测试内容
input: str
expected_output: Optional[str]
evaluation_criteria: list[str]

# 评分标准
rubric: dict

# 元数据
tags: list[str]
created_at: datetime
version: str

# 示例测试用例
test_case = EvalTestCase(
id="coding-001",
name="实现快速排序",
description="实现一个快速排序算法,处理各种输入情况",
difficulty=TaskDifficulty.INTERMEDIATE,
domain=TaskDomain.CODING,

input="""
请实现一个快速排序函数,要求:
1. 支持整数列表排序
2. 处理空列表和单元素列表
3. 处理重复元素
4. 添加类型注解
""",

expected_output=None, # 开放式任务

evaluation_criteria=[
"正确性:排序结果正确",
"完整性:处理所有边界情况",
"代码质量:清晰的命名和结构",
"类型注解:完整的类型提示"
],

rubric={
'correctness': {'weight': 0.4, 'threshold': 0.8},
'completeness': {'weight': 0.2, 'threshold': 0.7},
'code_quality': {'weight': 0.2, 'threshold': 0.7},
'type_annotations': {'weight': 0.2, 'threshold': 0.9}
},

tags=["sorting", "algorithm", "python"],
created_at=datetime(2026, 1, 1),
version="1.0"
)

测试数据集构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class EvalDatasetBuilder:
"""评估数据集构建器"""

def __init__(self):
self.test_cases = []

def add_from_file(self, file_path: str) -> 'EvalDatasetBuilder':
"""从文件添加测试用例"""
with open(file_path) as f:
cases = json.load(f)
for case in cases:
self.test_cases.append(EvalTestCase(**case))
return self

def add_synthetic(self, generator: TestCaseGenerator, count: int) -> 'EvalDatasetBuilder':
"""添加合成的测试用例"""
for _ in range(count):
case = generator.generate()
self.test_cases.append(case)
return self

def balance(self) -> 'EvalDatasetBuilder':
"""平衡测试集分布"""
# 按难度平衡
self._balance_by_field('difficulty')
# 按领域平衡
self._balance_by_field('domain')
return self

def build(self) -> EvalDataset:
"""构建最终数据集"""
return EvalDataset(self.test_cases)

评估流程

评估执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class EvalRunner:
"""评估执行器"""

def __init__(self, agent: Agent, dataset: EvalDataset):
self.agent = agent
self.dataset = dataset
self.results = []

async def run(self) -> EvalResults:
"""运行评估"""
for test_case in self.dataset.test_cases:
result = await self._run_test_case(test_case)
self.results.append(result)

return EvalResults(self.results)

async def _run_test_case(self, test_case: EvalTestCase) -> TestCaseResult:
"""运行单个测试用例"""
start_time = time.time()

try:
# 执行任务
response = await self.agent.run(test_case.input)

# 评估结果
evaluation = await self._evaluate_response(
response, test_case.expected_output, test_case.rubric
)

return TestCaseResult(
test_case_id=test_case.id,
success=evaluation.passed,
quality_score=evaluation.score,
execution_time=time.time() - start_time,
tokens_used=response.tokens_used,
details=evaluation.details
)

except Exception as e:
return TestCaseResult(
test_case_id=test_case.id,
success=False,
error=str(e),
execution_time=time.time() - start_time
)

结果评估

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class ResponseEvaluator:
"""响应评估器"""

def __init__(self, llm_judge: Optional[LLM] = None):
self.llm_judge = llm_judge or load_judge_model()

async def evaluate(
self,
response: str,
expected: Optional[str],
rubric: dict
) -> EvaluationResult:

scores = {}

# 对于有标准答案的任务
if expected:
scores['correctness'] = self._exact_match_score(response, expected)

# 对于开放式任务,使用 LLM 评估
for criterion in rubric:
if criterion not in scores:
score = await self._llm_evaluate(
response, criterion, rubric[criterion]
)
scores[criterion] = score

# 计算加权总分
weighted_score = sum(
scores[k] * rubric[k]['weight']
for k in scores
)

return EvaluationResult(
scores=scores,
overall_score=weighted_score,
passed=weighted_score >= 0.7
)

结果解读

统计分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class EvalAnalyzer:
"""评估结果分析器"""

def __init__(self, results: EvalResults):
self.results = results

def summary_stats(self) -> dict:
"""汇总统计"""
return {
'total_tests': len(self.results),
'pass_rate': self.results.pass_rate(),
'avg_quality': np.mean([r.quality_score for r in self.results]),
'avg_execution_time': np.mean([r.execution_time for r in self.results]),
'p95_execution_time': np.percentile([r.execution_time for r in self.results], 95),
'avg_tokens': np.mean([r.tokens_used for r in self.results])
}

def breakdown_by_difficulty(self) -> dict:
"""按难度分解"""
breakdown = defaultdict(list)
for result in self.results:
difficulty = result.test_case.difficulty
breakdown[difficulty].append(result.quality_score)

return {
k: {
'count': len(v),
'avg_score': np.mean(v),
'std_dev': np.std(v)
}
for k, v in breakdown.items()
}

def failure_analysis(self) -> dict:
"""失败分析"""
failures = [r for r in self.results if not r.success]

return {
'total_failures': len(failures),
'failure_rate': len(failures) / len(self.results),
'common_errors': self._cluster_errors(failures),
'patterns': self._identify_failure_patterns(failures)
}

可视化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def create_eval_dashboard(results: EvalResults):
"""创建评估结果仪表板"""
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

# 1. 通过率分布
axes[0, 0].pie(
[results.pass_count(), results.fail_count()],
labels=['通过', '失败'],
autopct='%1.1f%%'
)
axes[0, 0].set_title('通过率')

# 2. 质量分数分布
axes[0, 1].hist(
[r.quality_score for r in results],
bins=20,
edgecolor='black'
)
axes[0, 1].set_title('质量分数分布')
axes[0, 1].set_xlabel('分数')
axes[0, 1].set_ylabel('数量')

# 3. 执行时间分布
axes[1, 0].boxplot([r.execution_time for r in results])
axes[1, 0].set_title('执行时间分布')
axes[1, 0].set_ylabel('秒')

# 4. 按领域性能
by_domain = defaultdict(list)
for r in results:
by_domain[r.test_case.domain].append(r.quality_score)

domains = list(by_domain.keys())
scores = [np.mean(by_domain[d]) for d in domains]
axes[1, 1].bar(domains, scores)
axes[1, 1].set_title('按领域性能')
axes[1, 1].tick_params(axis='x', rotation=45)

plt.tight_layout()
return fig

最佳实践

1. 评估设计

  • 多层次评估:单元测试、集成测试、端到端测试
  • 多样化测试集:覆盖不同难度、领域、场景
  • 明确的评估标准:避免主观判断

2. 执行实践

  • 多次运行:减少随机性影响
  • 盲评:避免评估者偏见
  • 自动化:减少人工成本

3. 结果使用

  • 趋势分析:关注改进而非绝对值
  • 根因分析:深入分析失败原因
  • 持续改进:基于结果优化 Agent

关键要点总结

  1. 明确评估目的:能力、性能、可靠性
  2. 设计合理指标:完成率、质量分数、效率
  3. 构建多样化测试集:覆盖不同场景
  4. 自动化评估流程:减少人工成本
  5. 深入结果分析:趋势、根因、改进

个人评价

评估是 AI Agent 开发的核心环节:

优点

  1. 数据驱动:基于客观数据而非直觉
  2. 持续改进:通过评估发现改进点
  3. 质量保证:确保 Agent 达到预期标准

总体评价

建立科学的评估体系是构建高质量 AI Agent 的基础。本文提供的方法已在 Anthropic 内部得到验证,可供其他团队参考。


本文内容翻译自 Anthropic Engineering Blog 官方博客。

© 2026 Generative AI Discovery All Rights Reserved.
Theme by hiero