29CM(무신사 그룹)이 AWS Bedrock 기반 LLM 비용이 지속 증가하는 원인을 메트릭 가시성 확보부터 차근차근 파악하고, Prompt Caching 도입으로 전체 LLM 청구액의 64%를 절감한 과정을 다룬다. 문제는 AWS Bedrock 콘솔이 일별 합계만 보여주고 API별 토큰 분리를 지원하지 않는다는 점이었고, 직접 메트릭 파이프라인을 구축한 뒤에야 단일 속성 추출 API가 전체 토큰의 92%를 차지한다는 사실을 발견했다.
핵심 포인트- AWS Bedrock 콘솔은 API별 토큰 분리를 지원하지 않아 비용 원인 파악이 불가능했다 — 메트릭 가시성 확보가 첫 과제였다.
- LangChain4j의 ChatModelListener로 API별 input/output/cache_read/cache_write 토큰을 Prometheus 메트릭으로 추적하는 파이프라인을 직접 구축했다.
- 속성 추출 API 단독으로 전체 토큰의 92% 차지 — 15K 토큰짜리 시스템 프롬프트를 매 호출마다 변동 없이 재전송하는 구조가 원인이었다.
- 프롬프트를 고정값(시스템 블록: 규칙·예시·JSON 스키마)과 변동값(유저 메시지 블록: 상품 데이터)으로 분리한 뒤 CachePointBlock(1시간 TTL)을 추가했다.
- 적용 1주 후 캐시 히트율 98%, 전체 LLM 비용 64% 절감 달성 — AI 비용 시뮬레이션 예측과 실측 오차 1%p 이내였다.
상세 정리- 문제 발단: LLM 비용 증가 추이 관찰 → Bedrock 콘솔은 일별 토큰 합계만 표시, API별 분리 없음 → 원인 파악 불가, 최적화 시작점 결정 불가
- 메트릭 파이프라인 설계: 서블릿 필터가 요청 경로를 ThreadLocal에 담아 태깅, ChatModelListener가 매 Bedrock 호출 완료 시 토큰 수·지연시간·에러를 llm_endpoint/llm_model/type 태그와 함께 Prometheus로 전송
- 카디널리티 폭발 방지: allowlist에 등록된 경로만 태그로 남기고 나머지는 "other"로 버킷화
- 비용 계산 분리: 코드가 아닌 Grafana 변수(토큰 단가)로 이동 — 단가 변경 시 재배포 불필요, Bedrock 콘솔 수치와 대조 가능
- 원인 발견: 대시보드 가동 직후 속성 추출 API가 전체 92% 차지 확인 — 배치 작업(매일 오전 7시~오후 2시)이 상품 최대 100개(약 2K 토큰) + 15K 고정 시스템 프롬프트를 매 호출마다 반복 전송
- AI 비용 시뮬레이션 활용: 코드베이스 호출 패턴 + Bedrock 가격표 + 실제 일일 토큰 분포를 LLM에 입력 → 옵션별 예상 절감율·우선순위·의존성 산출. 최종 금액 계산은 Grafana 실측치 × 단가로 결정론적 처리(LLM에 산술 위임 X)
- 시뮬레이션 결론: Prompt Caching 1순위 — 정확도 영향 없음, 코드 변경 최소, 고빈도+동일 프롬프트 호출 패턴이 캐싱 가격 모델과 잘 맞음
- 구현 전 준비: 프롬프트 내 고정값(규칙·예시·JSON 스키마)을 시스템 블록으로, 변동값(상품명·카테고리 ID)을 유저 메시지 블록으로 명시적 분리
- Bedrock Converse API 적용: 시스템 프롬프트 블록 뒤에 CachePointBlock(type=DEFAULT, ttl=1시간) 추가 — prefix matching으로 K,V 캐시 저장, 히트마다 TTL 1시간 갱신, 히트 없을 때만 만료
- LangChain4j 기여: 1시간 TTL 파라미터가 미지원이라 SDK 직접 호출로 우회, BedrockChatRequestParameters에 cacheTtl 추가하는 PR #4920 기여 후 main 머지 완료
- 결과: 캐시 히트율 98%(사실상 전 호출이 캐시 히트), 전체 LLM 비용 64% 절감 — 시뮬레이션 예측 대비 실측 오차 1%p 이내로 가격 모델 신뢰도 검증됨
- 추가 캐싱 패턴 정리: Tool 정의 캐싱, 대화 히스토리 캐싱, RAG 문서 캐싱, Cache Warming(병렬 발사 전 워밍 콜 1회 — Thomson Reuters Labs에서 히트율 한 자릿수 → 80%대), Relocation Trick(시스템 프롬프트 내 동적 값을 유저 메시지로 이동 — ProjectDiscovery에서 히트율 한 자릿수 → 70%대)
- 안티패턴: 시스템 프롬프트에 타임스탬프·사용자 ID 삽입 시 매 호출마다 해시가 달라져 캐시 무효화 — 증상은 에러 없이 cache_read=0으로만 확인 가능
왜 읽나AWS Bedrock(또는 Claude API)으로 고빈도 반복 LLM 호출을 운영 중인 백엔드·ML 엔지니어에게 메트릭 가시성 확보부터 Prompt Caching 실전 적용까지 코드·수치·안티패턴을 모두 담은 레퍼런스.