当前位置: 首页 > news >正文

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

我自建了一套 agent_bench 评测系统

目标

  1. 按"能力维度"设计(不是任务类型)
  2. 细粒度指标(不只是成功/失败)
  3. 可视化报告(雷达图 + 诊断建议)
  4. 可扩展架构(随时加新维度)

结果

┌─────────────────────────────────────────────────────────┐ │ AGENT_BENCH 评测系统 │ ├─────────────────────────────────────────────────────────┤ │ 代码量:约 9,000 行(36 个 Python 文件) │ │ 评测维度:5 个 │ │ 评测任务:54 个 │ │ 评测器:5 个(每个维度一个) │ │ 报告生成:HTML 可视化 │ │ 自动化率:100% │ └─────────────────────────────────────────────────────────┘

二、系统架构设计

2.1 整体架构

图 1:AGENT_BENCH 评测系统架构图

上图展示了 AGENT_BENCH 的逻辑架构设计,包含 6 个核心组件:

评测基准(Benchmarks)、评测器(Evaluators)、报告生成(Reports)、任务调度、评测环境(Environments)、待评测 Agent。数据流从 benchmarks → evaluators → reports,environments 提供沙箱执行环境。

┌─────────────────────────────────────────────────────────┐ │ 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/ # 待评测 Agent(3 个实现) │ ├── 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/AutoGen
scripts/19 个5,641 行评测脚本和工具
integrations/3 个~500 行Locust/LangSmith/Garak
environments/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() }

设计亮点

  1. 抽象基类:强制子类实现核心方法
  2. 数据类:统一结果格式
  3. 批量评测:支持一次评测多个任务
  4. 汇总统计:自动生成统计数据

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_id=task["id"], task_name=task["name"], difficulty=task["difficulty"], score=overall_score * 5, details={ "api_success_rate": api_success, "parameter_accuracy": param_accuracy, "tool_efficiency": efficiency, "tool_calls": tool_calls, "execution_results": execution_results }, timestamp=datetime.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, context=dialogue_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_id=task["id"], task_name=task["name"], difficulty=task["difficulty"], score=overall_score * 5, details={ "context_retention": context_retention, "coreference_resolution": coreference, "intent_recognition": intent_recognition, "dialogue_history": dialogue_history, "turn_scores": scores }, timestamp=datetime.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( model="qwen3.5-plus", api_key="your-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> <title>Agent 评测报告</title> <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> </head> <body> <div class="container"> <h1>Agent 评测报告</h1> <!-- 综合得分 --> <div class="summary"> <h2>综合得分:3.47/5 (C 级)</h2> </div> <!-- 5 维度雷达图 --> <div id="radar-chart"></div> <!-- 各维度详细得分 --> <div class="dimensions"> <h3>各维度得分</h3> <div class="dimension"> <span>任务规划</span> <div class="bar"> <div class="fill" style="width: 67%"></div> </div> <span>3.37/5</span> </div> </div> <!-- 按难度分级统计 --> <div class="difficulty-stats"> <h3>按难度统计</h3> <table> <tr><th>难度</th><th>任务数</th><th>平均得分</th><th>通过率</th></tr> <tr><td>Easy</td><td>12</td><td>4.05/5</td><td>85%</td></tr> <tr><td>Medium</td><td>28</td><td>3.42/5</td><td>65%</td></tr> <tr><td>Hard</td><td>14</td><td>2.89/5</td><td>45%</td></tr> </table> </div> <!-- 改进建议 --> <div class="recommendations"> <h3>改进建议</h3> <ul> <li>工具使用能力待加强(2.64/5)</li> <li>增强异常处理规划</li> <li>加强长上下文记忆机制</li> </ul> </div> </div> </body> </html>

5.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( summary=summary, radar_data=radar_data, results=results ) # 5. 保存报告 Path(output).write_text(html, encoding="utf-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.py

import 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", command="tail -f /dev/null", detach=True, network_disabled=True, # 禁用网络 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", timeout=30 # 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 周)

  1. 增加性能评测模块
  2. 支持多 Agent 对比

你对 Agent 评测系统有什么想法?

A. 架构设计很合理,想试试
B. 有些功能我们也在做,可以交流
C. 有不懂的地方,想请教
D. 想参与开源贡献

下篇预告:评测相关、Hermes 系列、crewAI 系列都有可能,因为我要求自己一定要真实实战,所以哪个先有效果就先分享哪篇;

作者:测试员周周,14 年测试经验,专注 AI+ 测试实

http://www.jsqmd.com/news/651479/

相关文章:

  • 轻量化ASR生态整合:SenseVoice-Small ONNX与Obsidian插件联动教程
  • 【STM32实战指南】SPI与8080双模式驱动OLED显示技术解析
  • LVDS技术在汽车视频传输中的应用与优化
  • 告别命令行恐惧:用Windows Terminal和VS Code图形化搞定Rust环境与第一个项目
  • 如何在Apple Silicon Mac上专业运行iOS游戏:PlayCover终极配置指南
  • HC-06蓝牙模块主从模式实战:从AT指令到双向通信
  • Elasticsearch安全认证实战:从零配置密码与Kibana集成
  • 中东电商入局指南:Noon vs Amazon,出海卖家该如何选择?
  • 朱雀AI检测率高怎么降?比话降AI图文教程:从56%降到0%
  • Windows 11终极优化指南:免费工具让系统运行速度提升51%
  • 手把手教你用MLU370-M8单卡跑通Wav2Lip口播模型(附中文优化思路)
  • 抖音小程序通用支付避坑指南:前端开发者如何用云开发搞定RSA签名难题
  • 快速上手:DCMTK工具包的安装与配置指南
  • 深入解析Nginx启动报错:libcrypto.so.1.1缺失的根源与系统级修复
  • 终极DLSS文件管理方案:5分钟搞定多平台游戏DLSS版本切换
  • 你的无刷电机为啥启动就抖?可能是电感法位置检测没调好(避坑指南)
  • Ubuntu 22.04 LTS 上快速部署Ollama的完整指南(含模型下载与WebUI配置)
  • torch-npu安装指南:从版本匹配到依赖解决
  • 如何让经典《植物大战僵尸》完美适配现代宽屏显示器?PvZWidescreen模组终极指南
  • UniCloud H5项目绑定阿里云域名全流程(含SSL证书踩坑实录)
  • Dism++:Windows系统维护的终极工具,如何用10个技巧提升电脑性能?
  • 神器dnSpy,无需源码也能修改 .NET 程序
  • 突破百度网盘下载限速的技术方案:baidu-wangpan-parse深度解析
  • java面试必问11:Spring Bean 生命周期:从实例化到销毁,一篇讲透
  • 终极指南:如何使用Universal x86 Tuning Utility彻底解决笔记本高温降频问题
  • CurXecute漏洞:AI代码编辑器Cursor的远程代码执行风险
  • 避开这些坑!网易云音乐开源API使用中的5个常见问题及解决方案
  • 睿港国际移民获瓦努阿图官方全方位授权,DSP护照与绿卡授权实力再获认可 - 资讯焦点
  • 写论文这件事,本质上是把“思维碎片”变成“知识成品”的过程。有的人工具顺、效率高
  • 用Cooledit Pro给全志T113-S3音频调试当‘耳朵’:手把手教你量化解决录音尖锐失真