How TReNDS automates root-cause analysis with Amazon Bedrock

TL;DR · AI 摘要
TReNDS利用Amazon Bedrock和AWS服务实现自动化根本原因分析,将故障排查效率提升至分钟级。
核心要点
- 结合CloudWatch订阅过滤器与Lambda实现错误实时检测
- 使用Strands Agents SDK与Bedrock模型完成AI驱动的根因分析
- 架构使复杂问题排查时间从小时级缩短至分钟级
结构提纲
按章节快速跳转。
- §引言
介绍TReNDS中心与AWS合作背景及技术选型动机
- ·现有问题
传统日志分析流程耗时且效率低下,需人工追溯执行路径
- ›系统架构
基于CloudWatch+Lambda+Bedrock的自动化分析流水线
- ›核心组件
Strands Agents SDK实现日志上下文与代码关联分析
- ›实施效果
将多服务复杂问题排查时间从小时级降至分钟级
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- TReNDS根因分析架构
- 数据源
- CloudWatch日志
- GitHub源码
- 处理引擎
- Lambda函数
- Strands Agents SDK
- Amazon Bedrock
- 输出
- SNS通知
- 结构化分析报告
金句 / Highlights
值得收藏与分享的关键句。
通过Bedrock模型实现日志上下文、源码和执行路径的智能关联分析
架构使复杂问题的根因定位时间从小时级缩短至分钟级
结合GitHub源码与CloudWatch日志实现执行路径的自动还原
TReNDS如何利用Amazon Bedrock实现根本原因分析自动化 | 人工智能
TReNDS如何利用Amazon Bedrock实现根本原因分析自动化
本文由佐治亚州立大学TReNDS中心的Vitaly Omelchenko与笔者联合撰写。
在神经影像与数据科学转化研究中心(TReNDS)——由佐治亚州立大学、佐治亚理工学院和埃默里大学联合成立的机构——我们开发并应用先进的分析方法和神经信息工具进行脑健康研究。自2019年以来,我们的基础设施一直运行在亚马逊云服务(AWS)上,多年来构建了多样化的应用组合,包括研究工具和API,所有应用均部署在Amazon Elastic Kubernetes Service(Amazon EKS)上,通过FluentBit将日志传输至Amazon CloudWatch。
随着应用规模的增长,我们需要调查的错误数量也呈指数级增加。在探索Amazon Bedrock时,我们发现了一个长期期待的机会:可以自动化事件响应中最耗时的部分——根本原因调查本身。
在本文中,我们将分享在TReNDS生产环境中部署的架构。该架构结合Amazon CloudWatch订阅过滤器、AWS Lambda、Strands Agents SDK和Amazon Bedrock,实现实时错误检测、日志上下文与GitHub源代码的关联,并向团队推送AI驱动的根本原因分析。
本文所述架构和建议反映了TReNDS中心团队的经验,不代表佐治亚州立大学、佐治亚理工学院或埃默里大学的官方指导。
我们希望解决的问题
与许多团队一样,我们已建立了告警和监控系统,能够及时发现系统故障。然而,知道系统出现了故障与理解故障原因存在本质区别。工程师仍需手动打开Amazon CloudWatch Logs,阅读堆栈跟踪,查找相关源文件,并在脑海中追溯执行路径。对于简单错误,这个过程需要15-30分钟;对于涉及多个服务的复杂问题,耗时则会显著增加。
我们意识到,这种调查过程正是具备适当工具的基础模型可以胜任的工作。该模型不仅能够总结错误信息,还能通过提取日志上下文、阅读源代码,生成结构化分析报告。这正是我们决定构建的系统。
架构设计
我们最终采用的架构如下:
图1 — 自动化根本原因分析架构
部署在EKS上的应用通过FluentBit将日志发送至CloudWatch。CloudWatch订阅过滤器监控错误级别模式(ERROR、Exception、FATAL、CRITICAL),当检测到匹配项时触发Lambda函数。Lambda函数运行由Amazon Bedrock驱动的Strands Agent进行错误分析,随后将分析结果发布到Amazon Simple Notification Service(Amazon SNS)主题,实现向团队推送。
系统的核心是 Amazon Bedrock。基础模型(FM)负责实际的错误、代码和根本原因推理。我们在 Amazon Bedrock 上使用 Strands Agents SDK 来处理工具调用编排。我们定义可用的工具,模型则决定何时以及如何调用这些工具。给定一个堆栈跟踪,代理可能会获取相关源文件,意识到需要更多上下文,搜索相关错误处理,并生成结构化分析,而无需我们硬编码该调查路径。
由于 TReNDS 处理与健康相关的研究数据,数据驻留和合规性是重要考量因素。Amazon Bedrock 在我们的 AWS 账户内处理请求,因此日志数据和源代码会保留在与我们应用程序其余部分相同的环境中。AI 分析无需将数据发送到外部端点。这使数据流保持在我们已管理的边界内。这对于我们的工作尤为重要,因为 TReNDS 处理可能受 HIPAA 要求约束的健康相关研究数据。有关符合 HIPAA 要求的 AWS 服务的更多信息,请参阅 AWS HIPAA 合格服务参考。
虽然我们的设置使用了 EKS 和 FluentBit,但这种模式也适用于其他将日志发送到 CloudWatch 的应用程序,包括 ECS、Lambda、EC2 或使用 CloudWatch Agent 的本地部署工作负载。
先决条件
要实现此解决方案,您需要以下内容:
- 具有访问 Amazon Bedrock(具体为 Anthropic Claude Sonnet)权限的 AWS 账户。
- 包含通过 FluentBit 将日志发送到 CloudWatch 的应用程序的 Amazon EKS 集群。
- 配置了订阅过滤器的 CloudWatch 日志组。
- 包含您的应用程序源代码的 GitHub 仓库。
- 安装了 Strands Agents SDK(可通过官方 Lambda 层获取)。
- 熟悉 Python。
- 配置了用于通知的 Amazon SNS 主题。
- 具有适当 IAM 权限的 AWS Lambda 函数,用于访问 Amazon Bedrock、CloudWatch Logs、AWS Secrets Manager 和 SNS。
使用 Strands Agents SDK 构建工具
代理的功能来自于我们赋予它的工具。在我们构建的所有工具中,源代码检索最为关键。堆栈跟踪引用文件路径和行号,但如果没有访问实际实现的权限,代理将仅限于日志模式匹配。通过赋予代理读取源文件的能力,它可以追踪执行路径并识别导致故障的具体代码。使用 Strands Agents SDK,您可以通过用 @tool 装饰 Python 函数来定义自定义工具。这是我们构建的从 GitHub 仓库获取源代码的工具:
import base64
import boto3
import requests
from strands import Agent, tool
# 从 AWS Secrets Manager 获取 GitHub 令牌
secrets_client = boto3.client("secretsmanager")
github_token = secrets_client.get_secret_value(
SecretId="trends/github-token"
)["SecretString"]
@tool
def fetch_source_code(file_path: str, repo: str) -> str:
"""从 GitHub 仓库获取源文件。
Args: file_path: 仓库中文件的路径 repo: 以 'owner/repo' 格式表示的仓库 """ response = requests.get( f"https://api.github.com/repos/{repo}/contents/{file_path}", headers={"Authorization": f"token {github_token}"} ) if response.status_code != 200: return f"无法从 {repo} 获取 {file_path}: HTTP {response.status_code}" content = base64.b64decode(response.json()["content"]) return content.decode("utf-8")
文档字符串和类型提示非常重要。Strands 会使用它们来告诉模型工具的功能以及预期的参数。模型会根据在错误中发现的内容决定何时调用此工具。有关更多模式,请参阅自定义工具文档。
在部署时,我们使用 Strands Agents 官方的 Lambda 层。无需手动打包 SDK。
## 流水线的工作原理
当我们的应用程序之一发生错误时,流水线会自动经过四个阶段。首先,CloudWatch 会检测到错误模式,并使用压缩的日志数据调用我们的 Lambda 函数。Lambda 解码事件后,Strands Agent 接管后续处理。代理会从同一容器中获取额外的日志上下文,从 GitHub 获取相关源代码,并推理根本原因。最后,它会通过 SNS 发布结构化分析结果,发送给我们的团队。以下部分将详细说明每个阶段的具体流程。
### 接收和解码 CloudWatch 事件
CloudWatch 订阅过滤器会将 base64 编码、gzip 压缩的日志事件发送到 Lambda。每次调用包含一个或多个在短时间内窗口内匹配过滤器模式的日志事件。Lambda 处理程序会解码信息,提取日志组名称和匹配事件,并将它们传递给代理进行分析。有关标准解码模式,请参阅 CloudWatch Logs 订阅过滤器文档。
### 获取扩展上下文
订阅过滤器会传递匹配的日志行,但单行通常不足以解决问题。CloudWatch 事件信息包含 logStream,它标识了生成错误的特定容器。我们构建了第二个 @tool 来从同一流中获取周围的日志。这使代理能够获取完整的堆栈跟踪和导致失败的请求上下文,而不会受到其他并发请求的干扰:
@tool def fetch_log_context(log_group: str, log_stream: str, timestamp: int, window_seconds: int = 30) -> str: """从同一日志流中获取错误周围的日志行。
Args: log_group: CloudWatch 日志组名称 log_stream: 生成错误的日志流 timestamp: 错误事件的时间戳(以毫秒为单位) window_seconds: 错误前后的时间窗口 """ response = logs_client.filter_log_events( logGroupName=log_group, logStreamNames=[log_stream], startTime=timestamp - (window_seconds * 1000), endTime=timestamp + (window_seconds * 1000), ) events = response.get("events", []) if not events: return f"在错误发生后的 {window_seconds}s 内,{log_stream} 中未找到日志事件。" return "\n".join(e["message"] for e in events)
通过限定到日志流,我们可以从同一容器中获取干净的、按时间顺序排列的事件序列。这包括触发错误的请求、之前的警告以及完整的异常跟踪信息。
### Agent analysis
代理接收到错误信息及其上下文后,会自主决定需要调查的内容。与遵循预定义决策树的基于规则的系统不同,代理会解析错误信息,识别堆栈跟踪中的文件路径和类名,并确定需要检索的源文件。如果初步代码审查显示错误源自依赖项或共享工具,代理会沿着该链继续追踪,而无需我们进一步提示。我们通过系统提示定义了输出格式:
SYSTEM_PROMPT = """你是一位分析生产环境错误的高级站点可靠性工程师。
给定一个错误及其周围的日志上下文:
- 通过分析堆栈跟踪确定根本原因
- 使用 fetch_source_code 读取相关源文件
- 提供结构化分析,包括:
- 严重程度(CRITICAL/HIGH/MEDIUM/LOW)
- 根本原因解释
- 相关源代码上下文
- 建议的修复方案
- 可能受影响的相关区域
"""
系统提示定义了结构化输出格式,但将调查策略交给模型自行决定。代理根据在错误中发现的内容决定调用哪些工具。带有清晰文件路径的堆栈跟踪会触发 fetch_source_code 调用。没有堆栈跟踪的错误可能导致代理在代码库中搜索错误信息字符串。这种灵活性正是代理方法的核心价值。我们无需预见到应用程序可能产生的每种错误类型。
Lambda 处理程序将所有内容整合在一起:
agent = Agent( model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-20250514"), system_prompt=SYSTEM_PROMPT, tools=[fetch_source_code, search_github_code, fetch_log_context] )
result = agent( f"分析来自 {log_group} 的这个错误:\n\n{error_message}" )
处理程序使用我们选择的 Amazon Bedrock 模型创建 Agent 实例,定义输出格式的系统提示,以及可用工具列表。然后将错误信息和日志组名称传递给代理,触发自主调查循环。
### Delivering results
代理完成分析后,我们会将结果发布到 Amazon SNS 主题,并分发到电子邮件和 Slack。以下是典型通知的示例:
错误分析 — order-service
严重程度:HIGH 错误:OrderService.java:142 处的 NullPointerException
根本原因:processPayment() 方法调用 paymentGateway.charge(), 在网关超时时可能返回 null,但第 142 行在没有 null 检查的情况下 访问 response.getTransactionId()。
源代码上下文(OrderService.java:138-148): [显示相关代码]
建议修复:在访问字段前添加对网关响应的 null 检查。 考虑为网关超时添加重试机制。
相关:RefundService.java:89 中存在类似模式
代理在没有人工指导的情况下自主调查了这个错误。它读取了相关源代码,识别出 null 检查的缺失,甚至标记了另一个文件中的类似模式。这展示了代理方法的价值。与遵循固定检查清单不同,代理会根据每一步发现的内容调整调查策略,就像经验丰富的工程师一样。
自从部署该系统以来,我们明显看到了团队处理生产错误方式的变化。最直接的改变是速度的提升。调查时间从原来的15到30分钟缩短至不到60秒。由于代理的分析包含建议的修复方案,工程师们经常能在邮箱中直接收到现成的解决方案。他们可以立即着手实施修复,而无需花费时间进行诊断。
运行该系统的成本可以忽略不计。每次分析仅产生少量的Amazon Bedrock推理费用,通常每个错误涉及两到三次工具调用。对于我们的工作负载来说,这仅是等效工程师工时成本的一小部分。
我们的开发人员通过电子邮件接收代理的分析结果,反馈一直非常积极。即使对于工程师从未遇到过的错误,这些分析也能提供明确的解决起点。工程师无需额外调查即可快速理解发生了什么以及该如何处理。
发布后,相同的代码路径可能会重复产生错误。我们使用Amazon DynamoDB的去重机制确保只有首次出现的错误会触发分析,其余错误会被静默过滤,从而保持邮箱整洁并降低Amazon Bedrock成本。
## 选择合适的Amazon Bedrock模型
Amazon Bedrock通过单一API为我们提供了多种基础模型的访问。我们测试了多个模型,以找到最适合错误分析场景的模型,评估标准包括推理质量(理解代码和错误)、工具使用可靠性(调用GitHub和CloudWatch工具)、延迟以及每次分析的成本。
模型 | 最适合场景 | 工具使用 | 延迟 | 相对成本
---|---|---|---|---
Anthropic Claude Sonnet | 复杂的多文件推理,细微的代码问题 | 可靠 | 快 | 中等
Anthropic Claude Haiku | 简单错误,高吞吐量的分类处理 | 良好 | 最快 | 低
Anthropic Claude Opus | 深度跨服务调查 | 中等 | 高 |
Amazon Nova Pro | 通用分析,性价比高 |
Amazon Nova Lite | 简单错误分类,预算型工作负载 | 最低
我们选择了Claude Sonnet作为主要模型。在我们的测试中,它始终能生成最准确的根本原因分析。它可以追踪多文件调用链,识别诸如缺少空检查等细微问题,并推理并发问题。对于有不同成本或延迟要求的团队,表格中的其他模型也适合处理更简单的错误模式。
在Strands中切换模型只需一行代码修改,这使我们的评估变得简单直接:
通过修改这一行代码,我们测试了多个模型
请查看Amazon Bedrock文档获取最新的模型ID
model = BedrockModel(model_id="us.anthropic.claude-sonnet-4-20250514")
注意:模型ID会定期更新。请查看Amazon Bedrock支持模型文档获取当前模型ID。
## 下一步计划
我们正在探索该系统的多个扩展方向。首要任务是将检索增强生成(RAG)与我们的内部操作手册进行连接。
- 通过将Amazon Bedrock知识库与我们的内部操作手册及历史事件报告集成,代理将在分析中能够引用TReNDS特定的处理流程。
- 我们还计划实施分层模型策略。简单的、已知的错误模式将路由到Haiku进行快速且低成本的初步处理,而复杂或新颖的错误则升级到Sonnet进行深度分析。这将在错误处理量上实现成本和响应时间的双重优化。
- 最后,我们正朝着自动化创建GitHub问题和拉取请求的方向努力。当代理识别到潜在修复方案时,它将自动生成包含分析结果的GitHub问题,并推送包含建议代码修改的拉取请求,从而减少诊断到解决之间的手动操作步骤。
随着系统规模的扩大,我们也在考虑使用Amazon Bedrock AgentCore来管理代理运行时、可观测性和身份管理。请参阅Strands Agents示例了解多代理和部署模式。
## 结论
我们在TReNDS构建这个系统,是因为我们希望应用中的每个错误都能得到即时的结构化调查,而不仅仅是发出警报。Amazon Bedrock和Strands Agents SDK使实现变得简单直接。我们定义了几个工具并编写了一个系统提示。现在,我们拥有了一个能够像经验丰富的工程师一样推理生产环境错误的代理。它能在几秒钟内输出结果。
添加新功能只需编写另一个@tool函数和几行Python代码。无论需求是Jira集成、包含修复建议的GitHub PR,还是连接到正在运行的Pod进行深入调查的工具,模式都是一致的。基础模型负责推理和编排,我们只需将其连接到所需的系统即可。
## 作者信息
'"`