이미 지불한 AI 비용을 제외한 당신의 AI 청구서
요약
AI API 비용을 절감하기 위한 세 가지 캐싱 계층인 정확한 일치, 의미론적 일치, 공급자 네이티브 캐싱의 차이점과 트레이드오프를 설명합니다. 중복되는 요청과 시스템 프롬프트를 효율적으로 처리하여 비용을 최적화하는 방법을 다룹니다.
핵심 포인트
- 정확한 일치 캐싱은 비용은 낮으나 실제 적중률이 매우 낮음
- 의미론적 캐싱은 임베딩 유사도를 활용해 높은 적중률을 제공하지만 정확도 조절이 필요함
- Anthropic과 OpenAI의 네이티브 캐싱은 접두사 처리를 통해 입력 비용을 60~90% 절감함
- 효율적인 AI 운영을 위해 각 계층별 적절한 캐싱 전략 선택이 필수적임
일주일 동안 AI API 지출을 관찰하면 두 가지 사실이 명확해집니다. 첫 번째는 비용이 트래픽에 따라 선형적으로 증가한다는 것이며, 이는 누구나 예상하는 부분입니다. 두 번째는 그 트래픽의 상당 부분이 동일한 트래픽이라는 점입니다. 열 명의 서로 다른 사용자가 약간씩 다른 단어로 질문하는 동일한 고객 지원 질문, 모든 요청의 앞에 붙는 동일한 시스템 프롬프트 (System Prompt), 5분마다 크론 (cron) 작업으로 실행되는 동일한 내부 도구 쿼리 등이 이에 해당합니다. 당신은 모델이 어제 계산했던 것과 동일한 답변을 계산하는 데 대해 전체 비용을 지불하고 있는 것입니다.
캐싱 (Caching)은 AI 호출에 대해 한 번만 비용을 지불하느냐, 아니면 매번 지불하느냐의 차이를 만듭니다. 이것은 영리한 최적화가 아니라 — 최소한의 기본 사항입니다. 흥미로운 질문은 어떤 캐싱을, 어떤 트레이드오프 (tradeoffs)와 함께, 어느 계층 (layers)에서 사용할 것인가 하는 점입니다.
세 가지 계층, 세 가지 트레이드오프
단일한 "AI 캐시"란 존재하지 않습니다. 중복되지만 서로 다른 문제를 해결하는 세 가지 계층이 있습니다.
정확한 일치 (Exact match). 당신이 보내는 요청이 이전에 보낸 것과 바이트 단위로 완전히 동일하다면, 이전 응답을 반환합니다. 이는 웹에서 etag가 작동하는 방식과 같습니다. 즉각적이고, 비용이 들지 않으며, 결코 틀리지 않습니다. 문제는 실제 운영 중인 AI 트래픽에서는 거의 적중하지 않는다는 점입니다. 프롬프트 내의 다른 타임스탬프, 사용자별 이름, 또는 재정렬된 도구 목록과 같은 아주 미세한 변화만으로도 요청은 더 이상 동일하지 않게 됩니다. 실제 AI API 환경에서 정확한 일치 방식의 캐시 적중률 (Cache hit rates)은 보통 5~15% 범위에 머뭅니다.
의미론적 일치 (Semantic match). 사용자의 질문 _의미 (meaning)_가 이전 질문과 충분히 유사하다면, 이전 응답을 반환합니다. "환불 정책이 무엇인가요?"와 "어떻게 돈을 돌려받나요?"는 서로 다른 문자열이지만 동일한 질의입니다. 의미론적 캐싱 (Semantic caching)은 두 질문을 임베딩 (embedding)하고, 코사인 유사도 (cosine similarity)를 계산하며, 유사도가 특정 임계값 (threshold)을 초과할 때 캐시된 답변을 반환합니다. 이는 정확한 일치 방식의 캐시 미스 (cache misses)가 발생하는 트래픽의 30~60%를 포착합니다. 트레이드오프 (tradeoff)는 정확성입니다. 임계값이 너무 낮으면 잘못된 답변을 반환하고 (거짓 양성, false positives), 너무 높으면 실제 일치하는 항목을 놓치게 됩니다. 기본값인 0.95는 보수적인 수치이며, 대부분의 프로덕션 (production) 환경에서는 사용 사례에 따라 이를 조정하게 됩니다.
공급자 네이티브 캐시 (Provider-native cache). Anthropic의 프롬프트 캐싱 (prompt caching)과 OpenAI의 캐시된 입력 토큰 (cached input tokens)은 다른 계층에서 작동합니다. 이들은 _응답 (response)_을 캐싱하는 것이 아니라, _접두사 처리 (prefix processing)_를 캐싱합니다. 시스템 프롬프트 (system prompt)가 2,000 토큰이고 사용자 메시지가 50 토큰인 경우, 공급자는 최근 요청에서 시스템 프롬프트를 인식하여 해당 2,000 토큰을 다시 처리하는 과정을 건너뛸 수 있습니다. 출력 (output)에 대해서는 여전히 비용을 지불하지만, 캐시 적중 (cache hits) 시 입력 (input) 비용은 60~90% 감소합니다. 이는 시스템 메시지가 요청 전반에 걸쳐 안정적인 경우에 작동하며, 대부분의 프로덕션 트래픽이 이에 해당합니다.
이 세 가지 계층은 _상호 보완적 (additive)_입니다. 정확한 일치 (Exact) 방식은 지연 시간 (latency) 없이 동일한 요청을 포착합니다. 의미론적 일치 (Semantic) 방식은 거의 동일한 요청을 저렴하게 포착합니다. 공급자 네이티브 (Provider-native) 방식은 앞선 두 캐시가 모두 적중하지 않더라도 시스템 프롬프트의 오버헤드 (overhead)를 잡아냅니다. 이들을 함께 쌓아서 사용하면 종종 총 지출을 절반으로 줄일 수 있습니다.
보수적인 수학적 계산
예시를 들어보겠습니다. 고객 지원 봇을 운영한다고 가정해 봅시다. 한 달에 50,000건의 요청이 발생합니다. 평균 입력은 1,500 토큰 (시스템 프롬프트 + 검색된 컨텍스트 + 사용자 메시지)이고, 평균 출력은 300 토큰입니다. 스포츠 모드 마크업 (sport-mode markup)이 적용된 Claude Sonnet을 사용할 경우, 직접 비용은 월 약 $360이며, Prism을 통해 마크업을 적용하면 비용이 약간 더 높아집니다.
이제 캐싱을 적용해 보겠습니다:
- 정확한 일치 (Exact match): 히트율 8%. $29 절감.
- 의미적 일치 (Semantic match, 임계값 0.95): 정확한 일치에서 놓친 부분에 대해 22%의 추가 히트율 발생. $79 절감.
- 안정적인 시스템 프롬프트 접두사(system prompt prefix)에 대한 제공자 네이티브 캐시 (Provider-native cache): 모델로 전달된 나머지 70%의 트래픽에 대해 입력 토큰(input-token) 비용 약 70% 할인. $98 절감.
합계: 월 $206, 즉 57% 할인. 정확한 비율은 트래픽 구성에 따라 크게 달라지지만, 그 구조는 일관적입니다. 각 계층은 이전 계층이 남긴 빈틈을 보완하며 복리로 작용합니다.
캐싱이 역효과를 내는 경우
캐싱은 소프트웨어 분야에서 지나치게 공격적일 경우 지연 시간(latency)뿐만 아니라 답변 자체를 바꾸어 버리는 몇 안 되는 사례 중 하나입니다. 언급할 가치가 있는 세 가지 실패 모드가 있습니다.
오래된 답변 (Stale answers). 검색 인덱스(retrieval index)가 업데이트되었습니다. 고객의 계정 상태가 변경되었습니다. 사용자의 이전 질문이 현재 질문에 영향을 미칩니다. 만약 캐시 TTL(Time To Live)이 너무 길다면, 세상은 변했는데 캐시된 응답은 그대로이므로 잘못된 답변이 됩니다. 기본값인 1시간 TTL이 보수적인 데에는 이유가 있습니다. 사용자 상태(user-state)에 의존하는 모든 것은 캐시를 완전히 우회해야 합니다.
의미적 허위 양성 (Semantic false positives).
Prism은 이 세 가지 계층을 모두 쌓아 올립니다. 캐싱은 모든 티어(tier)에서 무료로 제공됩니다. 무료 계정은 기본적으로 적용되며, 유료 계정 또한 별도의 헤더 설정 없이 기본적으로 적용됩니다. 정확한 일치(Exact cache)가 가장 먼저 실행되고 (Redis SHA-256 지문 방식), 그다음 의미적 캐시(Semantic cache)가 실행되며 (fastembed BGE-small을 통한 사용자의 마지막 메시지 임베딩에 대한 Upstash Vector 코사인 유사도 방식), 마지막으로 Anthropic 또는 OpenAI로의 제공자 네이티브 캐시 패스스루(provider-native cache pass-through)가 실행됩니다. 각 계층의 히트(hit) 여부는 응답 헤더(X-Prism-Cache-Status, -Saved-Cents, -Age-Seconds, -Similarity)에 표시되므로, 어떤 계층이 무엇을 잡아냈는지 정확히 확인할 수 있습니다.
기본 설정은 보수적입니다: 1시간의 TTL(Time-to-Live), 0.95의 유사도 임계값(similarity threshold), 키 범위 지정(key-scoped, 즉 캐시는 귀하의 API 키로 네임스페이스되어 계정 간에 절대 공유되지 않음) 방식입니다. 대부분의 워크로드에는 이 설정이 적절합니다. 만약 특정 사용 사례에 맞춰 튜닝이 필요하다면 — 변동성이 큰 데이터에 대한 더 짧은 TTL, 의역이 빈번한 도메인에서의 더 낮은 임계값, 여러 키에 걸친 프로젝트 수준의 범위 설정 등 — 이러한 조절 기능은 Pro 플랜의 일부로 제공됩니다.
개발 과정에서 저를 놀라게 했던 점은 의미적 계층(semantic layer)이 제 역할을 하는 빈도가 얼마나 높은가 하는 점이었습니다. 실제적인 트래픽이 발생하는 상황에서 정확히 일치(Exact-match)하는 히트율은 한 자릿수에서 낮은 두 자릿수에 머물러 있습니다. 실제 비용 절감이 실현되는 곳은 바로 의미적 계층이며, 이 계층이야말로 반드시 튜닝해야 하는 부분입니다. 저희는 0.95를 기본값으로 설정했는데, 그보다 낮으면 즉시 사용하기에는 위험 요소가 있기 때문입니다. 운영 환경의 사용자들은 이를 모니터링하고 조정합니다. 모니터링이 가능하다는 사실 자체, 즉 모든 히트가 usage_logs에 유사도 점수를 기록한다는 점이 핵심입니다.
이것이 아닌 것
캐싱은 마법이 아니며, 적절한 모델을 선택하는 것을 대신할 수도 없습니다. 만약 Haiku로 처리할 수 있는 쿼리에 Claude Opus를 사용하고 있다면, 캐싱을 아무리 많이 해도 미스(miss) 발생 시 발생하는 20배의 비용 격차를 메울 수 없습니다. 라우팅(Routing)이 우선입니다. 캐싱은 그 아래에 있는 계층입니다. 즉, 트래픽이 반복될 때 올바른 모델 호출 비용을 더 저렴하게 만들어 주는 역할을 합니다. 브라우저 캐싱 없이 웹 앱을 출시하지 않듯이, 프롬프트 캐싱(prompt caching) 없이 AI 앱을 출시해서는 안 됩니다. 이것은 단순히 위생(hygiene)의 문제입니다.
당신이 지불해야 하는 청구서는 실제로 소비한 AI에 대한 청구서여야 합니다. 캐싱(Caching)은 그 상태에 도달하기 위해 수행하는 작업입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기