Sentry의 Span 계층 구조를 통해 발견한 5개 에이전트 파이프라인 내의 조용한 재시도: 한 에이전트가 22.6초를 소요하는 동안
요약
CrewAI와 Amazon Bedrock을 활용하여 AWS 보안 설정을 스캔하는 5단계 멀티 에이전트 파이프라인 구축 사례를 소개합니다. Sentry의 Span 계층 구조를 통해 에이전트 실행 중 발생하는 지연 시간과 조용한 재시도 문제를 모니터링하고 분석하는 방법을 다룹니다.
핵심 포인트
- CrewAI와 Amazon Bedrock Nova Pro를 결합한 멀티 에이전트 시스템 구축
- AWS 리소스 스캔 및 CIS 벤치마크 매핑을 위한 전문 에이전트 설계
- Sentry를 활용한 에이전트 파이프라인의 실행 성능 및 지연 시간 계측
- 에이전트 내부의 조용한 재시도로 인한 성능 저하 문제 식별
이 글은 Sentry가 지원하는 DEV's Summer Bug Smash: Clear the Lineup을 위한 제출물입니다.
프로젝트 개요 (Project Overview)
저는 AWS Security Posture Agent를 구축했습니다. 이는 보안 설정 오류(misconfigurations)를 스캔하여 AWS 계정을 조사하고, 발견 사항을 CIS 벤치마크에 매핑하며, 위험 점수를 산출하고, 복사해서 붙여넣을 수 있는 수정 명령어를 생성하는 5개의 전문 AI 에이전트입니다.
이 에이전트들은 Amazon Bedrock Nova Pro를 LLM (Large Language Model)으로 사용하여 CrewAI에서 순차적으로 실행됩니다:
1. ResourceDiscovery → EC2, S3, Lambda, IAM, SG, API GW, DynamoDB 인벤토리 작성
2. SecurityScanner → 열린 포트, 퍼블릭 버킷, 관리자 역할, 보안에 취약한 설정 탐색
3. ComplianceChecker → CIS AWS Foundations Benchmark에 매핑
...
각 에이전트는 90개의 IAM 역할, 14개의 S3 버킷, 9개의 보안 그룹(Security Groups), 7개의 Lambda 함수가 있는 실제 계정을 대상으로 실제 AWS API 호출을 수행하는 커스텀 boto3 도구를 가지고 있습니다. 테스트 데이터가 아닙니다. 실제 발견 사항입니다.
GitHub logo simplynadaf / aws-security-posture-agent
CrewAI + Amazon Bedrock을 사용하여 AWS 계정의 보안 설정 오류를 스캔하고, Sentry AI Agent Monitoring으로 계측(instrumented)된 멀티 에이전트 AI 시스템입니다. 5개의 전문 에이전트가 리소스를 발견하고, 보안을 분석하며, CIS 벤치마크에 매핑하고, 위험 점수를 산출하며, 수정 명령어를 생성합니다.
AWS Security Posture Agent
5개의 AI 에이전트가 AWS 계정을 스캔합니다. 설정 오류를 찾고, 위험 점수를 매기며, 수정 명령어를 받으세요.
빠른 시작 (Quick Start) | 아키텍처 (Architecture) | 스크린샷 (Screenshots) | 성능 수정 (Performance Fix)
문제 (The Problem)
대부분의 AWS 계정은 보안 부채 (security debt)를 조용히 쌓아갑니다. 테스트를 위해 열어둔 SSH 포트, 암호화되지 않은 S3 버킷, 아무도 생성한 기억이 없는 전체 관리자 권한 (full admin access)의 IAM 역할 등이 있습니다. 수동 감사 (manual audits)는 무언가를 놓치기 마련이며, AWS Config 규칙은 비용이 발생합니다. SecurityHub는 너무 시끄럽습니다 (noisy).
이 에이전트는 60초 내에 귀하의 계정을 스캔하여 실제 문제를 찾아내고, 이를 CIS 벤치마크 (CIS benchmarks)에 매핑하며, 위험 점수를 산정하고, 각 문제를 해결하기 위한 정확한 AWS CLI 명령어를 제공합니다.
발견 내용 (What It Finds)
실제 AWS 계정 (90개의 IAM 역할, 14개의 S3 버킷, 9개의 보안 그룹, 7개의 Lambda 함수)에서:
97개의 보안 탐지 결과 (security findings)
├── CRITICAL: 0.0.0.0/0으로부터의 열린 SSH/RDP, MFA가 없는 IAM 사용자
├── HIGH: 관리자 역할, 암호화되지 않은 EBS, 퍼블릭 액세스 차단 누락
...
…
데모 (Demo)
제 AWS 계정을 대상으로 실행되는 전체 스캔 과정입니다. 스캔 부분은 4배속으로 재생되었으며, 결과 설명 부분은 정상 속도로 진행됩니다:
버그 수정 또는 성능 개선 (Bug Fix or Performance Improvement)
저의 첫 번째 본능은 Bedrock의 지연 시간 (latency)을 탓하는 것이었습니다. 무언가 느려질 때마다 LLM을 탓하게 되곤 하니까요, 그렇지 않나요?
SecurityScanner 에이전트는 22.6초가 소요된 반면, 다른 모든 에이전트는 평균 5~10초가 걸렸습니다. 각 에이전트의 실행 내부에서 어떤 일이 일어나고 있는지에 대한 가시성 (visibility)이 없었다면, 저는 time.time() 호출을 추가하며 추측만 했을 것입니다.
Sentry의 트레이스 워터폴 (trace waterfall)은 다른 이야기를 들려주었습니다. 진짜 문제는 Python 실행 시간이나 네트워크 지연 시간이 아니었습니다. 문제는 LLM이 첫 번째 시도에서 깔끔하게 처리할 수 없는 컨텍스트 페이로드 (context payload)를 받았다는 것이었습니다.
근본 원인: 제가 만든 IAMAnalyzer 도구가 계정 내의 90개 IAM 역할(서비스 연결 역할 (service-linked roles)을 필터링한 후에는 59개)을 모두 가져온 뒤, 이를 27KB 크기의 JSON 블롭 (JSON blob)으로 직렬화하여 해당 페이로드 (payload) 전체를 도구 출력값으로 LLM에 전달했습니다. 이로 인해 컨텍스트 윈도우 (context window)가 과부하되었습니다. CrewAI의 내부 재시도 (retry) 로직이 작동했고, 더 많은 컨텍스트를 포함한 두 번째 시도에서 토큰을 낭비하게 되었습니다.
도구 하나. 잘못된 기본 설정. 파이프라인 전체가 피해를 입었습니다.
코드 (Code)
수정 사항이 포함된 PR:
GitHub logo fix: paginate IAM analysis and add token budget guard #1
**simplynadaf**가 2026년 7월 20일에 게시함
무엇이 문제였나 (What)
IAMAnalyzer 도구가 계정 내의 모든 역할(90개, 서비스 연결 역할을 필터링한 후 59개)을 가져와 전체 상세 정보를 단일 JSON 블롭에 쏟아부었습니다. 이 블롭의 크기는 26,980자에 달했습니다. LLM은 이를 처리하지 못해 막혔고, CrewAI는 작업을 재시도했습니다. 그 결과 SecurityScanner 에이전트가 22.6초를 소요하는 동안 다른 모든 에이전트는 5~10초 만에 작업을 마쳤습니다.
어떻게 발견했나 (How I found it)
각 에이전트와 도구에 Sentry 스팬 (spans)을 추가했습니다. 트레이스 폭포수 (trace waterfall)를 보니 명확했습니다. SecurityScanner가 다른 모든 것보다 두 배나 넓었습니다. 도구 스팬 (tool spans)을 자세히 조사해 보니, 다른 도구들이 약 4,000자인 것에 비해 iam_analyzer는 result_length_chars: 26980을 기록하고 있었습니다.
7배나 차이 나는 출력량. 그것이 문제였습니다.
무엇을 변경했나 (What I changed)
iam_analyzer.py에서 세 가지를 변경했습니다:
- 역할을 페이지네이션 (paginate)하고
RoleLastUsed날짜별로 정렬하여, 가장 활발하게 사용된 상위 20개만 분석합니다. 나머지는 몇 달 동안 아무도 건드리지 않은 오래된 역할들입니다. - 31개의 서비스 연결 역할을 사전에 건너뜁니다 (어차피 수정할 수 없으므로, 이를 감사하는 것은 노이즈에 불과합니다).
- 마지막에 토큰 예산 가드 (token budget guard)를 추가했습니다: JSON 출력이 4,000자를 초과하면
role_summary를 이름과 정책 목록만 남기고 축소합니다.
수치 (Numbers)
- 도구 출력 (Tool output): 26,980자에서 15,532자로 감소 (42% 감소)
- SecurityScanner: 22.6초에서 17.8초로 감소 (21% 빨라짐, 더 이상 LLM 재시도 없음)
- IAM에 대한 API 호출 (API calls to IAM): 59회에서 20회로 감소
- 전체 파이프라인 (Total pipeline): 62초에서 57.7초로 감소
- 발견 사항 (Findings): 여전히 27개. 가장 활발한 상위 20개 역할(Role)에 모든 문제적 역할(AdminRole, Bedrock-Lambda-Role 등 모두 빈번하게 사용됨)이 포함되어 있으므로 커버리지 손실은 없음.
핵심 변경 사항은 src/security_posture/tools/iam_analyzer.py에 있습니다. 변경 전후는 다음과 같습니다:
변경 전 (버그 발생):
# 페이지네이션 제한 없이 모든 역할(Role)을 가져옴
roles = iam.list_roles(MaxItems=100)
role_details = []
...
이는 90개의 역할이 있는 계정에 대해 26,980자의 JSON을 생성합니다. LLM이 이를 처리하지 못하고 막혀버립니다 (chokes).
변경 후 (수정 완료):
# 수정: 페이지네이션(Paginate)을 적용하고 관련성(relevance)에 따라 정렬
all_roles = []
paginator = iam.get_paginator("list_roles")
...
여기에 마지막으로 토큰 예산 가드(token budget guard)가 추가되었습니다:
# 토큰 예산 가드: 출력이 임계값을 초과하면 잘라냄
if len(output) > 4000:
result["role_summary"] = [
...
세 가지 변경 사항이 적용되었습니다. 페이지네이션(Pagination), 관련성 정렬(relevance sorting), 그리고 안전 밸브(safety valve)입니다. 이로 인해 SecurityScanner의 재시도가 중단되었습니다.
나의 개선 사항
결과 우선:
| 지표 (Metric) | 변경 전 | 변경 후 | 개선 사항 |
|---|---|---|---|
| IAM 도구 출력 (IAM tool output) | 26,980자 | 15,532자 | 42% 감소 |
| ... |
SecurityScanner의 21% 성능 향상은 LLM이 재시도하는 대신 단 한 번의 패스(single pass)로 분석을 완료했기 때문에 발생했습니다.
발견 과정:
수정 자체는 간단합니다. 흥미로운 점은 Sentry가 어떻게 저를 문제의 핵심으로 바로 안내했는가 하는 점입니다.
트레이스 폭포수(trace waterfall)가 없었다면, 저는 그저 "파이프라인이 62초 걸린다"는 것만 알았을 것입니다. 하지만 트레이스는 다른 사실을 말해주고 있었습니다:
- 각 에이전트 실행을
gen_ai.invoke_agentspan으로 감쌉니다. - 각 도구 호출(tool call)을
gen_ai.execute_toolspan으로 감쌉니다. - 파이프라인을 실행하고 트레이스 워터폴(trace waterfall)을 확인합니다.
SecurityScannerspan은 시각적으로 명확했습니다: 다른 모든 것보다 두 배나 넓었습니다.- 그 내부의
iam_analyzer도구 span은result_length_chars가 26,980임을 보여주었습니다. security_group_analyzer의 4,200자 및s3_config_checker의 3,800자와 비교해 보십시오.
이 불균형이 단서였습니다. 도구의 출력이 형제 도구들보다 7배 더 크다면, 이를 줄여야 합니다.
Sentry의 최적 활용법
저는 Sentry의 AI 에이전트 모니터링(AI Agent Monitoring)을 사용하여 CrewAI 멀티 에이전트 파이프라인을 처음부터 계측(instrument)했습니다. 이것은 웹 앱이나 API가 아닙니다. LLM 호출을 수행하고 커스텀 도구를 실행하는 5개의 자율 AI 에이전트입니다. 표준 APM(Application Performance Monitoring)은 여기에서 도움이 되지 않았을 것입니다.
계측한 내용
모든 파이프라인 실행은 다음과 같은 span 계층 구조를 가진 Sentry 트랜잭션(transaction)을 생성합니다:
Transaction: "Security Posture Scan" (57s)
├── gen_ai.invoke_agent: ResourceDiscovery
│ └── gen_ai.execute_tool: aws_resource_scanner
...
계측 코드
각 에이전트에 대해 (main.py 내):
with start_span(
op="gen_ai.invoke_agent",
name=f"invoke_agent {agent_name}",
...
각 도구에 대해 (monitoring.py 내 데코레이터):
def trace_tool(tool_name: str):
def decorator(func):
@functools.wraps(func)
...
Sentry가 밝혀낸 것
트레이스 워터폴(trace waterfall)은 병목 현상을 시각적으로 명확하게 드러냈습니다. SecurityScanner span은 다른 어떤 에이전트보다 거의 두 배나 넓었으며, 다른 에이전트들이 평균 5~10초가 걸리는 동안 22.6초가 소요되었습니다.
그 내부에서 iam_analyzer 도구 span은 result_length_chars: 26980을 보여준 반면, s3_config_checker는 3,800을, security_group_analyzer는 4,200을 보여주었습니다. 입도(granularity)는 개별 boto3 호출 수준까지 내려갑니다. 모든 GetPublicAccessBlock, ListRoles, ListAttachedRolePolicies가 각각의 span으로 나타납니다.
수정 전 (SecurityScanner가 22.6초로 트레이스를 점유함):
⚠️ 수정 전 (SecurityScanner가 22.6초로 트레이스를 점유함):


수정 후 (모든 에이전트가 비례하며, 단일 병목 현상 없음):
[
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기