AWS 기술 블로그
Amazon Bedrock AgentCore Observability로 프로덕션 수준의 AI 에이전트 구축하기
들어가며
AI 에이전트를 개발하다 보면 항상 마주하는 질문들이 있습니다.
- “어디서 병목이 발생하고 있지?”
- “왜 이 에이전트가 예상과 다르게 동작하지?”
- “토큰 비용이 어디에 가장 많이 들고 있지?”
이러한 질문들에 답하기 위해서는 AI 에이전트의 내부 동작을 깊이 있게 관찰할 수 있어야 합니다. 하지만 현실은 어떨까요? 많은 개발팀들이 프로덕션 배포 직전, 혹은 배포 후 에야 모니터링의 필요성을 깨닫고 복잡한 observability 인프라를 급하게 구축하느라 고생합니다.
AWS Summit New York City 2025에서 발표된 Amazon Bedrock AgentCore Observability는 이러한 문제를 근본적으로 해결합니다. 개발 초기 단계부터 프로덕션 환경까지, 일관된 모니터링 경험을 제공하는 통합 솔루션입니다.
AgentCore Observability가 특별한 이유
1. 프레임워크에 구애받지 않는 표준화
AgentCore Observability의 가장 큰 강점은 OpenTelemetry 표준 기반으로 설계되었다는 점입니다. Strands, CrewAI, LangGraph 등 어떤 프레임워크를 사용하든, 어떤 LLM을 선택하든 동일한 방식으로 모니터링할 수 있습니다.
이는 단순히 편의성의 문제가 아닙니다. 여러 프레임워크를 실험하거나, 프로젝트마다 다른 기술 스택을 사용하는 조직에서는 각 프레임워크별로 별도의 모니터링 도구를 학습하고 유지보수해야 하는 부담이 사라집니다.
2. 즉시 사용 가능한 설계
복잡한 설정 없이 바로 시작할 수 있습니다. AgentCore Runtime에서 호스팅되는 에이전트의 경우, 단 4줄의 코드 추가만으로 완전한 observability를 확보할 수 있습니다.
from bedrock_agentcore_runtime import BedrockAgentCoreRuntime
runtime = BedrockAgentCoreRuntime()
response = runtime.invoke(
agent=your_agent,
runtime_session_id="session-123"
)
설정 파일도, 복잡한 계측 코드도 필요 없습니다. 세션 메트릭, 성능 데이터, 에러 추적, 모든 도구 호출 내역까지 자동으로 캡처됩니다.
3. 엔드투엔드 가시성
전통적인 모니터링 도구들이 놓치기 쉬운 영역들을 포괄합니다:
- 토큰 사용량: 각 LLM 호출마다 사용된 토큰 수를 추적하여 비용 최적화 가능
- 도구 선택 패턴: 에이전트가 어떤 순서로 어떤 도구를 선택하는지 분석
- 추론 과정: 각 결정 단계에서의 사고 과정 추적
- 레이턴시 분석: 워크플로우 전체에 걸친 엔드투엔드 지연시간 측정
구현 방법
AgentCore Observability는 두 가지 배포 시나리오를 지원합니다.
시나리오 1: AgentCore Runtime 호스팅
가장 빠르고 간단한 방법입니다. 기존 에이전트 코드에 Runtime SDK만 추가하면 됩니다.
사전 요구사항:
- AWS 계정 및 Bedrock 모델 액세스 권한
- CloudWatch Transaction Search 활성화 (최초 1회만)
- OpenTelemetry 라이브러리 설치
pip install aws-opentelemetry-distro
구현:
from bedrock_agentcore_runtime import BedrockAgentCoreRuntime
from strands import Agent
# 에이전트 정의
agent = Agent(
name="TravelAgent",
instructions="사용자의 여행 계획을 도와주는 에이전트",
tools=[search_flights, book_hotel, get_weather]
)
# Runtime으로 래핑하여 실행
runtime = BedrockAgentCoreRuntime()
response = runtime.invoke(
agent=agent,
runtime_session_id="travel-session-001"
)
이게 전부입니다. 별도의 계측 코드나 설정 없이 완전한 observability가 자동으로 활성화됩니다.
시나리오 2: 외부 환경 호스팅 (EC2, EKS, Lambda 등)
자체 인프라에서 에이전트를 실행하는 경우에도 동일한 수준의 모니터링을 제공합니다.
환경 변수 설정:
# .env 파일
AGENT_OBSERVABILITY_ENABLED=true
OTEL_PYTHON_DISTRO=aws_distro
OTEL_PYTHON_CONFIGURATOR=aws_configurator
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_LOGS_HEADERS=x-aws-log-group=bedrock-agentcore-observability,
x-aws-log-stream=my-agent-stream,x-aws-metric-namespace=AgentCore
OTEL_RESOURCE_ATTRIBUTES=service.name=TravelAgent
실행:
opentelemetry-instrument python your_agent.py
OpenTelemetry 계측이 자동으로 프레임워크 작업, LLM 호출, 도구 실행, 전체 흐름을 캡처합니다.
실전 활용: 데이터 분석과 디버깅
Trace ID 기반 상세 분석
CloudWatch에서는 두 가지 주요 방식으로 데이터를 확인할 수 있습니다.
- GenAI Observability 대시보드
가장 직관적인 접근 방법입니다:
- CloudWatch → GenAI Observability → Bedrock AgentCore
- 전체 에이전트 목록과 세션 개요 확인
- 특정 Session ID 선택하여 상세 trace 조회
다음 스크린샷은 GenAI Observability 메인 페이지의 Bedrock AgentCore 탭을 보여주며, 에이전트 성능을 모니터링하기 위한 핵심 지표들을 표시합니다. 에이전트 목록, 세션 수, 트레이스 개수, 오류 발생률 등의 정보를 확인할 수 있으며, 사용자 정의 시간 범위로 필터링하여 조회할 수 있습니다.

다음 스크린샷은 개별 에이전트를 상세히 분석한 화면으로, 해당 에이전트의 세션, 트레이스, 지연시간, 에러, 스로틀링 정보를 시각화 그래프와 함께 보여줍니다.

다음 스크린샷은 특정 세션 ID를 선택했을 때 표시되는 상세 정보를 보여줍니다. 해당 세션에 연결된 트레이스 목록과 세션 요약 정보를 확인할 수 있으며, 트레이스 ID를 클릭하면 각 span의 상세 정보, 이벤트, 타임라인이 포함된 트레이스 뷰가 나타납니다.

- Transaction Search & Traces
더 깊이 있는 분석이 필요할 때:
- CloudWatch → Transaction Search → Trace ID로 필터링
- 또는 CloudWatch → Traces → Trace ID 직접 검색
Span 단위 분석의 이해
로그는 span 단위로 저장됩니다. 예를 들어 하나의 에이전트 실행이 다음과 같이 분해됩니다:
- LLM 호출 (사용자 질문 분석)
- 도구 실행
- LLM 응답 처리
- 도구 실행
- LLM 호출 (최종 답변 생성)
각 span은 독립적으로 조회 가능하지만, Traces 뷰에서 전체 시퀀스를 시각화하면 훨씬 명확합니다.
Strands 프레임워크 특화 분석
Strands를 사용하는 경우, execution_event_loop_cycle 단위로 로그가 그룹화됩니다:
Cycle 1: 사용자 질문 분석 → 필요한 도구 결정 → 도구 실행 및 결과 수집
Cycle 2: 수집된 데이터 기반 최종 답변 생성
각 cycle의 Event를 클릭하면 LLM에 입력된 전체 메시지를 확인할 수 있어, 중간 단계별 디버깅이 가능합니다.
토큰 사용량 추적:
Metadata 섹션에서 각 호출의 토큰 사용량을 확인할 수 있습니다. Strands agent의 마지막 span에서는 누적된 모든 메시지에 대한 최종 토큰 수를 보여줍니다.
커스텀 로깅으로 더 깊은 인사이트
기본 자동 계측만으로도 충분히 유용하지만, 특정 구간을 더 자세히 추적하고 싶을 때가 있습니다.
커스텀 Span 생성:
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("flight_recommendation_logic") as span:
recommended_flights = analyze_user_preferences(user_input)
# Metadata로 저장
span.set_attribute("user.budget", user_budget)
span.set_attribute("user.preferred_airline", preferred_airline)
span.set_attribute("flights.count", len(recommended_flights))
# Event로 상세 데이터 저장
span.add_event("flight_analysis_input", {
"user_query": user_input,
"filters": search_filters
})
주요 차이점:
- set_attribute: 해당 span의 Metadata에 저장 (필터링, 집계에 유용)
- add_event: 해당 span의 Event에 저장 (입출력 디버깅에 유용)
이를 통해 “프리미엄 사용자의 평균 처리 시간”, “특정 항공사 선호도별 성공률” 등의 분석이 가능합니다.
GenAI Observability vs Traces: 언제 무엇을 쓸까?
GenAI Observability의 장점:
- 더 쉬운 접근성과 직관적인 UI
- Trajectory 뷰 제공 (에이전트의 의사결정 흐름 시각화)
- 비즈니스 사용자도 이해하기 쉬운 구조
Traces의 장점:
- 더 상세한 타임라인 분석
- add_event로 추가한 커스텀 이벤트 확인 가능
- 기술적 디버깅에 최적화
참고: GenAI Observability에서는 add_event 내용이 직접 표시되지 않지만, logger를 사용하면 Event 섹션에 반영됩니다.
비용 관리와 샘플링 전략
Transaction Search 이해하기
중요한 점: X-Ray에는 모든 trace가 저장되지만, CloudWatch Logs에는 기본적으로 1%만 샘플링됩니다. 이는 비용과 성능의 균형을 위한 설계입니다.
제약 없는 조회:
- Trace ID를 직접 아는 경우 → 샘플링 여부와 무관하게 항상 조회 가능
- GenAI Observability 대시보드 → 모든 세션 조회 가능
SQL 스타일 쿼리:
- Transaction Search를 통한 복합 조건 검색
- 샘플링된 데이터에 대해서만 동작
- 필요시 샘플링 비율 조정 가능
프로덕션 베스트 프랙티스
1. 단계별 접근
개발 단계:
- 높은 verbosity 설정
- 100% 샘플링으로 모든 trace 캡처
- 모든 LLM 입출력 로깅
테스트 단계:
- 중간 수준의 로깅
- 10-20% 샘플링
- 주요 구간만 상세 로깅
프로덕션 단계:
- 최소한의 로깅으로 성능 최적화
- 1-5% 샘플링
- 에러 및 비정상 케이스는 항상 로깅
2. 일관된 네이밍 컨벤션
# 좋은 예
span.set_attribute("agent.name", "travel_booking")
span.set_attribute("agent.version", "2.1.0")
span.set_attribute("business.user_tier", "premium")
span.set_attribute("business.transaction_value", 1500)
# 피해야 할 예
span.set_attribute("name", "travel") # 너무 일반적
span.set_attribute("userTier", "premium") # 일관성 없는 네이밍
속성명에 접두사(agent., business., user.)를 사용하면 나중에 쿼리와 분석이 훨씬 쉬워집니다.
3. 민감 데이터 필터링
def sanitize_input(data):
sanitized = data.copy()
sanitized['credit_card'] = '****-****-****-' + data['credit_card'][-4:]
return sanitized
PII, 카드 정보, 비밀번호 등은 절대 로그에 포함되어서는 안 됩니다.
실제 사용 사례: 비용 최적화
한 고객사의 여행 예약 에이전트 사례입니다. Observability를 통해 다음을 발견했습니다:
문제점:
- 항공편 검색 시 평균 3-4회의 LLM 호출 발생
- 각 호출마다 전체 대화 히스토리를 반복 전송
- 월 토큰 비용의 60%가 불필요한 컨텍스트 전송
해결책:
# Before: 매번 전체 컨텍스트 전송
messages = conversation_history + [new_message]
# After: 관련 컨텍스트만 선택적 전송
relevant_context = select_relevant_messages(
conversation_history,
new_message,
max_tokens=2000
)
messages = relevant_context + [new_message]
결과:
- 토큰 사용량 45% 감소
- 응답 시간 30% 개선
- 월 운영 비용 $12,000 절감
이러한 최적화는 Observability를 통한 토큰 사용 패턴 분석 없이는 발견하기 어려웠을 것입니다.
마치며
AI 에이전트는 이제 실험 단계를 넘어 비즈니스 크리티컬한 워크플로우의 중심이 되고 있습니다. 이러한 환경에서 Observability는 선택이 아닌 필수입니다.
Amazon Bedrock AgentCore Observability는 다음을 가능하게 합니다:
- 빠른 개발: 복잡한 설정 없이 즉시 시작
- 깊은 인사이트: 토큰부터 의사결정까지 전 과정 추적
- 프레임워크 독립성: 기술 스택 변경에도 일관된 모니터링
- 프로덕션 준비: 개발 초기부터 내장된 신뢰성
더 이상 “블랙박스” 에이전트에 의존할 필요가 없습니다. 오늘부터 투명하고 신뢰할 수 있는 AI 시스템을 구축하세요.
더 알아보기
- AgentCore Observability 공식 문서: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html
- OpenTelemetry 시맨틱 컨벤션: https://opentelemetry.io/docs/concepts/semantic-conventions/
- Amazon Bedrock AgentCore 강의시리즈
- Amazon Bedrock AgentCore 블로그 시리즈
- Amazon Bedrock AgentCore Runtime을 쉽고 빠르게 시작하기
- Enterprise Agentic AI를 위한 Amazon Bedrock AgentCore Built-in Tools: Code Interpreter and Browser Tool
- Amazon Bedrock AgentCore Gateway: AI 에이전트의 MCP 도구 통합 관리하기
- Amazon Bedrock AgentCore Identity로 안전한 기업형 에이전트 구현하기
- Amazon Bedrock AgentCore Observability with Langfuse