【评测系列2】从零实现 AgentBench评测系统:架构设计与实战

张开发
2026/4/16 18:50:15 15 分钟阅读

分享文章

【评测系列2】从零实现 AgentBench评测系统:架构设计与实战
我自建了一套 agent_bench 评测系统目标按能力维度设计不是任务类型细粒度指标不只是成功/失败可视化报告雷达图 诊断建议可扩展架构随时加新维度结果┌─────────────────────────────────────────────────────────┐ │ AGENT_BENCH 评测系统 │ ├─────────────────────────────────────────────────────────┤ │ 代码量约 9,000 行36 个 Python 文件 │ │ 评测维度5 个 │ │ 评测任务54 个 │ │ 评测器5 个每个维度一个 │ │ 报告生成HTML 可视化 │ │ 自动化率100% │ └─────────────────────────────────────────────────────────┘二、系统架构设计2.1 整体架构图 1AGENT_BENCH 评测系统架构图上图展示了 AGENT_BENCH 的逻辑架构设计包含 6 个核心组件评测基准Benchmarks、评测器Evaluators、报告生成Reports、任务调度、评测环境Environments、待评测 Agent。数据流从 benchmarks → evaluators → reportsenvironments 提供沙箱执行环境。┌─────────────────────────────────────────────────────────┐ │ AGENT_BENCH 架构 │ ├─────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 评测基准 │ │ 评测器 │ │ 报告生成 │ │ │ │ Benchmarks │───▶│ Evaluators │───▶│ Reports │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────┐│ │ │ 评测任务调度 ││ │ │ Task Scheduler ││ │ └─────────────────────────────────────────────────────┘│ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 评测环境 │ │ 待评测 Agent │ │ 指标计算 │ │ │ │ Environments│◀──▶│ Agents │ │ Metrics │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘2.2 目录结构实际项目结构2026 年 4 月实测项目目录结构AGENT_BENCH/ ├── README.md # 系统说明 ├── INSTALLATION_COMPLETE.md # 安装指南 ├── INTEGRATION_GUIDE.md # 集成指南 ├── INTEGRATION_SUMMARY.md # 集成总结 ├── PROJECT_OVERVIEW.md # 项目概览 ├── requirements.txt # Python 依赖 │ ├── benchmarks/ # 评测基准8 个评测集 │ ├── task_planning/ # 任务规划评测集 │ ├── tool_use/ # 工具使用评测集 │ ├── dialogue/ # 多轮对话评测集 │ ├── coding/ # 代码能力评测集 │ ├── knowledge/ # 知识应用评测集 │ ├── nl2sql/ # NL2SQL 评测集 │ ├── llm_as_judge/ # LLM 作为评委 │ └── safety/ # 安全性评测集 │ ├── environments/ # 评测环境 │ ├── sandbox/ # 沙箱环境 │ ├── tools/ # 工具模拟 │ └── scenarios/ # 场景配置 │ ├── agents/ # 待评测 Agent3 个实现 │ ├── openclaw_agent.py # OpenClaw Agent │ ├── langchain_agent.py # LangChain Agent │ └── autogen_agent.py # AutoGen Agent │ ├── evaluators/ # 评测器核心 │ ├── task_planning_evaluator.py # 任务规划评测器 │ ├── tool_use_evaluator.py # 工具使用评测器 │ ├── dialogue_evaluator.py # 多轮对话评测器 │ ├── coding_evaluator.py # 代码能力评测器 │ ├── knowledge_evaluator.py # 知识应用评测器 │ └── metrics.py # 指标计算核心 │ ├── reports/ # 评测报告 │ ├── results/ # 原始结果JSON │ ├── performance/ # 性能测试报告 │ ├── quick_eval/ # 快速评测结果 │ ├── real_eval/ # 真实评测结果 │ └── *.html # 可视化报告 │ ├── scripts/ # 工具脚本19 个 │ ├── run_eval.py # 运行评测 │ ├── generate_report.py # 生成报告 │ ├── run_comparison_eval.py # 对比评测 │ ├── fair_model_comparison.py # 公平对比 │ └── ... │ ├── integrations/ # 第三方集成3 个 │ ├── locust_performance_test.py # 性能测试Locust │ ├── langsmith_tracing.py # 链路追踪LangSmith │ └── garak_security_scan.py # 安全扫描Garak │ ├── configs/ # 配置文件 │ └── eval_config.yaml # 评测配置 │ ├── docs/ # 文档 │ └── ... │ └── test_integrations.py # 集成测试 统计共 12 个一级目录36 个 Python 文件9,148 行代码2.3 核心模块职责模块职责实际代码量文件数benchmarks/定义评测任务题目257 行3 个evaluators/评测逻辑评分2,316 行6 个environments/评测环境沙箱待完善3 个子目录agents/Agent 接口适配369 行3 个reports/报告生成待完善4 个子目录scripts/评测脚本和工具5,641 行19 个integrations/第三方集成~500 行3 个2.4 代码量统计详情实际统计结果2026 年 4 月 16 日实测模块文件数代码行数说明benchmarks/3 个257 行8 个评测集目录核心文件 3 个evaluators/6 个2,316 行5 个评测器 1 个指标计算agents/3 个369 行OpenClaw/LangChain/AutoGenscripts/19 个5,641 行评测脚本和工具integrations/3 个~500 行Locust/LangSmith/Garakenvironments/0 个待完善沙箱/工具/场景目录已创建reports/0 个待完善结果/性能/快速评测目录已创建总计36 个约 9,000 行物理行数含空行和注释说明核心评测逻辑集中在evaluators/模块scripts/包含评测脚本和工具。environments/和reports/目录结构已创建后续会补充实现。三、核心模块实现详解3.1 评测器基类设计所有评测器都继承自一个基类Python - evaluators/base_evaluator.py# evaluators/base_evaluator.py from abc import ABC, abstractmethod from typing import Dict, List, Any from dataclasses import dataclass dataclass class EvalResult: 评测结果数据结构 task_id: str task_name: str difficulty: str score: float details: Dict[str, Any] timestamp: str class BaseEvaluator(ABC): 评测器基类 def __init__(self, config: Dict): self.config config self.results: List[EvalResult] [] abstractmethod def evaluate(self, agent, task: Dict) - EvalResult: 执行评测子类实现 pass abstractmethod def calculate_metrics(self, result: EvalResult) - Dict: 计算指标子类实现 pass def run_batch(self, agent, tasks: List[Dict]) - List[EvalResult]: 批量评测 for task in tasks: result self.evaluate(agent, task) self.results.append(result) return self.results def generate_summary(self) - Dict: 生成汇总统计 if not self.results: return {} return { total_tasks: len(self.results), avg_score: sum(r.score for r in self.results) / len(self.results), by_difficulty: self._group_by_difficulty(), results: [r.__dict__ for r in self.results] } def _group_by_difficulty(self) - Dict: 按难度分组统计 groups {} for result in self.results: diff result.difficulty if diff not in groups: groups[diff] [] groups[diff].append(result.score) return { diff: { count: len(scores), avg_score: sum(scores) / len(scores) } for diff, scores in groups.items() }设计亮点抽象基类强制子类实现核心方法数据类统一结果格式批量评测支持一次评测多个任务汇总统计自动生成统计数据3.2 任务规划评测器实现这是 5 个评测器中最复杂的一个代码实现前 100 行 截图说明任务规划评测器包含分解覆盖率、分解精度、粒度合理性、依赖识别等 4 个核心指标的计算逻辑。核心功能任务拆解解析覆盖率计算精度计算粒度评估依赖关系识别3.3 工具使用评测器实现Python - evaluators/tool_use_evaluator.py# evaluators/tool_use_evaluator.py class ToolUseEvaluator(BaseEvaluator): 工具使用评测器 def evaluate(self, agent, task: Dict) - EvalResult: 评测工具使用能力 # 1. 发送任务 prompt task[prompt] agent_response agent.send(prompt) # 2. 执行工具调用在沙箱中 tool_calls self._parse_tool_calls(agent_response) execution_results [] for call in tool_calls: result self._execute_tool(call, task[environment]) execution_results.append(result) # 3. 计算指标 api_success self._calc_api_success(execution_results) param_accuracy self._calc_param_accuracy(tool_calls, task[expected_params]) efficiency self._calc_efficiency(tool_calls, task[optimal_calls]) # 4. 综合评分 overall_score ( api_success * 0.4 param_accuracy * 0.4 efficiency * 0.2 ) return EvalResult( task_idtask[id], task_nametask[name], difficultytask[difficulty], scoreoverall_score * 5, details{ api_success_rate: api_success, parameter_accuracy: param_accuracy, tool_efficiency: efficiency, tool_calls: tool_calls, execution_results: execution_results }, timestampdatetime.now().isoformat() )核心功能工具调用解析沙箱环境执行API 成功率计算参数准确性验证工具使用效率评估3.4 多轮对话评测器实现Python - evaluators/dialogue_evaluator.py# evaluators/dialogue_evaluator.py class DialogueEvaluator(BaseEvaluator): 多轮对话评测器 def evaluate(self, agent, task: Dict) - EvalResult: 评测多轮对话能力 dialogue_history [] scores [] # 多轮对话 for turn in task[turns]: # 发送用户输入 user_input turn[user_input] agent_response agent.send(user_input, contextdialogue_history) # 评测当前轮 turn_score self._evaluate_turn( agent_response, turn[expected_behavior], dialogue_history ) scores.append(turn_score) # 更新对话历史 dialogue_history.append({ user: user_input, agent: agent_response }) # 计算各项指标 context_retention self._calc_context_retention(dialogue_history) coreference self._calc_coreference_resolution(dialogue_history) intent_recognition sum(scores) / len(scores) # 综合评分 overall_score ( context_retention * 0.3 coreference * 0.3 intent_recognition * 0.4 ) return EvalResult( task_idtask[id], task_nametask[name], difficultytask[difficulty], scoreoverall_score * 5, details{ context_retention: context_retention, coreference_resolution: coreference, intent_recognition: intent_recognition, dialogue_history: dialogue_history, turn_scores: scores }, timestampdatetime.now().isoformat() )核心功能多轮对话管理上下文保持率计算指代消解准确率意图识别准确率3.5 指标计算核心Python - evaluators/metrics.py# evaluators/metrics.py class MetricsCalculator: 指标计算器 staticmethod def normalize_score(raw_score: float, min_val: float, max_val: float) - float: 将原始分数归一化到 1-5 分 if max_val min_val: return 3.0 normalized (raw_score - min_val) / (max_val - min_val) return 1.0 normalized * 4.0 staticmethod def calculate_weighted_average(scores: Dict[str, float], weights: Dict[str, float]) - float: 计算加权平均 total_weight sum(weights.values()) weighted_sum sum(scores[k] * weights[k] for k in scores if k in weights) return weighted_sum / total_weight staticmethod def calculate_confidence_interval(scores: List[float], confidence: float 0.95) - Dict: 计算置信区间 import numpy as np mean np.mean(scores) std np.std(scores) n len(scores) # t 分布临界值简化 t_critical 1.96 if n 30 else 2.0 margin t_critical * std / np.sqrt(n) return { mean: mean, std: std, ci_lower: mean - margin, ci_upper: mean margin, confidence: confidence } staticmethod def generate_radar_data(dimension_scores: Dict[str, float]) - List[Dict]: 生成雷达图数据 labels list(dimension_scores.keys()) values list(dimension_scores.values()) # 闭合雷达图 labels.append(labels[0]) values.append(values[0]) return [ {label: label, value: value} for label, value in zip(labels, values) ]核心功能分数归一化加权平均计算置信区间计算雷达图数据生成四、一键运行评测4.1 命令行使用实际执行命令$ python3 eval_nl2sql.py NL2SQL 评测结果 总用例数30 通过数25 通过率83.33% 按难度统计: Easy: 10/10 (100.00%) Medium: 11/12 (91.67%) Hard: 4/8 (50.00%) 截图说明上图是 NL2SQL 评测的实际执行输出30 道题整体通过率 83.33%Easy 难度 100% 通过Hard 难度仅 50% 通过。4.2 Python API 使用Python - API 调用示例from agents import OpenClawAgent from evaluators import TaskPlanningEvaluator, ToolUseEvaluator from benchmarks import load_benchmark # 1. 初始化 Agent agent OpenClawAgent( modelqwen3.5-plus, api_keyyour-api-key ) # 2. 加载评测基准 tasks load_benchmark(task_planning, difficulty[easy, medium, hard]) # 3. 初始化评测器 evaluator TaskPlanningEvaluator(config{}) # 4. 运行评测 results evaluator.run_batch(agent, tasks) # 5. 获取汇总 summary evaluator.generate_summary() print(f总任务数{summary[total_tasks]}) print(f平均得分{summary[avg_score]:.2f}/5) print(f按难度统计{summary[by_difficulty]})4.3 配置文件YAML - configs/eval_config.yaml# configs/eval_config.yaml agent: type: openclaw_agent model: qwen3.5-plus api_key: ${OPENCLAW_API_KEY} # 从环境变量读取 evaluator: dimensions: - task_planning - tool_use - dialogue - coding - knowledge difficulty: - easy - medium - hard report: format: html include_radar: true include_bar_chart: true include_details: true output_dir: reports/results五、评测报告生成5.1 HTML 报告结构HTML - 报告模板!DOCTYPE html html head titleAgent 评测报告/title script srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script /head body div classcontainer h1Agent 评测报告/h1 !-- 综合得分 -- div classsummary h2综合得分3.47/5 (C 级)/h2 /div !-- 5 维度雷达图 -- div idradar-chart/div !-- 各维度详细得分 -- div classdimensions h3各维度得分/h3 div classdimension span任务规划/span div classbar div classfill stylewidth: 67%/div /div span3.37/5/span /div /div !-- 按难度分级统计 -- div classdifficulty-stats h3按难度统计/h3 table trth难度/thth任务数/thth平均得分/thth通过率/th/tr trtdEasy/tdtd12/tdtd4.05/5/tdtd85%/td/tr trtdMedium/tdtd28/tdtd3.42/5/tdtd65%/td/tr trtdHard/tdtd14/tdtd2.89/5/tdtd45%/td/tr /table /div !-- 改进建议 -- div classrecommendations h3改进建议/h3 ul li工具使用能力待加强2.64/5/li li增强异常处理规划/li li加强长上下文记忆机制/li /ul /div /div /body /html5.2 报告生成脚本Python - scripts/generate_report.py# scripts/generate_report.py import json from pathlib import Path from jinja2 import Template def generate_html_report(results_dir: str, output: str): 生成 HTML 报告 # 1. 加载评测结果 results load_results(results_dir) # 2. 计算汇总数据 summary calculate_summary(results) # 3. 生成雷达图数据 radar_data generate_radar_data(summary[dimension_scores]) # 4. 渲染 HTML 模板 with open(templates/report.html) as f: template Template(f.read()) html template.render( summarysummary, radar_dataradar_data, resultsresults ) # 5. 保存报告 Path(output).write_text(html, encodingutf-8) print(f报告已生成{output})六、技术亮点6.1 可扩展架构插件化设计Python - 添加新维度# 添加新维度只需 3 步 # 1. 创建新的评测器 class NewDimensionEvaluator(BaseEvaluator): def evaluate(self, agent, task): # 实现评测逻辑 pass # 2. 创建评测基准 # benchmarks/new_dimension/ # 3. 更新配置文件 # eval_config.yaml evaluator: dimensions: - task_planning - tool_use - dialogue - coding - knowledge - new_dimension # ← 添加新维度6.2 沙箱环境安全的工具执行Python - environments/sandbox.pyimport docker class SandboxEnvironment: Docker 沙箱环境 def __init__(self): self.client docker.from_client() self.container None def start(self): 启动沙箱容器 self.container self.client.containers.run( python:3.10-slim, commandtail -f /dev/null, detachTrue, network_disabledTrue, # 禁用网络 volumes{ /tmp/sandbox: {bind: /sandbox, mode: rw} } ) def execute_code(self, code: str) - Dict: 在沙箱中执行代码 # 写入代码文件 self.container.exec_run( sh -c cat /sandbox/code.py EOF\n code \nEOF ) # 执行代码 result self.container.exec_run( python /sandbox/code.py, timeout30 # 30 秒超时 ) return { exit_code: result.exit_code, output: result.output.decode(), success: result.exit_code 0 } def stop(self): 停止沙箱 if self.container: self.container.stop() self.container.remove()6.3 自动化评分无需人工干预Python - 自动评分def auto_score(agent_response: str, expected: Dict) - float: 自动评分 # 1. 解析 Agent 输出 parsed parse_response(agent_response) # 2. 对比标准答案 if expected[type] exact_match: score 1.0 if parsed expected[value] else 0.0 elif expected[type] fuzzy_match: score calculate_similarity(parsed, expected[value]) elif expected[type] rubric_based: score score_by_rubric(parsed, expected[rubric]) # 3. 返回分数 return score七、总结7.1 核心成果完成的工作✅ 5 个评测器✅ 54 个评测任务✅ 自动化评测流程✅ HTML 可视化报告✅ 沙箱环境✅ 插件化架构技术亮点可扩展架构随时加新维度细粒度指标不只是成功/失败自动化评分无需人工干预沙箱隔离安全执行7.2 下一步计划短期1-2 周增加性能评测模块支持多 Agent 对比你对 Agent 评测系统有什么想法A. 架构设计很合理想试试B. 有些功能我们也在做可以交流C. 有不懂的地方想请教D. 想参与开源贡献下篇预告评测相关、Hermes 系列、crewAI 系列都有可能因为我要求自己一定要真实实战所以哪个先有效果就先分享哪篇作者测试员周周14 年测试经验专注 AI 测试实

更多文章