Claude Code를 팀에 도입하기로 결정했다면, 첫 번째 실수는 환경 변수 하나로 끝낼 수 있다고 착각하는 것이다. CLAUDE_CODE_USE_BEDROCK=1 한 줄이면 동작한다. 그리고 그 한 줄 뒤에, 대부분의 팀이 예상하지 못한 세 가지 문제가 기다리고 있다. 거버넌스 구멍, 비용 누수, 그리고 프로덕션 인프라 미비. 이 세 축은 서로 독립적이지 않다. 하나가 뚫리면 나머지 두 개도 흔들린다.
왜 Bedrock인가—거버넌스가 답이다
직접 Anthropic API를 쓰는 것과 AWS Bedrock을 경유하는 것, 모델 품질은 동일하다. 차이는 통제 레이어에 있다. dev.to의 실무 가이드(iqraa.tech 전문 공개)가 정리한 핵심은 명확하다. Bedrock을 선택하는 이유는 세 가지다.
첫째, CloudTrail 감사. Bedrock을 통한 모든 호출은 호출자 신원, 소스 IP, 리전, 모델 ID와 함께 CloudTrail에 append-only로 기록된다. SIEM 연동이 가능한 형태로. 직접 API는 이게 없다.
둘째, SCP 수준 가드레일. IAM은 특정 역할이 무엇을 할 수 있는지를 제어하지만, SCP(Service Control Policy)는 AWS 조직 전체에서 어떤 계정이 무엇을 할 수 있는지를 제어한다. DenyBedrockOutsideApprovedRegions 정책 하나로 승인된 리전(예: us-east-1, eu-west-1) 외 모든 Bedrock 호출을 막을 수 있다. 개발자가 실수로 규정 외 리전에서 호출해도 SCP가 조직 레벨에서 차단한다.
셋째, 데이터 레지던시. 직접 API는 요청이 어느 리전에서 처리되는지 제어권이 거의 없다. Bedrock은 리전을 고정할 수 있다.
거버넌스 설계에서 팀들이 가장 자주 놓치는 두 가지가 있다. 하나는 IAM 정책에서 Resource: "*"를 Bedrock invoke 액션에 부여하는 것이다. Bedrock은 Anthropic 모델만 호스팅하지 않는다. Llama, Mistral, Nova, 마켓플레이스 모델도 있다. 와일드카드 권한은 자격증명이 유출됐을 때 폭발 반경을 조직 전체 AI 인프라로 확장한다. anthropic.claude-* ARN으로 스코프를 좁혀야 한다.
다른 하나는 모델 액세스 프로비저닝 지연이다. 신규 AWS 계정에서 Claude 모델은 기본으로 활성화되어 있지 않다. Bedrock 콘솔에서 명시적으로 요청해야 하며, 승인까지 수 시간이 걸릴 수 있다. 롤아웃 당일 이 사실을 처음 발견하면 런치가 수 시간 블로킹된다. Haiku, Sonnet, Opus를 지금 당장 쓰지 않더라도 미리 요청해두는 것이 정답이다.
비용 구조—청구서의 상한선과 실제 지불액은 다르다
토큰당 공시 요금은 최대치다. 실제 지불액은 캐시 설계와 모델 라우팅으로 결정된다.
프롬프트 캐싱이 핵심 레버다. 캐시 히트 토큰은 일반 입력 요금의 약 10%로 청구된다. CLAUDE.md에 동적 타임스탬프나 빌드 ID를 넣으면 캐시 히트율이 급락한다. 정적 접두부를 안정적으로 유지하면 긴 세션에서 유효 입력 비용을 80~90% 줄일 수 있다는 게 현장 수치다.
그런데 Ploy 팀이 Claude Opus에서 GPT-5.6으로 전환한 사례(Hacker News 경유 공개)는 이 캐시 구조가 프로바이더마다 완전히 다르게 동작한다는 걸 보여준다. Anthropic은 조직 단위 공유 캐시로 어떤 대화든 동일한 정적 접두부를 적중시키지만, GPT-5.6은 명시적 캐시 키를 요구하고 키별 처리량 제한(약 15 rpm)이 있어 전역 키 하나로는 트래픽 분산 시 콜드 캐시로 넘친다. 워크스페이스 단위 키와 계층형 breakpoint를 적용하자 첫 호출 캐시 적중률이 0%에서 83.7%로 올랐고, 초기 비용 격차(약 50% 비쌈)가 사라졌다. 모델 간 비용 비교는 캐시 구조를 동등하게 맞춘 다음에야 유효하다.
모델 라우팅도 빠른 승수다. Haiku 입력은 $0.80/M 토큰, Opus는 $15/M이다. 도입 30일 후 실제 모델 믹스를 확인해야 한다. Opus가 지배적이라면 두 가지 원인 중 하나다. CLAUDE.md가 Sonnet에게 충분한 구조를 주지 않거나, 개발자들이 수동으로 기본 모델을 오버라이딩하고 있거나.
CI에서 --max-budget-usd는 필수 가드레일이다. 파이프라인 하나에 상한이 없으면 실패한 파이프라인의 에이전트 루프가 무한 실행되며 비용을 소진한다. 루틴 작업 기준 파이프라인당 $5가 적절한 기본값이다. 같은 원칙이 자체 호스팅 에이전트에서도 작동한다. Redis에 일별 토큰 쿼터를 저장하고 초과 시 호출을 차단하는 미들웨어가 없으면, 루프 버그 하나가 시간당 수십 달러를 태운다.
프로덕션 인프라—데모와 운영 사이의 갭
로컬에서 완벽하게 동작하는 에이전트가 프로덕션에서 첫 번째 천 개 요청을 버티지 못하는 이유는 모델이 아니라 주변 인프라 때문이다. dev.to의 프로덕션 AI 에이전트 배포 가이드가 15개 이상의 에이전트 배포 경험을 바탕으로 정리한 체크리스트는 AI-First 팀에게도 그대로 적용된다.
TLS는 협상 대상이 아니다. 에이전트가 어떤 포트에서든 트래픽을 받는다면 TLS 1.3이 필요하다. 프롬프트와 응답이 평문으로 오가는 환경은 API 키 탈취뿐 아니라 프롬프트 인젝션 공격의 벡터가 된다.
인증은 컴퓨팅 예산의 방화벽이다. 멀티 테넌트 에이전트라면 스코프와 만료 시간이 내장된 HMAC 기반 토큰이 필요하다. 단일 키 유출이 수천 달러의 추론 비용으로 이어진다. 인증 실패 시도는 반드시 로깅한다.
모니터링은 업타임 체크 이상이어야 한다. 에이전트의 침묵형 장애는 표준 업타임 모니터가 감지하지 못한다. 컨텍스트 윈도우 포화, 도구 호출 타임아웃, 모델 거절은 HTTP 200을 반환하면서도 에이전트를 사실상 멈추게 한다. p95 레이턴시 10초 초과 또는 5분 윈도우에서 에러율 5% 초과에 알림을 걸어야 한다.
그리고 Ploy 사례가 추가로 보여준 인프라 이슈가 있다. 도구 스키마 설계가 에이전트 안정성을 결정한다. GPT-5.6이 선택적 매개변수 25개를 모두 그럴듯한 임의값으로 채우면서 파일 읽기의 52~64%가 빈 결과를 반환했다. 도구가 success: true를 반환하니 모델은 파일이 비어있다고 판단하고 반복 호출을 늘렸다. 해결책은 프롬프트 지시가 아니라 스키마 변환이었다. 선택 속성을 anyOf: [T, null] 형태의 필수·nullable로 바꾸고 도구 실행 전에 null을 제거하자 빈 읽기가 0%로 떨어지고 도구 호출이 30% 줄었다. 모델의 도구 호출 동작은 모델 문서가 아니라 실제 프로덕션 트레이스로 검증해야 한다.
팀 리드가 설계해야 할 실전 프레임
세 개의 소스를 엮으면 하나의 실전 프레임이 나온다.
거버넌스 레이어: SCP로 리전과 모델 범위를 조직 레벨에서 고정한다. IAM 권한 경계로 개발자가 만들 수 있는 역할의 범위를 제한한다. 인라인 정책으로 Claude Code가 실제 호출할 수 있는 모델 ARN을 최소화한다. CloudTrail로 모든 호출을 감사한다.
비용 레이어: CLAUDE.md를 정적으로 유지해 캐시 히트율을 극대화한다. CI 파이프라인마다 --max-budget-usd 상한을 설정한다. 30일 후 모델 믹스를 리뷰하고 Opus 비율이 높다면 원인을 찾는다. 모델을 전환할 때는 캐시 구조를 먼저 동등하게 맞추고 비교한다.
인프라 레이어: TLS, 만료 토큰 기반 인증, 레이트 리미팅을 기본값으로 설정한다. 프롬프트/응답 전체를 trace ID와 함께 구조화 로깅한다. 도구 스키마는 프로덕션 트레이스로 검증하고, 선택적 매개변수 처리 방식이 모델마다 다르다는 걸 가정 조건으로 둔다. 에이전트 상태는 5분 단위 스냅샷으로 보호한다.
이 세 레이어 중 하나라도 빠진 채 Claude Code를 켜는 것은, 속도를 얻는 게 아니라 비용 부채와 보안 부채를 동시에 여는 것이다. 엔터프라이즈 규모로 300명의 엔지니어에게 롤아웃한 금융 서비스 사례도 결국 이 세 축의 순서와 우선순위 문제였다. 팀 리드가 첫 번째로 설계해야 할 것은 어떤 모델을 쓸 것인가가 아니라, 그 모델 주변에 어떤 통제 구조를 둘 것인가다.