人工智能

UAEF:一个与框架无关的 AI 智能体闭环评测系统

在 AWS 上构建 AI 智能体的团队会使用多种框架,包括 LangGraph、LangChain、Strands Agents 和 Amazon Bedrock AgentCore。每个框架都以自己的方式记录智能体的执行过程,因此消息、工具调用以及智能体之间交接的结构各不相同。评测工具往往也遵循同样的边界:团队针对单一框架的轨迹格式构建指标、评分逻辑和结果存储,而当他们切换框架或在多个框架上运行智能体时,就必须重新构建这些内容。

这种耦合使得一个基本的开发问题更难回答:对提示词、模型或工具的改动是否改善了智能体?要回答这个问题,需要在智能体的各个版本之间保持一致的指标,并有一份共享的历史结果记录可供比较。智能体质量还涵盖单一准确率分数无法捕捉的多个维度:工具调用、响应质量、负责任 AI、性能、多轮对话、多智能体协作和推理。

在本文中,我们介绍通用智能体评测框架(UAEF)。来自电信、医疗和金融服务行业 12 家机构的客户使用 UAEF,以一套一致的指标评测其 AI 智能体,并在发布前比较智能体版本。UAEF 是一个与框架无关的评测系统:它使用适配器将各框架的轨迹转换为统一格式,然后用 7 个维度下的 36 项内置指标对这些轨迹打分。它将结果存储在 Amazon DynamoDB 和 Amazon Simple Storage Service(Amazon S3)中,并生成报告和洞察,为智能体的下一轮迭代提供依据。本文介绍 UAEF 的工作原理,提供选择指标和准备数据集的实操指南,并给出每个受支持框架的可运行 notebook。

UAEF:面向智能体框架的统一评测层

UAEF 是一个与框架无关的 AI 智能体评测系统。它接收团队已有的智能体,并在受支持的框架和运行时上以相同方式对其打分。UAEF 接收两个输入:被测智能体和用于运行它的数据集。数据集为每个测试用例提供输入,还可以包含标准答案,即每个输入的预期输出。标准答案是可选的,只有将智能体响应与参考结果进行比较的指标才会用到它。要评测工具调用,标准答案还必须包含每个测试用例的预期工具调用:智能体应调用哪些工具、以什么顺序调用以及使用什么参数。此后的一切都在 UAEF 内部完成。

图 1 展示了单次评测的路径,从输入到报告和洞察。首先,适配器读取智能体的原生执行记录,包括其消息、工具调用和智能体之间的交接,并将其规范化为一个统一的轨迹,从而使后续步骤无论智能体由哪个框架生成都完全相同。接下来,UAEF 在存储数据之前筛查轨迹中的个人身份信息(PII),例如电子邮件地址、电话号码和信用卡号。然后,评测引擎从 7 个质量维度下的 36 项内置指标中选择一部分,对轨迹打分。当你持久化一次运行时,UAEF 会将其作为实验记录在 Amazon DynamoDB 和 Amazon S3 中:Amazon DynamoDB 保存用于列出和比较的每次实验元数据,Amazon S3 保存完整结果。运行结果存储后,团队可以将智能体版本与基线进行比较,以检测回归,并生成报告和洞察,解释发生了什么变化以及原因。这些报告闭合了循环:团队评测智能体,了解哪些方面出现回归或改进,修改提示词、模型或工具,然后再次评测。

Closed-loop data flow: an adapter normalizes a framework trace, the engine scores it, UAEF stores the results, and reports feed the next iteration

图 1:UAEF 闭环评测数据流

本节其余部分按该流程依次展开:使 UAEF 与框架无关的适配器、评测引擎及其指标、PII 检测、实验存储与比较,以及闭合循环的报告。

统一轨迹与适配器

适配器是 UAEF 与框架无关的关键。适配器读取智能体运行的记录,包括其消息、工具调用和智能体之间的交接。它将该记录转换为一种称为 AgentTrace的统一表示,这是 UAEF 其余部分唯一打分的内容。由于这一转换,UAEF 可以与智能体配合工作,无论它是用哪个 SDK 构建的(例如 LangGraph、LangChain 或 Strands Agents)。它可以在本地运行、位于 HTTP 端点之后,或运行在 Amazon Bedrock AgentCore 等托管运行时上,轨迹可以存放在 Langfuse 中,也可以完全不捕获。UAEF 为上述每种情况提供适配器,它们产生相同的 AgentTrace,因此指标、分数和比较在所有这些情况下都保持一致。

轨迹通过两种方式到达 UAEF。如果轨迹已经存在,来自过去的运行、日志或可观测性存储,则将其交给 UAEF,由匹配的适配器进行规范化。如果不存在,UAEF 会替你调用智能体:给定运行时 Amazon Resource Name(ARN)或 HTTP 端点,它针对每个数据集输入调用智能体,收集响应,并一步完成适配。无论哪种方式,输出都是相同的 AgentTrace.

由于每个指标、模式和报告都作用于 AgentTrace 而非框架原生格式,因此无论轨迹来自何处,后续打分都完全相同。这种分离,即先规范化再打分,使团队能够在同一尺度上比较基于一个框架构建的智能体与基于另一个框架构建的智能体。

评测引擎

评测引擎会从7个质量维度对一条规范轨迹进行打分,每个维度都捕捉智能体行为的一个独特方面,而单一的准确率数字会掩盖这些方面。工具调用衡量智能体是否选择了正确的工具、是否以合理的顺序调用它们,以及是否传入了有效的参数。响应质量衡量最终答案是否相关、完整、准确,并且基于所提供的上下文而非凭空捏造。

负责任AI衡量安全性、偏见、毒性以及抵御提示注入的能力。性能衡量延迟、token使用量和吞吐量方面的运营成本。多轮衡量智能体维持对话的能力,包括上下文保持、连贯性以及跨轮次的目标完成情况。多智能体衡量协作智能体系统中的协调能力,例如任务委派和分工。推理衡量智能体思维链的内部逻辑,包括一致性和无谬误性。

每个维度由一个或多个内置指标计算得出,共36个内置指标,每个指标返回区间[0, 1]内的归一化分数,其中1为最佳,因此各维度和总体结果共享同一尺度。指标分为两类。确定性指标直接从轨迹和标准答案计算分数,并在重复运行时精确复现。大语言模型(LLM)作为评判者的指标通过在Amazon Bedrock上提示评判模型,对难以用闭式定义描述的质量(如响应相关性或安全性)进行打分。你还可以添加自己的自定义指标,或利用RAGAS和DeepEval集成。

由于评判指标会将智能体自身的输出反馈到提示中,该内容被视为不可信输入:能够影响其评判者的智能体就能影响自己的分数。评分标准与内容分开发送,并且内容会被转义,使其无法突破分隔符而被当作指令读取。每个评判响应都会被严格解析,并且必须引用其所评分内容中的逐字片段。如果找不到证据,该分数会被拒绝而非记录。评判分数是评测信号,而非安全决策,不应作为安全控制的闸门。要对智能体本身进行运行时强制执行,请在其自身的调用路径中应用Amazon Bedrock Guardrails。完整模型见SECURITY.md。

实验管理与比较

UAEF将每次评测记录为一个实验,以便日后比较不同智能体版本的结果。调用 evaluate() 或 batch_evaluate() 并传入 persist=True 会创建一个新实验,由可选名称和目标标识,并将其写入两个角色互补的存储。Amazon DynamoDB为每个实验保存一行,包含用于列出和比较的元数据:评测次数、每个指标的平均分数以及总体平均值。Amazon S3保存一个JSON文件,包含完整的评测结果,包括每个指标的分数和评判者的推理。处理敏感数据的团队可以为存储副本开启PII脱敏。

Python库还对更细粒度的结构进行建模。一个实验包含多次运行,每次运行记录被测的智能体设计:框架、模型、工具、系统提示和参数。一次运行还可以记录配置快照和Git提交。你可以将一次运行标记为其所在实验的基线。这将每个分数与产生它的变更(无论是新提示、不同模型还是新增工具)关联起来。

比较基于存储的每个指标平均值进行。对于两次运行共有的每个指标,比较引擎会计算绝对变化和百分比变化。然后使用可配置阈值(默认5%)将该指标分类为回归、改进或不变。一次调用中可以将多次运行与单个基线进行比较。回归检测器还会为每个回归分配严重程度:轻微(5–10%)、中等(10–20%)或严重(超过20%)。它按维度对回归进行分组,例如可以显示提示变更是否影响了工具调用但未影响响应质量。

在Web UI中,Compare选项卡列出已存储的实验,并按框架或数据集进行筛选。你选择两个或更多实验。第一个用作基线,UI显示每个指标的分数,并高亮回归和改进。UI调用相同的库比较引擎,因此结果与Python API返回的结果一致。

报告与洞察生成

评测存储后,UAEF从三个层面对其进行报告,每个层面回答不同的问题。这次运行表现如何?为什么得到这样的分数?与早期版本相比如何?

结果视图。 评测完成后,Web UI显示实验摘要:总体分数、已评测的测试用例数、框架以及未能运行的查询。每个指标的平均值以维度雷达图和指标条形图呈现。表格列出每个测试用例及其查询、智能体响应、预期答案和分数。展开一行会显示完整响应及其维度和指标分数。对于多轮对话,它会显示每一轮及其各自的分数和智能体调用的工具。

详细报告。 从结果视图或实验列表中,你可以按需生成统计报告。UAEF从Amazon S3加载存储的结果,并在新的浏览器选项卡中打开报告。报告按维度和指标细分结果。它显示每个指标的置信区间和离群值、分数分布、指标之间的相关性、负责任AI摘要以及报告失败的测试用例。最后给出建议,指出得分最低的维度和在测试用例间变化最大的指标。报告仅根据分数计算,不使用LLM,因此相同结果会产生相同报告。

LLM生成的洞察。 在Python库中,你可以将报告传给Amazon Bedrock上的模型进行分析。对于单次运行,分析涵盖优势、关键弱点、关于根本原因的假设以及按优先级排序的建议。对于多次运行的比较,分析涵盖总体趋势、回归和改进的可能原因、每个回归所携带的风险以及后续步骤。这些洞察会提示在下次评估前应更改提示、模型或工具中的哪些内容。

两种使用方式

你可以在同一引擎上以两种方式运行UAEF。使用Python库,你可以在笔记本、脚本以及持续集成和持续交付(CI/CD)流水线中以代码方式评估智能体。你可以使用可部署的AWS服务,通过低代码Web界面评估智能体。你上传数据集、选择框架和指标、运行评估并查看分数。两条路径运行相同的评估引擎并写入相同的存储,因此结果不取决于由哪条路径产生。你可以从界面开始,然后转到代码,而无需改变结果的评分或比较方式。

使用UAEF评估智能体:操作指南

了解UAEF能测量什么,与了解你应该测量什么,是两回事。旅行预订智能体和政策问答智能体以不同方式失败,在所有维度上对两者打分既浪费时间又浪费Amazon Bedrock调用。使用本操作指南选择与你的智能体匹配的指标,然后随着新问题的出现再添加更多指标。

入门

UAEF是开源软件,采用 Apache 2.0许可证 中 awslabs/uaef GitHub 仓库。其中包含 Python 库、框架适配器、内置指标、用于可部署服务的 AWS 云开发工具包(AWS CDK)基础设施、Web 界面,以及针对每个受支持框架的可运行笔记本。 安装指南 涵盖需求、从构建好的软件包安装以及开发环境搭建。

以下指标与你的智能体匹配,然后随着新问题的出现再添加更多指标。入门UAEF 是开源软件,采用 Apache 2.0 许可证,托管于 awslabs/uaef GitHub 仓库。其中包含 Python 库、框架适配器、内置指标、用于可部署服务的 AWS 云开发工具包(AWS CDK)基础设施、Web 界面,以及针对每个受支持框架的可运行笔记本。安装指南涵盖需求、从构建好的软件包安装以及开发环境搭建。 服务部署指南 涵盖将 UAEF 作为服务部署(含 Web 界面)、配置参考以及拆除。

查看实际效果

在 UAEF Web 界面中完成一次完整评测,从上传真实答案到获得各维度分数。

选择指标

从你的场景出发,而不是从指标列表出发。找到与你的智能体匹配的那一列,并从该列中勾选的指标开始。 需要真实答案 列显示哪些指标会与参考答案或预期工具调用进行对比。

维度 指标 需要真实答案 场景
RAG / 知识问答 常规问答 工具调用智能体 多轮对话 推理 安全与合规 多智能体 生产监控
响应质量 答案相关性 ✓ ✓ ✓
准确率 ✓ ✓ ✓
完整性 ✓ ✓ ✓
幻觉分数 ✓
ragas_faithfulness ✓
ragas_context_precision ✓ ✓
ragas_context_recall ✓ ✓
工具调用 工具选择准确率 ✓ ✓ ✓
工具序列正确性 ✓ ✓ ✓
参数质量 ✓ ✓
mcp_compliance ✓
多轮 上下文保留 ✓
连贯性 ✓ ✓
conversation_completeness ✓ ✓
用户满意度 ✓
轮次效率 ✓
推理 连贯性 ✓
逻辑一致性 ✓
推理步骤正确性 ✓
谬误检测 ✓
负责任的人工智能 安全评分 ✓ ✓ ✓
毒性评分 ✓
bias_score ✓
提示注入检测 ✓
多智能体 工作流完成度 ✓ ✓
委派质量 ✓
agent_utilization ✓
协调效率 ✓
性能 延迟评分 ✓
token_efficiency ✓
成本效益 ✓
吞吐量 ✓

下表显示了针对每种场景推荐的起始指标。有关支持指标的完整列表,请参阅 指标目录.

将你选定的指标作为 metrics 参数传给 evaluate() 或 batch_evaluate()完整示例请参阅随后的“示例笔记本”部分。工具调用和性能等确定性指标直接从轨迹计算得出,而其他指标则调用 LLM 评判器。当不存在真实答案时,UAEF 会自动跳过需要参考答案的指标,因此部分标注的数据集和未标注的生产流量仍然值得评测。

选择流水线

指标决定你衡量什么。六个独立的选择决定评测如何运行。用每一行中的问题来确定它。

选择 问问自己 然后使用 在代码中
被动或主动 我是已经有轨迹了,还是需要在受控条件下生成轨迹? 被动: 评测一条你已经拥有的轨迹。 主动: 调用一个 invoke_* 辅助函数,让 UAEF 运行该智能体。

evaluate(trace=recorded,

adapter=“langgraph”)

或

raw = invoke_http_agent_for_framework(

端点、查询、“strands”)

一条轨迹或一个数据集 我是在调试单个案例,还是在衡量一次发布? 对单条轨迹或对话使用 evaluate()。对数据集使用 batch_evaluate()。

evaluate(trace=trace)

或

batch_evaluate(traces=traces,

max_workers=4)

单轮还是多轮?是否有任何测试用例依赖更早的轮次?多轮:在数据集中添加 session_id 和 turn_id,并将每一轮都传给适配器,由适配器组装出每个对话。sessions = adapter.transform_to_canonical(turn_payloads)batch_evaluate(traces=sessions)单智能体还是多智能体?是否有多个智能体处理同一个请求?无需配置。适配器会返回 AgentTrace 或 MultiAgentTrace,UAEF 会选择匹配的评估器。adapter = get_adapter(FRAMEWORK)trace = adapter.tra是否需要受控生成轨迹?被动:评测已有轨迹。主动:调用 invoke_* 辅助函数,让 UAEF 运行智能体。evaluate(trace=recorded,adapter=“langgraph”)或raw = invoke_http_agent_for_framework(ENDPOINT, query, “strands”)单条轨迹还是数据集?我是在调试单个案例,还是在衡量一次发布?单条轨迹或对话使用 evaluate()。数据集使用 batch_evaluate()。evaluate(trace=trace)或batch_evaluate(traces=traces,max_workers=4)单轮还是多轮? 是否有任何测试用例依赖更早的轮次? 多轮: 在数据集中添加 session_id 和 turn_id,并将每一轮都传给适配器,由适配器组装出每个对话。

sessions = adapter.transform_to_canonical(

turn_payloads)

batch_evaluate(traces=sessions)

单智能体还是多智能体?是否有多个智能体处理同一个请求?无需配置。适配器会返回 AgentTrace 或 MultiAgentTrace,UAEF 会选择匹配的评估器。adapter = get_adapter(FRAMEWORK)trace = adapter.transform_to_canonical(raw)离线还是在线?我是在发布前测试,还是在监控生产环境?离线:在开发和 CI 中使用准备好的数据集。在线:实时对话,逐轮打分。batch_evaluate(…)或OnlineEvaluator().evaluate_response(trace=trace)临时还是持久化bW 是否有多个智能体处理同一个请求? 无需配置。适配器会返回 AgentTrace 或 MultiAgentTrace,UAEF 会选择匹配的评估器。

adapter = get_adapter(FRAMEWORK)

trace = adapter.transform_to_canonical(raw)

离线还是在线 我是在发布前测试,还是在监控生产环境? 离线: 在开发和 CI 中使用准备好的数据集。 在线: 实时对话,逐轮打分。

batch_evaluate(…)

或

OnlineEvaluator().evaluate_response(

trace=trace)

临时还是持久化我是否要把这次运行与之后的运行进行比较?持久化:设置 persist=True 并指定实验名称。否则,使用返回的结果。batch_evaluate(traces=traces, persist=True,experiment_name=“Support agent v2”)a多轮——详情请参阅多轮评估工作流指南。b只有持久化的运行才能进行比较。准备数据集在 CSV 或 XLSX 文件中为每个测试用例提供一行。只有 是必填的。列必填用途是发送给智能体的输入否预期响应否参考文档 我是否要把这次运行与之后的运行进行比较? 持久化: 设置 persist=True 并指定实验名称。否则,使用返回的结果。

batch_evaluate(traces=traces, persist=True,

experiment_name=“Support agent v2”)

适配器.transform_to_canonical(raw)离线还是在线我是在发布前测试,还是在监控生产环境?离线:在开发和 CI 中使用准备好的数据集。在线:实时对话,逐轮打分。batch_evaluate(…)或OnlineEvaluator().evaluate_response(trace=trace)临时还是持久化b我是否要把这次运行与之后的运行进行比较?持久化:设置 persist=True 并指定实验名称。否则,使用返回的结果。batch_evaluate(traces=traces, persist=True,experiment_name=“Support agent v2”) 多轮—— 详情请参阅 多轮评估工作流指南.

我是否要把这次运行与之后的运行进行比较?持久化:设置 persist=True 并指定实验名称。否则,使用返回的结果。batch_evaluate(traces=traces, persist=True,experiment_name=“Support agent v2”) 只有持久化的运行才能进行比较.

准备数据集

在 CSV 或 XLSX 文件中为每个测试用例提供一行。只有 Question 是必填的。

列 用途是发送给智能体的输入否预期响应否用于检索式评估的参考文档否预期工具调用,以 JSON 数组表示仅多轮将行分组为一段对话仅多轮对一段对话内的轮次排序,从 1 开始,并且匹配时不区分大小写,并接受常见别名,如 和 ,因此现有测试文件通常无需重命名即可使用。多轮数据集。共享 的行会按顺序发送到单个智能体会话,因此后续轮次可以依赖先前的 用途
Question 是 发送给智能体的输入
Answer 否 预期响应
context 否 用于检索式评估的参考文档
expected_tool_calls 否 预期工具调用,以 JSON 数组表示
session_id 仅多轮 将行分组为一段对话
turn_id 仅多轮 对一段对话内的轮次排序,从 1 开始

Question 和 Answer 匹配时不区分大小写,并接受常见别名,如 Query 和 Expected_Output,因此现有测试文件通常无需重命名即可使用。

多轮数据集。 共享同一会话的行会按顺序发送到单个智能体会话,因此后续轮次可以依赖先前的轮次。你的智能体端点必须维护自己的对话状态,因为 UAEF 会为每一轮发送其会话 ID,而不是重放历史记录。请使用小写的 和 。否则,该文件将按单轮进行评估。保护敏感数据。在共享或持久化来自真实流量的数据集之前,请使用 来检测并脱敏个人身份信息,例如电子邮件地址、电话号码和信用卡 session_id 按顺序发送到单个智能体会话,因此后续轮次可以依赖先前的轮次。你的智能体端点必须维护自己的对话状态,因为 UAEF 会为每一轮发送其会话 ID,而不是重放历史记录。请使用小写的 session_id 和 turn_id否则,该文件将按单轮进行评估。

保护敏感数据。 在共享或持久化来自真实流量的数据集之前,请使用 uaef.security.PIIDetector 来检测并脱敏个人身份信息,例如电子邮件地址、电话号码和信用卡号。

示例笔记本

如果你想查看更多示例,请查看我们的 notebooks/ 文件夹。这些笔记本涵盖批处理评估、多轮对话、多智能体以及跨框架的实验管理等场景,涉及的框架包括 LangGraph、Strands Agents 和 Amazon Bedrock AgentCore。

笔记本 涵盖内容
00_langgraph.ipynb LangGraph:单轮、批处理、多轮和多智能体评测
02_langchain.ipynb LangChain 智能体
04_json.ipynb 通过通用 JSON 适配器支持自定义框架
05_strands.ipynb Strands Agents(包括多智能体)
06_agentcore.ipynb Amazon Bedrock AgentCore,包括多智能体
07_langfuse.ipynb 已在 Langfuse 中收集的轨迹
01_langgraph_ragas_deepeval.ipynb RAGAS 和 DeepEval 集成
08_experiment_management.ipynb 实验、基线以及回归检测
10_reporting_pipeline.ipynb 基于已存储结果的报告与仪表盘
11_pii_detection.ipynb 轨迹中的 PII 检测与脱敏

清理

单独运行该库不会产生任何内容,但持久化一次运行会将实验元数据写入 Amazon DynamoDB,并将完整结果写入 Amazon S3。当你不再需要保存的实验时,请将两者都删除。默认名称为 uaef-experiments ,可通过 和 环境变量覆盖。 uaef-results,可通过 覆盖。 UAEF_DYNAMODB_TABLE 和 UAEF_S3_BUCKET 环境变量覆盖。删除存储桶前必须先清空其中的内容。

如果你部署了该服务, 服务部署指南 包含两种部署模式的拆除顺序。在你认为拆除已完成之前,请阅读其保留资源说明:DynamoDB 表、S3 存储桶和 Amazon Cognito 用户池均以保留策略创建,因此删除堆栈后它们及其内容仍会保留在原处。这是有意为之,这样拆除就不会销毁已保存的实验,但这也意味着在你自行移除它们之前,这些存储会持续产生费用。

结论

UAEF 将智能体评测与生成该智能体的框架分离。适配器可将来自 LangGraph、LangChain、Strands Agents、Amazon Bedrock AgentCore 和 Langfuse 的轨迹转换为统一格式,通用 JSON 适配器则可处理其他框架。随后,无论团队以何种方式构建智能体,都同样适用 7 个维度下的 36 项内置指标。UAEF 既可评测单条轨迹,也可对历史轨迹运行批量评测,然后按实验将结果存入 Amazon DynamoDB 和 Amazon S3。团队随后可以跨智能体版本比较各次运行、检测回归,并利用生成的报告和洞察来决定下一轮迭代中要更改什么。Web UI 与 Python 库共用同一评测引擎,因此团队可以先从低代码起步,再转向代码方式,而无需改变评分或存储的工作方式。

要开始使用,请参阅 开源仓库.


关于作者