4가지 침묵하는 실패, 2개의 문서화되지 않은 API, 그리고 사용자 정보 누락으로 충돌한 컨테이너
요약
CrewAI 에이전트를 AWS Bedrock AgentCore에 배포하는 과정에서 겪은 디버깅 사례를 다룹니다. PyPI의 플레이스홀더 패키지 문제, 잘못된 HTTP 상태 코드, 문서화되지 않은 제약 사항 등 실제 배포 환경에서 마주치는 기술적 난관과 해결 방법을 공유합니다.
핵심 포인트
- PyPI의 플레이스홀더 패키지로 인한 의존성 오류 주의
- AWS CodeArtifact를 통한 실제 SDK 설치 필요성
- 200 OK 응답이 실제 성공을 보장하지 않는 상황 인지
- 문서화되지 않은 명명 규칙 및 클라이언트 분리 이슈 대응
이 글은 Sentry가 지원하는 DEV's Summer Bug Smash: Smash Stories를 위한 제출물입니다.
저는 CrewAI 에이전트를 AWS Bedrock AgentCore에 배포하는 데 일주일을 보냈습니다. SDK는 PyPI에 없었습니다. 에러 메시지는 200 OK였습니다. 컨테이너는 로그도 없이 충돌했습니다. 그리고 명명 규칙 정규식(naming regex)은 왜 그런지 알려주지도 않은 채 하이픈(-)을 거부했습니다.
이것은 전체 디버깅 과정입니다. 모든 실패는 침묵 속에서 일어났습니다. 모든 해결책은 아무도 문서화하지 않은 소스 코드를 읽어야만 가능했습니다.
목차
- 프로젝트
- 실패 1: PyPI에 존재하지 않는 SDK
- 실패 2: 실패를 의미하는 200 OK
- 실패 3: 로그 없이 충돌한 컨테이너
- 실패 4: 아무도 문서화하지 않은 명명 정규식
- 아무도 언급하지 않는 두 클라이언트의 분리
- 배운 점
프로젝트
저는 CrewAI와 Amazon Bedrock을 사용하여 이력서 맞춤형 AI 에이전트를 구축했습니다. 이 에이전트는 직무 기술서(job description)를 가져와 사용자의 이력서를 분석하고, 부족한 부분을 식별하며, 해당 역할에 실제로 필요한 내용에 맞춰 불렛 포인트(bullet points)를 다시 작성합니다.
로컬 환경에서는 완벽하게 작동했습니다. CrewAI가 에이전트를 오케스트레이션(orchestrate)하고, Bedrock Nova Pro가 LLM 호출을 처리하며, 출력 결과도 견고했습니다. 문제는 이를 프로덕션(production)에 배포하는 것이었습니다.
AWS는 2026년 6월에 AI 에이전트를 위한 관리형 런타임(managed runtime)으로 Bedrock AgentCore를 출시했습니다. 에이전트를 컨테이너화하고 이미지를 푸시하면, AgentCore가 스케일링(scaling), 메모리, 호출(invocation)을 처리합니다. 간단해 보입니다.
하지만 간단하지 않았습니다.
실패 1: PyPI에 존재하지 않는 SDK
문서에는 bedrock-agentcore-client를 설치하라고 되어 있습니다. 저는 다음과 같이 실행했습니다:
pip install bedrock-agentcore-client
설치는 성공했습니다. 에러도 없었습니다. 그 이유는 PyPI에 해당 이름의 **플레이스홀더 패키지(placeholder package)**가 있기 때문입니다. 설치는 되지만 임포트(import)는 침묵 속에 실패하며, 컨테이너는 내부적으로 깨진 의존성(dependency)을 가진 채 성공적으로 빌드됩니다.
실제 SDK는 AWS의 CodeArtifact 레지스트리에 있습니다. pip가 프라이빗 인덱스(private index)에서 가져오도록 설정해야 합니다:
aws codeartifact login --tool pip \
--domain amazon-agent-runtimes \
--repository agent-runtimes-pypi \
...
그곳에서 설치하세요. PyPI 패키지는 함정입니다. 아무도 경고해주지 않습니다.
낭비된 시간: 3시간. 에러는 컨테이너가 모듈을 임포트(import)하려고 시도하는 런타임(runtime) 시점에만 나타납니다. 빌드(build)는 성공합니다. 푸시(push)도 성공합니다. 배포(deployment)도 성공합니다. 하지만 호출(invocation) 결과는 빈 페이로드(payload)를 반환합니다.
실패 2: 실패를 의미하는 200 OK
SDK를 수정한 후, 에이전트(agent)를 배포하고 호출했습니다:
aws bedrock-agentcore-control invoke-agent-runtime \
--agent-runtime-id abc123 \
--payload '{"job_description": "..."}'
응답: HTTP 200. 페이로드(Payload): 빈 문자열.
500 에러도 아닙니다. 400 에러도 아닙니다. 에러 메시지도 없습니다. 내용물이 아무것도 없는 성공적인 HTTP 응답입니다.
CloudWatch를 확인했습니다. 로그가 없습니다. 컨테이너 상태를 확인했습니다. 실행 중(Running)입니다. 에이전트 런타임(agent runtime) 상태를 확인했습니다. 활성(Active) 상태입니다.
문제는 제 IAM 역할(role)에 bedrock:GetAgentRuntime 권한이 누락되었다는 것이었습니다. 이 권한이 없으면 호출 엔드포인트(invocation endpoint)는 요청을 수락하고, 이를 어디로도 라우팅(route)하지 않은 채 빈 본문(body)과 함께 200을 반환합니다.
에러 메시지도 없습니다. 로그 엔트리(log entry)도 없습니다. 서비스는 실패했을 때 성공을 반환합니다.
낭비된 시간: 5시간. 다양한 페이로드, 다양한 콘텐츠 타입(content types), 다양한 SDK 버전, curl 대 boto3, 동기(synchronous) 대 스트리밍(streaming) 방식을 모두 시도해 보았습니다. 모두 200 OK였고, 모두 비어 있었습니다. 해결책은 누락되었을 때 아무런 에러 신호도 생성하지 않는 단 하나의 IAM 권한이었습니다.
{
"Effect": "Allow",
"Action": "bedrock:GetAgentRuntime",
...
실패 3: 로그 없이 충돌한 컨테이너
다음 실패입니다. 컨테이너가 시작되고 30초 동안 헬스 체크(health checks)를 통과한 뒤 죽어버립니다. CloudWatch에 예외(exception)가 없습니다. 크래시 로그(crash log)도 없습니다. 상태는 이유 없이 "Failed"로 표시됩니다.
생각할 수 있는 모든 로깅(logging) 구문을 추가했습니다. Print 문, 구조화된 로깅(structured logging), 모든 임포트(import)를 감싸는 예외 처리기(exception handlers)까지 말입니다. 하지만 CloudWatch에는 아무것도 나타나지 않았습니다. 컨테이너가 로깅 프레임워크(logging framework)를 초기화할 수 있을 만큼 충분히 진행되지 못했기 때문입니다.
원인은 Dockerfile에 USER 1000 지시어가 누락된 것이었습니다.
# 이것은 조용히 충돌합니다
FROM python:3.12-slim
WORKDIR /app
...
이것은 정상적으로 작동합니다
FROM python:3.12-slim
RUN useradd -m -u 1000 agentuser
...
AgentCore는 컨테이너가 UID 1000으로 실행될 것을 요구합니다. 그렇지 않으면 런타임(runtime)이 컨테이너를 종료합니다. 콘솔의 에러 메시지에는 그저 "Failed."라고만 나옵니다. 그냥 "Failed."일 뿐입니다. 사용자 지시어(user directives), 권한(permissions), 또는 UID 요구 사항에 대한 언급은 전혀 없습니다.
저는 이를 AgentCore 팀의 GitHub 샘플 저장소(repos)를 읽고 찾아냈습니다. 문서(docs)가 아니라, 샘플 Dockerfile을 통해서 말이죠.
낭비된 시간: 4시간.
실패 4: 아무도 문서화하지 않은 네이밍 정규식 (regex)
제 에이전트 런타임(agent runtime)의 이름을 resume-tailor-agent로 지정하고 싶었습니다. 배포는 실패했습니다:
An error occurred (ValidationException):
Name must match pattern: ^[a-zA-Z0-9_]+$
하이픈(-)은 허용되지 않습니다. 알겠습니다. 이름을 resume_tailor_agent로 변경하고 넘어갔습니다.
하지만 이 에러 메시지는 컨트롤 플레인(control plane) 클라이언트를 사용할 때만 나타납니다. 콘솔(console)을 사용하면 그냥... 제출이 되지 않습니다. 빨간색 테두리도, 에러 토스트(error toast)도, 유효성 검사(validation) 메시지도 없습니다. 버튼을 눌러도 아무런 반응이 없습니다.
낭비된 시간: 1시간. 짧은 시간이었지만, 패턴은 동일합니다: 조용한 실패(silent failures).
아무도 언급하지 않는 두 클라이언트의 분리
여기서부터는 아키텍처(architectural)적인 문제입니다. AgentCore에는 두 개의 Python 클라이언트가 있습니다:
- 런타임을 관리하기 위한
bedrock-agentcore-control(생성, 업데이트, 삭제) - 런타임 SDK (컨테이너 내부에서 실행되는 것)를 위한
bedrock-agentcore
문서에서는 이 두 가지를 혼용하여 사용합니다. 코드 샘플은 설정(setup) 섹션에서는 하나를 임포트(import)하고, 호출(invocation) 섹션에서는 다른 하나를 임포트합니다. 이들은 설치 경로(install paths)도 다르고, CodeArtifact 저장소(repositories)도 다르며, API 표면(API surfaces)도 다릅니다.
잘못된 것을 설치해도 아무도 알려주지 않습니다. 설치한 패키지에 존재하지 않는 임포트(import)를 만날 때까지 코드는 계속 실행됩니다. 그리고 일부 버전에서는 두 패키지의 모듈 이름이 겹치기 때문에, 에러는 상단의 깔끔한 ImportError가 아니라 함수 호출 깊은 곳에서 발생하는 AttributeError로 나타날 수도 있습니다.
저는 어떤 클라이언트가 어떤 역할을 하는지 정리했습니다:
| 클라이언트 (Client) | 목적 (Purpose) | 설치 경로 (Install From) |
|---|---|---|
bedrock-agentcore-control | 런타임 생성/관리 (Create/manage runtimes) | CodeArtifact (도메인: amazon-agent-runtimes) |
| ... |
제가 찾은 그 어떤 문서에도 이 테이블은 존재하지 않습니다.
내가 배운 것들
5일간의 디버깅. 4가지의 뚜렷한 침묵하는 실패 (silent failures). 유용한 에러 메시지는 0개.
모든 문제는 동일한 패턴을 공유했습니다: 시스템이 잘못된 입력을 수락하고, 성공을 반환한 뒤, 무엇이 잘못되었는지 알리지 않은 채 다운스트림 (downstream) 어딘가에서 실패하는 것입니다. 실패를 의미하는 200 OK. 플레이스홀더 (placeholder) SDK로 성공해 버리는 빌드. 로그 없이 충돌하는 컨테이너.
만약 첫날부터 컨테이너에 Sentry를 도입했더라면, 임포트 (import) 실패, UID 충돌, 그리고 빈 응답 패턴을 며칠이 아닌 몇 시간 만에 잡아냈을 것입니다. 에이전트 배포에서 관찰 가능성 (Observability)은 선택 사항이 아닙니다. 인프라는 당신으로부터 실패를 적극적으로 숨깁니다.
앞으로 가져갈 세 가지 원칙:
1. 새로운 서비스의 200 OK를 절대 신뢰하지 마세요. 응답 본문 (response body)을 검증하세요. 만약 비어 있다면, 업스트림 (upstream) 어딘가에서 무언가 조용히 고장 난 것입니다.
2. 다른 무엇보다도, 컨테이너 시작 시점에 임포트를 테스트하세요. 모든 중요한 임포트 주변에 명시적인 로그 라인을 포함한 try/except 문을 작성하세요. 만약 SDK가 가짜라면, 첫 1초 만에 알 수 있을 것입니다.
3. 문서만 보지 말고 샘플 리포지토리 (sample repos)를 읽으세요. AWS의 예시 리포지토리에 있는 Dockerfile에는 USER 1000이 있었습니다. 문서는 이를 전혀 언급하지 않았습니다. 샘플 코드가 때로는 진짜 문서입니다.
그 이후로 저는 보안 포스처 스캐너 (security posture scanner) 프로젝트의 에이전트 파이프라인에 Sentry를 추가했습니다. 트레이스 폭포 (trace waterfalls)는 print 문을 사용했을 때 몇 시간이 걸렸을 문제들을 몇 초 만에 잡아냅니다. 혹독한 대가를 치르고 배운 교훈입니다.
위에 기술된 모든 에러는 2026년 7월 AgentCore의 GA (General Availability) 릴리스에서 발생한 것입니다. 이 글을 읽을 때쯤에는 일부가 수정되었을 수도 있습니다. 새로운 AWS 서비스에서 발생하는 침묵하는 실패의 패턴은 아마 영원할 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기