使用Strands Evals进行AI智能体故障检测与根因分析
本文介绍了Strands Evals SDK中的检测器,它可以自动识别AI智能体执行轨迹中的故障并进行根因分析,将诊断时间从数小时缩短至数分钟。文章详细讲解了如何调用检测函数、解读结构化输出(包括分类故障、置信度、因果链和修复建议),以及如何将检测集成到评估管线中实现自动化诊断。
当AI智能体在生产环境中出现故障时,知道它失败了只是开始。更困难的问题是它为什么失败以及如何修复。传统评估只会告诉你“这个智能体在目标完成上得了60分”,但你需要手动审查执行轨迹来理解问题所在。对于大规模运营智能体的团队,这种手动诊断成为从发现问题到交付修复之间的瓶颈。Strands Evals SDK中的检测器消除了这一瓶颈,它通过自动识别智能体执行轨迹中的故障并进行根因分析,将诊断时间从数小时缩短到数分钟。
本文将引导你调用检测函数来诊断真实的智能体故障。你将学习如何解读它们的结构化输出:带有置信度的分类故障、将根本原因与下游症状联系起来的因果链,以及指明修复属于系统提示词还是工具定义的修复建议。你还将学习如何将检测集成到评估管线中,实现每次测试运行的自动诊断。
检测器补充了之前文章中介绍的评估框架,不仅回答“智能体表现如何?”,还回答“它为什么失败以及如何修复?”。
前提条件
要学习本文内容,你需要满足以下前提条件:Python 3.10或更高版本;通过pip install strands-agents-evals安装Strands Evals SDK;启用Amazon Bedrock模型访问(检测器使用基于大语言模型的分析);对于Amazon CloudWatch示例,需配置具有logs:StartQuery和logs:GetQueryResults权限的AWS凭证。
为什么仅有分数不够
Strands Evals框架通过Cases、Experiments和Evaluators提供可靠的质量信号:目标成功率、工具选择准确率和有用性分数。这些对于捕获回归和从统计层面理解性能非常重要。但考虑一下检测到回归后会发生什么。在部署后或构建时测试中的提示词或工具更改后,智能体的目标成功率从85%下降到70%。评估器确认了下降。然后呢?
你需要识别哪些具体行为导致了故障,区分根本原因和下游症状,确定修复属于系统提示词还是工具定义,并按影响优先级排序。这个诊断工作流传统上需要高级工程师手动逐跨度检查轨迹,并在数百个步骤间关联故障,这个过程无法扩展。
检测器自动化了这一工作流。评估器通过生成本案例级别的分数来回答“智能体表现如何?”。检测器通过生成本跨度级别的诊断(带有分类故障、因果链和修复建议)来回答“为什么失败?”。
检测器工作原理
检测器管线分两个阶段进行,每个阶段都基于对执行轨迹的大语言模型分析。请参阅Understand observability for agentic resources in Amazon Bedrock AgentCore以了解智能体的会话、轨迹和跨度。
第一阶段:故障检测扫描会话中的每个跨度,对照一个全面的故障分类法(分为九个父类别:幻觉、错误操作、编排错误、任务指令违规、执行错误、上下文处理错误、重复行为、LLM输出问题和配置不匹配)。对于每个识别的故障,它返回跨度位置、一个或多个类别、置信度和从轨迹中提取的证据。
第二阶段:根因分析获取检测到的故障并追踪它们之间的因果链。一个上游错误常常级联成多个下游故障。根因分析将原因与症状分开。它将每个故障的因果关系分类(PRIMARY、SECONDARY或TERTIARY),确定传播影响,并生成按修复位置(系统提示词、工具描述或其他)分类的修复建议。
两个阶段都通过分层策略处理不同大小的会话:适合所选检测器模型上下文窗口的会话进行直接分析;中等大的会话进行故障路径修剪(仅保留祖先和后继跨度);非常大的会话进行分块分析并合并结果(将轨迹分割成重叠窗口并协调结果)。
下图展示了端到端管线,有两个入口点汇入相同的检测和分析流程。
[图:检测器管线,集成和独立入口点流入故障检测和根因分析。]
开始故障检测
以下示例使用来自《Evaluating AI agents for production: A practical guide to Strands Evals》中药物发现研究助手的会话轨迹。该智能体基于Strands Agents和Amazon Bedrock构建。要跟着操作,请启用OpenTelemetry跟踪运行智能体,将会话导出为JSON,或使用后面展示的CloudWatchProvider获取现有轨迹。请参阅Strands Agents SDK文档中的User Simulation了解如何设置跟踪和导出会话。
detect_failures函数接收一个Session对象(Strands Evals中的标准轨迹格式)并返回结构化故障。每个故障包括发生故障的跨度、预定义故障分类法中的一个或多个类别、置信度和从轨迹中提取的证据。
import json
from strands_evals.detectors import detect_failures
from strands_evals.types.trace import Session
from strands_evals.detectors import ConfidenceLevel
with open("agent_trace.json") as f:
session = Session.model_validate_json(f.read())
result = detect_failures(session, confidence_threshold=ConfidenceLevel.MEDIUM)
for failure in result.failures:
for cat, conf, ev in zip(failure.category, failure.confidence, failure.evidence):
print(f"[{conf}] {cat} at span {failure.span_id}")
print(f" Evidence: {ev}")以下是一个研究智能体的输出,该智能体被要求“研究为现实世界中的AI供电所需的能源影响”。智能体遇到了工具配置问题并逐渐退化:
[0.9] execution-error-category-tool-schema at span f503a7d546fa4157
Evidence: Tool execution failed due to missing required parameter 'knowledgeBaseId'. Error: 'Parameter validation failed: Invalid type for parameter knowledgeBaseId, value: None'
[0.75] hallucination-category-hall-usage at span 0466979670d14099
Evidence: Agent claims 'I don't have access to the specific knowledge base needed' and then proceeds to provide detailed information about AI energy requirements 'based on general knowledge' without using any tools.
[0.9] orchestration-related-errors-category-goal-deviation at span d98d578e61233d33
Evidence: Agent completely abandons the original task about AI energy requirements and instead provides a lengthy response about marine biology, stating 'I'm going to pivot to discuss marine biology instead.'在一次通过中,检测器识别出多个级别的故障:执行错误(工具参数验证)、语义问题(从“通用知识”产生幻觉)和编排问题(完全偏离目标)。一个跨度可以展示多个故障类别,每个类别都有独立的置信度和证据。
添加根因分析
识别故障很有用,但理解它们发生的原因才能推动修复。analyze_root_cause函数获取检测到的故障并追踪它们之间的因果链,将根本原因与下游症状分开,并推荐每个修复所属的位置。如果没有向analyze_root_cause提供故障,它会自动运行故障检测。
from strands_evals.detectors import detect_failures, analyze_root_cause
failures = detect_failures(session)
rca_result = analyze_root_cause(session, failures=failures.failures)
for rc in rca_result.root_causes:
print(f"Causality: {rc.causality}")
print(f" Span: {rc.failure_span_id} | Fix type: {rc.fix_type}")
print(f" Root cause: {rc.root_cause_explanation}")
print(f" Recommendation: {rc.fix_recommendation}")继续使用相同的研究智能体会话,根因分析揭示了因果结构:
Causality: PRIMARY_FAILURE
Span: f503a7d546fa4157 | Fix type: TOOL_DESCRIPTION_FIX
Root cause: Agent called retrieve tool without required knowledgeBaseId parameter because tool description does not clearly document that knowledgeBaseId is mandatory. This caused parameter validation failure and forced agent into multiple retry attempts with different parameter combinations.
Recommendation: Update retrieve tool description to explicitly mark knowledgeBaseId as a required parameter with clear documentation including format constraints and example values.
Causality: SECONDARY_FAILURE
Span: 0466979670d14099 | Fix type: SYSTEM_PROMPT_FIX
Root cause: Agent fabricated detailed AI energy consumption information claiming it is 'based on general knowledge' after all retrieval attempts failed, because system prompt lacks instruction prohibiting generation of factual content without tool-retrieved evidence.
Recommendation: Add instruction to system prompt requiring agent to explicitly acknowledge inability to complete research tasks when retrieval tools fail, and prohibit generating detailed factual content without tool-verified sources.修复类型的区分使得根因分析可操作。工具模式错误是TOOL_DESCRIPTION_FIX,因为retrieve工具的knowledgeBaseId没有清晰文档化。下游的幻觉是SYSTEM_PROMPT_FIX,因为缺少如何处理持续工具故障的指令。只修复一个类别会留下另一个未处理。
一站式诊断:diagnose_session
为了方便,diagnose_session将两个阶段作为单一管线运行(检测故障,然后分析根因)并返回一个统一的DiagnosisResult,包含去重后的建议:
from strands_evals.detectors import diagnose_session, ConfidenceLevel
result = diagnose_session(session, confidence_threshold=ConfidenceLevel.MEDIUM)
print(f"Found {len(result.failures)} failures, {len(result.root_causes)} root causes")
for rec in result.recommendations:
print(f" - {rec}")这会产生与前面示例相同的故障和根因,打包在一个结果中,建议在所有根因中去重。从一个函数调用中,你就得到一个按修复位置分类的具体更改的优先级列表。
与评估管线集成
当你将检测器集成到现有评估工作流中时,它们提供额外价值。DiagnosisConfig将自动诊断附加到任何实验,使得每个失败的测试案例自动生成诊断:
from strands_evals import Experiment
from strands_evals.evaluators import GoalSuccessRateEvaluator
from strands_evals.detectors import ConfidenceLevel, DiagnosisConfig, DiagnosisTrigger
from strands_evals.types.evaluation_report import EvaluationReport
experiment = Experiment(
cases=test_cases,
task_function=my_agent_task,
evaluators=[GoalSuccessRateEvaluator()],
diagnosis_config=DiagnosisConfig(
trigger=DiagnosisTrigger.ON_FAILURE,
confidence_threshold=ConfidenceLevel.MEDIUM
),
)
report = experiment.run()
report.display(include_recommendations=True)有两种触发模式可用。ON_FAILURE(默认)仅当至少一个评估器返回test_pass=False时运行诊断,这对于CI/CD回归检测具有成本效益。ALWAYS对每个案例运行诊断,无论结果如何,这对于识别名义上通过案例中的次优路径很有用。