LLM 비용 64% 절감! Prompt Caching 도입기
LLM 비용 증가 추세 속에서 API별 토큰 사용량 가시성 확보가 비용 절감의 첫걸음임을 강조함
속성 추출 API가 전체 토큰의 92%를 차지하는 원인으로 동일 시스템 프롬프트 반복 호출을 지목함
AI 기반 비용 시뮬레이션으로 Prompt Caching을 1순위 최적화 옵션으로 선정함
시스템 프롬프트와 메시지 프롬프트 분리 후 Prompt Caching 도입으로 캐시 히트율 98% 달성
최종적으로 LLM 비용 64% 절감 및 향후 최적화 방향 제시
메트릭 가시성 확보를 위한 LLM 호출 추적 아키텍처
본문에서는 LLM 비용 최적화의 첫 단계로 API별 토큰 사용량 메트릭 수집 파이프라인 구축을 강조하고 있습니다. AWS Bedrock 콘솔의 집계 정보만으로는 비용 발생 원인 파악이 어렵기 때문에, LangChain4j의 `ChatModelListener`와 서블릿 필터(Servlet Filter)를 활용하여 다음과 같은 정보를 추적합니다.
API별 토큰 사용량: `input`, `output`, `cache_read`, `cache_write` 타입별 토큰 수 기록
요청 메트릭: API별 요청 수, 응답 시간, 에러 수 집계
경로 태깅: 서블릿 필터로 요청 경로를 태깅하고, Prometheus 카디널리티(Cardinality) 문제를 방지하기 위해 `allowlist` 기반 버킷화 적용
이렇게 수집된 메트릭은 Grafana 대시보드로 시각화되어, 비용 발생의 근본 원인 분석을 가능하게 합니다. 특히, 토큰 단가 정보를 Grafana 변수로 관리하여 재배포 없이 유연하게 비용을 계산하는 점이 주목할 만합니다.
Prompt Caching 도입을 위한 프롬프트 구조 분리 전략
Prompt Caching의 효과를 극대화하기 위해, 고정값(규칙, 지시문, 예시 등)과 변동값(상품 데이터, 사용자 입력 등)을 명확히 분리하는 프롬프트 구조화 작업이 선행되었습니다. 이는 캐시의 Prefix Matching 방식에 필수적인 조건으로, 고정값은 시스템 프롬프트(System Prompt)에, 변동값은 메시지 프롬프트(Message Prompt)에 배치하는 방식으로 진행되었습니다.
시스템 프롬프트: 호출마다 동일한 규칙, 예시, 스키마 등을 포함하여 캐시 가능한 영역으로 구성
메시지 프롬프트: 상품명, 카테고리 ID 등 매번 변경되는 동적 데이터를 포함하여 캐시 대상에서 제외
이러한 구조 분리를 통해, 동일한 시스템 프롬프트에 대한 반복적인 LLM 호출 시 캐시 히트율(Cache Hit Rate)을 획기적으로 높일 수 있었습니다. 이는 LangChain4j의 `CachePointBlock`과 `ttl` 설정을 통해 구현되었으며, 1시간 TTL(Time-To-Live)은 배치 작업 패턴을 고려한 결정입니다.
AI 기반 비용 시뮬레이션으로 최적화 옵션 우선순위 결정
LLM 비용 최적화 옵션(Prompt Caching, 모델 다운사이즈, Batch API 전환 등)을 결정하기 위해, AI 기반 비용 시뮬레이션 방법론을 도입했습니다. 코드베이스에서 추출한 호출 패턴, Bedrock 모델별 가격표, 실제 토큰 분포 데이터를 입력으로 사용하여 각 옵션의 예상 절감율과 적용 우선순위를 도출했습니다.
시뮬레이션 입력: 호출 패턴, 모델 가격표, 일일 토큰 분포
시뮬레이션 출력: 옵션별 예상 절감율, 적용 우선순위 추천, 옵션 간 의존성 분석
이 시뮬레이션 결과, Prompt Caching이 정확도 영향이 적고 코드 변경량이 작으며, 기존 호출 패턴과 잘 맞아떨어져 1순위로 선정되었습니다. 이 방법론은 직관에 의존하는 대신 데이터 기반의 의사결정을 가능하게 하며, 향후 실측 결과와 비교하여 가격 모델의 신뢰성을 검증하는 도구로도 활용될 수 있습니다.
Prompt Caching의 효과적인 적용 및 안티패턴 분석
29CM는 시스템 프롬프트 캐싱 패턴을 단독으로 적용하여 캐시 히트율 98%를 달성했습니다. 이는 동일 시스템 프롬프트에 대한 고빈도 호출 패턴이 Prompt Caching의 가격 모델과 잘 부합했기 때문입니다. 또한, LangChain4j 라이브러리의 TTL 파라미터 부재 문제를 해결하기 위해 SDK 직접 호출 및 PR 기여를 통해 1시간 TTL을 적용하는 등 적극적인 기여를 수행했습니다.
반면, Prompt Caching의 효과를 저해하는 안티패턴(Anti-pattern)으로는 시스템 프롬프트에 타임스탬프나 사용자 ID 삽입, JSON 직렬화 시 키 순서 비일관성, 병렬 요청 동시 발사 등이 지적되었습니다. 이러한 안티패턴은 변경 빈도가 낮은 요소를 프롬프트 앞단에 배치하는 원칙을 위반하여 캐시 무효화를 유발합니다. 따라서 캐시의 동작 여부를 지속적으로 모니터링하는 것이 중요합니다.
LLM 비용 최적화의 누적 가능한 레버와 향후 과제
이번 Prompt Caching 적용은 LLM 비용 최적화의 첫 번째 단계이며, 향후 모델 다운사이즈, Batch API 전환, 추론 최적화(Paged Attention 등)와 같은 추가적인 최적화 레버가 남아있습니다. 각 단계는 독립적이면서도 효과가 누적되어, 모든 단계를 적용할 경우 90% 이상의 비용 절감이 가능할 것으로 예상됩니다.
핵심은 가시성 확보를 기반으로 Prompt Caching을 적용하고, 이를 통해 확보된 메트릭을 활용하여 다음 단계의 최적화를 검증해 나가는 것입니다. LLM 비용 최적화는 단발성 작업이 아니라 지속적인 모니터링과 개선이 필요한 과정임을 시사합니다. 특히, 데이터 미저장 정책(Zero-Retention Policy)과 같은 보안 고려사항도 함께 검토되어야 합니다.