pile·
AI / ML·무신사 테크무신사 테크·

LLM 비용 64% 절감, 캐시 히트율 98% 달성기

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 실전 적용까지 코드·수치·안티패턴을 모두 담은 레퍼런스.
무신사 테크
무신사 테크 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. AI / ML·네이버 D2네이버 D2·

    [AI 해커톤 후기] 코드와 문서만 읽은 LLM은 어떻게 사람과 같은 팀을 1위로 골랐을까

    네이버가 2026년 봄 개최한 '모두의 Engineering Day' AI 해커톤에서, 25개 팀의 코드와 문서를 LLM이 자동 채점하는 'LLM as a Judge' 평가 파이프라인을 설계하고 실제 운영한 사례를 다룬다. 코드만 읽는 LLM이 사람의 판단에 가까운 결론에 도달할 수 있는지, 반복해도 안정적인 결과가 나오는지를 검증했다.

    #llm-app#llm-as-a-judge#prompt-engineering+2
  2. AI / ML·인프랩 (인프런)인프런 (인프랩)·

    학습 에이전트 — AI 두뇌 구축하기

    인프런이 강의 학습 에이전트를 구축하며 겪은 기술 스택 선정, 컨텍스트·도구 설계, LLM-as-a-Judge 품질 개선, 비용 최적화 전략을 다룬다. LLM SSE 스트리밍 처리를 위해 Spring MVC + Virtual Thread + Spring AI를 선택하고, 명시적 프롬프트 캐싱으로 입력 토큰을 90% 절감하는 과정까지 실전 경험이 담겨 있다.

    #ai-agent#llm#llm-as-a-judge+2
  3. AI / ML·네이버 D2네이버 D2·

    AI 에이전트 회사 차리기: 설립부터 어디서든 동기화까지

    네이버 ENGINEERING DAY 2026 발표. Claude Code를 매일 쓰지만 매번 초기화되는 문제를 해결하기 위해 NaverMadCat이라는 다중 AI 에이전트 조직 프레임워크를 구축한 경험을 다룬다. 비서실장 역할의 에이전트가 10개 부서 에이전트를 조율하며, 어느 환경에서 접속해도 동일한 컨텍스트로 동작하도록 동기화 메커니즘을 구현했다.

    #claude-code#multi-agent#ai-agent+2