单轮评估无法捕捉多轮 Agent 的级联失败——早期一个错误会污染后续所有轮次。AWS 提出的 Agent Evaluation Metric (AEM) 支持逐轮分解定位,直接找出导致整条链路失败的初始故障点。
多轮智能体失败的方式是单轮评估无法捕捉的:一个早期的错误会悄然腐蚀后续所有轮次。本文介绍 Agent Evaluation Metric(AEM),一种可分解的、按轮次度量智能体质量的方法。我们将其应用于第一个维度:正确性。我们展示 AEM 如何精确定位导致失败的那一轮,并将其与只是继承了问题的轮次区分开来。
多轮智能体对话中的正确性挑战
在多轮对话中评估智能体的正确性是困难的,因为这个属性本身很脆弱,而整体分数掩盖了它在哪里出问题。本节说明级联错误如何击败结果级评估,并促使我们提出一种可分解的、按轮次的度量方法。
为什么正确性很重要
一次错误的工具调用会级联传播到后续各轮次的失败中。考虑一个五轮对话的企业助手场景。用户要求创建一份销售报告,然后进行优化。在第 2 轮,智能体选择了正确的动作但传入了"profit"而不是"revenue"。这个单一错误随后会在每一个后续轮次中悄无声息地传播。
下图追踪了这个失败过程。它展示了一个早期错误在第 2 轮如何级联传播到第 3–5 轮,以及按轮次评估如何将单一根本原因与其下游影响隔离开来。
图 1:一个早期错误级联传播到后续轮次,而按轮次评估将根本原因隔离出来
任务级评估只检查最终结果。它将整个交互标记为失败,而不揭示只需要修复某一轮。这就是核心问题:在多轮智能体对话中,错误会级联传播,而结果级评估无法将根本原因与其下游影响区分开来。
现有指标的局限性
大多数智能体评估工具在任务或响应级别对质量进行整体评分。当前一代工具提供目标完成度评分和大语言模型(LLM)作为评判者的质量评估。一些工具还添加了跟踪级别的根本原因分析。这些都很有价值,但它们有一个共同的框架:智能体质量被视为单一信号,而不是分解为可独立跟踪的部分。
它们没有提供的是将质量分解为可命名、可独立度量的子指标,并按轮次跟踪的方法。知道智能体"在目标完成度上得了 70 分"并不能告诉你失败是事实错误、缺失信息还是错误的工具选择。单一分数也无法在需求增长时平滑地扩展到新的维度。三个差距如下:
任务级指标(目标成功率)告诉你智能体是否完成了任务,但不能告诉你哪个质量维度出了问题。
单轮指标(有用性、忠实度)在孤立环境中评估响应,而不考虑错误如何跨轮次传播。
整体评分无法将事实错误与缺失必填字段区分开来,而且在不重新架构评估的情况下没有清晰的路径来添加新维度(安全性、指令保持力)。
一种可分解的、按轮次的评估模式填补了这些差距。它将质量分解为可命名的子指标,在完整轨迹中对每一轮进行评估,然后将它们组合成单一指标。同样的方法可以扩展到新维度而无需更改机制。
正确性作为复合指标
我们将智能体质量定义为由可命名、可独立度量的子指标构建的单一复合指标,由 AEM 计算。在本文中,AEM 通过两个子指标来度量正确性:
Truthfulness(真实性):智能体产生的值在事实是否与预期一致?这适用于工具调用中的参数值和自然语言响应中的陈述。
Completeness(完整性):所有必需元素是否都存在?没有缺失的参数,也没有遗漏请求信息的部分响应。
下图展示了这个分解过程。它说明了一个顶层分数如何分解为可命名的子指标,这些子指标独立度量后再重新组合,以及同样的模式如何扩展到未来的维度。
图 2:正确性分解为可命名的子指标,可扩展到新维度
核心贡献是分解本身。AEM 不是单一的不透明分数,而是子指标的复合体,每个子指标可在每轮度量并沿轨迹组合。工具和动作选择构成了它们下面的结构基础。同样的分解-评估-组合模式可扩展到新维度,如安全性、指令保持力和推理深度。正确性是我们实例化的第一个维度。
Agent Evaluation Metric 框架
AEM 将分解思想转化为具体的、逐轮的度量方法。本节定义轮次级层次结构、两个子指标及其组合方式,以及使分数可操作的失败分类法。
轮次级层次结构
正确性按轮次计算。一轮要么是响应轮(智能体回复用户),要么是动作轮(智能体调用工具)。我们以响应轮为先导,因为那是用户最终看到的,同样的度量也适用于动作轮。两者都属于同一个层次结构。
下图展示了这个共享的层次结构。它展示了相同的两个子指标在一边评估工具调用(参数键和值),在另一边评估自然语言响应(覆盖度和基础)。
图 3:相同的两个子指标评估工具调用和自然语言响应
对于响应轮,两个子指标适用于自由文本。Completeness 询问回复是否覆盖了完整问题,而 Truthfulness 询问它在事实上一致。同样的复合指标也适用于动作轮。在动作轮中,Completeness 检查参数键,确认所有必需参数都存在。Truthfulness 检查参数值,确认它们在语义上正确。两者都位于结构检查之上,即是否选择了正确的工具和动作。
在本文中,一轮的正确性被视为二元的:通过或失败,并附有具体的失败原因,命名子指标和字段。同样的分解也支持更细粒度的分级,对单个声明或字段在连续尺度上评分。
在整个对话中组合后,AEM 分数是通过的轮次比例。因为它按子指标分解,下降时会显示是真实性还是完整性维度推动了变化,而不只是说正确性下降了。
AEM 的分解与形式化
两个子指标都依赖语义比较而非精确匹配。对于响应和参数值,精确字符串匹配太过脆弱。"New York City"和"NYC"在语义上是等价的,"Q3 2024 revenue"和"third quarter revenue figures for 2024"传达相同的信息。
语义相似度评分判断两个值是否语义等价。概念上,这个检查如下:
def evaluate_truthfulness(gold_value, predicted_value, scorer, threshold=0.5):
"""Score semantic equivalence of a predicted value against gold."""
if gold_value == predicted_value:
return True, 1.0 # Exact match (fast path)
score = scorer.score(gold_value, predicted_value)
return score >= threshold, score
评分器可以是基于嵌入的相似度检查(快速、便宜)或 LLM-as-judge 调用(更细腻)。嵌入检查是一个透明的编码器加相似度函数,而评判者是一个更不透明的基于解码器的模型,其评分不能直接检查。阈值控制严格程度:更高的阈值能捕获真实错误,但有将语义等价物误标的风险,而更低的阈值则更宽松。这里的 0.5 是一个中性的默认值起始点,不是调优后的值。正确的值取决于你的领域对假阳性与假阴性的容忍度(见Lessons learned)。
相似度分数是连续的。阈值将其Collapse为二元的轮次判决(在本文中),而更细粒度的设置可以保留每个声明的分数而不是这样处理。
Completeness 在语义上检查响应轮(回复是否回答了整个问题?)而在结构上检查动作轮(所有必需的参数键都存在?):
def evaluate_completeness(gold_args, predicted_args):
"""Check all required parameters are present, with no unexpected extras."""
missing = set(gold_args.keys()) - set(predicted_args.keys())
extra = set(predicted_args.keys()) - set(gold_args.keys())
return len(missing) == 0 and len(extra) == 0, missing, extra
返回的 missing 和 extra 集合直接输入到失败分类法中。非空的 missing 集合产生 missing_parameters 失败,而非空的 extra 集合产生 extra_parameters 失败,精确定位哪些参数出了问题。
分解产生每个子指标、每个轮次的判定。合成则将它们汇总为一个数字。合成规则本身就是一种选择,符合该框架的可组合原则。本文默认采用未加权平均通过轮次法。
其他规则同样有效。加权平均对错误时代价更高的轮次给予更高权重。门控规则允许单个关键轮次失败封顶分数。每个子指标阈值,为每个维度设定独立标准。该框架将合成函数视为可插拔的。
当某个轮次失败时,具体的失败原因会精确捕获问题所在。该分类法覆盖两种轮次类型:响应轮次失败与行动轮次失败处于同一层级,结构性检查(工具选择和行动选择)仅在轮次调用工具时适用。
两个子指标——真实性和完整性——在两种轮次类型中保持不变。只有结构性检查是工具特定的。prior_action_failed 标签是使该指标在多轮对话中可操作的关键。它将根本原因与级联效应区分开来,既可以附加到响应轮次,也可以附加到行动轮次。评估器按依赖关系分配标签。当轮次的失败源自该轮次本身时,它就是根本原因;当轮次仅因消耗了已失败轮次的输出而失败时,它获得 prior_action_failed 标签。在开头的示例中,只有第 2 轮是根本原因,第 3-5 轮继承该标签。该指标还跟踪行动链长度(单次调用、两步以及复杂的三步及以上序列),因为较长的链会集中大部分性能退化。
前面描述的指标运行在一个可重复的流水线中。标注对话输入,输出一条分解后的 AEM 分数,归因到每个轮次,贯穿整个智能体生命周期。
下图展示了端到端流程:从标注对话,到逐轮评分和归因,再到被开发和生产环境消费的单一分數。
图 4:从标注对话到分解的逐轮正确性分数
对于这个五轮销售报告示例,流水线返回一个紧凑的分解结果(示例):
{"success_rate": 0.2, "test_pass": false,
"first_failure_turn": 2, "root_cause": "inconsistent_parameter_values",
"root_cause_count": 1, "cascading_count": 3}
评估从真实标注开始:正确答案响应和正确工具调用均已标注的对话。这个黄金参考通常是人工标注的(或者从更强模型引导并经人工审核的),因为它为每个轮次定义了"正确"的含义。每个对话是一系列轮次,每个轮次将黄金(预期)输出与预测(实际)输出配对。每个轮次携带一个标识其生产者的轮次角色。响应轮次和行动轮次如下所示:
[
{
"turn_no": 1,
"turn": "Agent",
"gold_turn": {"response": "Which region should the report cover?"},
"predict_turn": {"response": "Sure, which region would you like the report for?"}
},
{
"turn_no": 2,
"turn": "Tool",
"gold_turn": {"tool_id": "reports", "action": "FilterData",
"args": {"metric": "revenue", "region": "EU"}},
"predict_turn": {"tool_id": "reports", "action": "FilterData",
"args": {"metric": "profit", "region": "EU"}},
"tags": ["OrderInvariant_filter"]
}
]
比较黄金与预测产生逐轮正确性判定。响应轮次通过:措辞与黄金不同但语义等价,这正是语义相似度评分的用途。行动轮次失败:真实 性错误在指标值上暴露(预期 revenue 但预测了 profit)。tags 字段支持顺序不敏感评估。当多个工具调用以任意顺序都有效时(例如查日历和搜航班),评估器会检查有效的排序。它不会惩罚正确但顺序不同的行为。
每个轮次评估完成后,错误归因将根本原因与级联效应分离。它基于轮次判定进行操作,无论该轮次是响应还是行动:
def attribute_errors(turn_results):
"""Separate root cause failures from cascading failures."""
root_causes = []
cascading = []
for result in turn_results:
if not result.success:
if result.failure_reason == "prior_action_failed":
cascading.append(result)
else:
root_causes.append(result)
return {
"first_failure_turn": root_causes[0].turn_no if root_causes else None,
"root_cause": root_causes[0].failure_reason if root_causes else None,
"total_failures": len(root_causes) + len(cascading),
"root_cause_count": len(root_causes),
"cascading_count": len(cascading),
}
# Example output:
# first_failure_turn: 2, root_cause: "inconsistent_parameter_values"
# root_cause_count: 1, cascading_count: 3
# Fix the parameter in turn 2; turns 3-5 likely resolve automatically.
这改变了团队确定修复优先级的方 式。他们不再独立调查每个失败,而是专注于根本原因,因为修复根源后级联失败通常会自动解决。多步链中的单个根本原因,否则可能表现为多个独立失败。
在生产环境中,整体正确性分数被持续跟踪:
该框架输出结构化 JSON,流入监控仪表板。某些错误代价高昂,例如财务计算或合规相关响应。对于这些,分解后的子指标分数也可以与人工或黄金标签进行相关性分析。子指标相关性(例如 Pearson 或 Spearman)显示自动分数是否跟踪人工判断,以及在哪里引入审核员介入。
该方法论与框架无关,但许多团队通过现有测试工具运行评估。轮级正确性信号与 Strands Agents 评估 SDK 集成为自定义评估器。由此它插入到团队已经用于目标完成和 LLM-as-judge 评分的同一流水线中。这些内置评估器将质量报告为整体、每条轨迹的信号。AEM 是互补的,提供分解的、逐轮的正确性分数,将失败归因到特定子指标和轮次。该封装器重用了本文前面构建的逐轮检查(evaluate_truthfulness、evaluate_completeness 和归因逻辑):
from strands_evals.evaluators import Evaluator
from strands_evals.types import EvaluationData, EvaluationOutput
class CorrectnessCustomEvaluator(Evaluator):
"""Wraps the turn-level correctness checks as a Strands Agents custom evaluator."""
def __init__(self, threshold: float = 0.5, name: str = "correctness"):
super().__init__(name=name)
self._threshold = threshold
def evaluate(self, evaluation_case: EvaluationData) -> list[EvaluationOutput]:
# Run the per-turn truthfulness + completeness checks over the dialog
turn_results = evaluate_dialog(evaluation_case, threshold=self._threshold)
success_rate = sum(r.success for r in turn_results) / len(turn_results)
failures = [r.failure_reason for r in turn_results if not r.success]
return [
EvaluationOutput(
score=success_rate,
test_pass=all(r.success for r in turn_results),
reason=f"failing turns: {failures}" if failures else "all turns pass",
label="correctness",
)
]
这里 evaluate_dialog 应用前面所示的相同逐轮真实性和完整性检查,并为每个轮次返回一个结果。这种模式将评估逻辑(分解、失败分类法、轮级组合)保留为可移植的自定义代码,而 Strands Agents 提供运行器、链路收集和报告。具体来说,每次运行产生逐轮链路(工具调用和模型调用的 span)和结构化报告。您可以将该报告显示或导出为 JSON 到您自己的仪表板和告警。AEM 添加了逐轮正确性分数。该封装器在与单个运行中的其他评估器(包括我们在下一篇文章中介绍的安全评估器)一起运行正确性信号。
将框架应用于 Amazon Quick Suite
Amazon Quick Suite 是一款企业级助手,运行的是这种多轮次、多工具对话——正是该指标的适用场景。本节不报告内部生产数据,而是以开头示例中的销售报告对话为例,演示团队如何解读 AEM 输出。
用户最终评判的是每轮收到的回复,因此回复就是我们的评估单位,逐轮贯穿整个对话。在单个回复背后,智能体通常在交互延迟约束下链式调用多个工具,AEM 则对这些工具链产生的结果进行正确性评分。
在整个对话上运行评估流水线,会产生该对话的单一 AEM 分数及其分解。success_rate 是领先指标,其次是各子指标分解,以及 test_pass 标志——只有每轮都通过时该标志才为 true。同一次调用还返回每轮失败原因,用于错误归因。
一个归因示例
回到五轮销售报告对话。第 2 轮传入了 profit 而非预期的 revenue,因此在 truthfulness 上因 inconsistent_parameter_values 而失败。第 3–5 轮基于该结果构建,同样失败,但属于级联失败:每轮都带有 prior_action_failed 标签。原始失败计数报告四个轮次出问题。归因结果则报告一个根因在第 2 轮,以及三个下游影响——这才是有意义的数字。
实际规则是先归因,再调查。以下是几个反复出现的模式,让这一点更加具体,表格总结了每种情况下应查看哪里。
要点是:更长的链会将更大比例的失败推回前面的轮次,而非独立的错误。修复少量根因可以解决许多观察到的失败,因此归因将嘈杂的失败列表转化为简短、有序的修复列表。
实践中总结出几条经验。首先,先归因再调查:prior_action_failed 标签将根因与级联效应区分开来,因此链中一个早期错误不会被读成多个独立失败。
其次,根据领域调整相似度阈值。根据对误报与漏报的容忍度来设置该阈值。阈值过于严格会标记出语义等价项(如"NYC"与"New York City"),而过于宽松则会漏掉真实错误。
第三,标记顺序无关的步骤。当多个工具调用可以任意顺序执行时,将其标记可以让评估器将有效的交替顺序计为正确,而非让正确行为失败。
还有两个更宏观的经验教训涉及信任与增长。对于代价高昂的错误,通过将分解的子指标与人工标签或黄金判断进行相关性验证。让人工审查者进入审查循环,在未被发现的错误会产生实际后果的地方。建立信任后,再通过新增子指标而非新建流水线来扩展:定义每轮标准和失败分类法,然后以相同评分方式组合。规划质量、指令保留和安全都可以遵循这一方法。
结论与下一步
本文介绍了 Agent Evaluation Metric(AEM)作为多轮智能体对话的单一复合指标,并将其应用于第一个维度:正确性。AEM 将正确性分解为命名子指标(truthfulness 和 completeness),在轮次级别精确评估,并进行错误归因。它超越了对失败的检测:能识别哪个维度出了问题、哪一轮导致了问题,以及后续失败是根因还是级联效应。
该方法论融入团队已有的评估工作流。首先是ground truth,然后 AEM 通过 truthfulness 和 completeness 对每轮评分。错误归因再将根因与级联失败分离,因此计数反映的是独立问题而非下游噪声。在模型版本间跟踪分数,将该指标转化为回归信号,可在现有 Strands Agents 流水线中通过 custom-evaluator wrapper 运行。分数下降会指向负责的子指标,失败分类法会识别需要调查的具体轮次。
正确性是 AEM 通过可扩展方法实例化的第一个维度:将质量概念分解为命名子指标,在完整轨迹中评估每轮,归因失败,并将结果组合为单一指标。本系列下一篇文章将把相同方法应用于安全性,后续文章还会扩展到多语言和多模态评估。
要开始使用,请探索 Strands Agents samples 仓库中的工作示例和 Strands Agents 评估文档,然后按上文所示自定义评估器改编为你自己的对话。要了解更多关于这里使用的企业助手,请参阅 Amazon Quick Suite。现在采用正确性维度的团队,可以随着需求增长添加安全性和其他维度。