프롬프트 캐싱 운영법: OpenAI·Claude API 비용을 줄이는 prefix 설계
프롬프트 캐싱은 LLM API 비용을 줄이는 좋은 방법이지만, “켜면 자동으로 싸진다”는 식으로 이해하면 실패한다. 캐시는 같은 prefix가 반복될 때 효과가 난다. 프롬프트 앞부분이 매번 달라지면 캐시는 거의 맞지 않는다. 개발자가 해야 할 일은 캐시 옵션을 켜는 것이 아니라, 캐시가 맞을 수밖에 없는 입력 구조를 만드는 것이다.
OpenAI prompt caching 문서는 cache hit가 정확한 prefix match에서 가능하다고 설명한다. 정적인 지시문과 예시는 앞에 두고, 사용자별 정보처럼 바뀌는 값은 뒤에 두는 것이 핵심이다. Anthropic prompt caching 문서는 자동 caching과 명시적 cache breakpoint를 제공하며, 반복 작업에서 비용과 지연시간을 줄이는 용도로 안내한다. 실무에서는 이 원칙을 코드 구조와 로그 설계로 옮겨야 한다.
캐시가 잘 맞는 프롬프트 구조
캐시가 잘 맞는 구조는 대체로 다음 순서를 따른다.
- 고정 시스템 지시문
- 고정 출력 형식과 금지사항
- 고정 예시 또는 few-shot 샘플
- 고정 도구 스키마 또는 문서 묶음
- 사용자별 입력
- 이번 요청에서만 쓰는 옵션
핵심은 1~4번이 가능한 한 오래 유지되는 것이다. 사용자 ID, 현재 시간, 실험군 이름, 요청 ID 같은 값이 1번 앞에 들어가면 prefix가 매번 달라진다. 그러면 긴 시스템 프롬프트를 아무리 재사용해도 캐시 히트가 낮아진다.
예를 들어 고객 지원 챗봇에서 모든 요청에 다음 정보를 넣는다고 하자. “현재 시간, 고객 이름, 고객 플랜, 최근 결제 상태, 공통 정책, FAQ 문서, 사용자 질문.” 이 순서라면 현재 시간과 고객 정보 때문에 앞부분이 계속 바뀐다. 더 나은 순서는 “공통 정책, FAQ 문서, 답변 규칙, 고객 정보, 사용자 질문”이다. 공통 문서가 prefix에 놓이면 캐시 가능성이 올라간다.
캐시가 안 맞는 흔한 원인
첫 번째 원인은 timestamp다. 디버깅을 위해 현재 시각을 프롬프트 맨 위에 넣는 팀이 많다. 모델에게 시간이 꼭 필요하다면 뒤쪽에 넣거나, 날짜만 넣는다. 초 단위 timestamp는 캐시를 깨는 대표적인 값이다.
두 번째 원인은 검색 결과 순서다. RAG 검색 결과가 매번 조금씩 다른 순서로 들어가면 prefix가 달라진다. 같은 문서 집합이라도 정렬 기준이 흔들리면 캐시가 깨진다. 점수, 문서 ID, 업데이트 날짜 같은 안정적인 기준으로 정렬해야 한다.
세 번째 원인은 프롬프트 버전 관리 부재다. 기능별로 시스템 프롬프트를 복사해서 조금씩 고치면 캐시도 분산된다. 공통 규칙은 모듈로 빼고, 기능별 차이는 뒤쪽 옵션으로 둔다. 프롬프트 변경은 코드 리뷰와 테스트를 거쳐 배포해야 한다.
네 번째 원인은 너무 작은 prefix다. OpenAI 문서 기준 자동 caching은 일정 토큰 길이 이상에서 동작한다. 매우 짧은 프롬프트는 캐시 절감 효과가 작다. 캐시는 긴 공통 지시문, 긴 도구 스키마, 반복 문서가 있을 때 특히 유리하다.
OpenAI API에서 볼 지표
OpenAI 문서는 cached_tokens, cache_write_tokens 같은 사용량 필드를 통해 cache write와 read를 측정할 수 있다고 설명한다. 운영에서는 이 값을 기능별로 저장해야 한다. 단순히 전체 cached_tokens 합계만 보면 안 된다. 어떤 기능이 캐시를 잘 쓰고, 어떤 기능이 계속 miss를 내는지 알아야 한다.
추천 지표는 다음과 같다.
- cache hit token ratio = cached_tokens / input_tokens
- cache write token ratio = cache_write_tokens / input_tokens
- 기능별 평균 cached_tokens
- 모델별 cache hit ratio
- 배포 버전별 cache hit ratio
- 캐시 적용 전후 p95 latency
캐시의 목적은 비용 절감만이 아니다. 긴 prefix를 다시 처리하지 않으면 지연시간도 줄어들 수 있다. 따라서 비용 그래프와 latency 그래프를 같이 봐야 한다. 캐시 히트율이 높아졌는데 지연시간이 그대로라면 병목이 다른 곳에 있을 수 있다.
Claude API에서 볼 지표
Anthropic 문서는 automatic caching과 explicit cache breakpoints를 제공한다. 자동 caching은 멀티턴 대화에서 성장하는 메시지 기록을 캐시하는 데 편하고, explicit breakpoint는 어떤 content block까지 캐시할지 개발자가 제어할 수 있다. 긴 문서 분석, 반복되는 도구 스키마, 긴 정책 문서에는 명시적 breakpoint가 더 예측 가능하다.
운영에서는 cache_creation_input_tokens, cache_read_input_tokens처럼 캐시 생성과 읽기 토큰을 분리해 본다. 캐시 생성이 많고 읽기가 적다면 매번 새 prefix를 쓰고 있다는 뜻이다. 읽기가 많다면 반복 요청에서 비용을 줄이고 있을 가능성이 크다.
TTL도 고려해야 한다. Anthropic 문서는 5분 또는 1시간 TTL 같은 옵션을 설명한다. 사용자가 같은 문서에 대해 몇 분 안에 여러 질문을 하는 제품이라면 짧은 TTL도 충분하다. 사내 업무 도구처럼 하루 종일 같은 지식베이스를 반복한다면 더 긴 TTL 구조를 검토할 수 있다.
제품별 캐시 설계 예시
문서 Q&A 제품에서는 문서 본문을 먼저 전처리한다. 원문 전체를 매번 넣지 말고, 문서별 핵심 섹션과 메타데이터를 안정적인 순서로 구성한다. 사용자가 같은 문서에서 질문을 이어갈 때 이 문서 prefix가 재사용되도록 만든다.
코딩 에이전트에서는 도구 스키마와 작업 규칙이 길다. 이 부분은 prefix로 고정한다. 반면 현재 에러 로그, 변경 대상 파일, 사용자 요청은 뒤에 둔다. 에이전트가 매번 전체 레포 요약을 다시 읽는 구조라면 캐시보다 컨텍스트 설계가 먼저다.
고객 지원 챗봇에서는 정책 문서와 답변 규칙을 앞에 두고, 고객 정보와 질문을 뒤에 둔다. 검색 결과는 문서 ID 기준으로 안정 정렬한다. 검색 점수가 근소하게 바뀌어 순서가 흔들리는 경우에는 상위 문서 ID를 정렬해 prefix 안정성을 높일 수 있다.
캐시가 손해가 되는 경우도 있다
캐시가 항상 이득은 아니다. 공통 prefix가 거의 없고 사용자 입력이 대부분인 서비스에서는 히트율이 낮다. 캐시 쓰기 비용이 있는 모델에서는 miss가 반복되면 비용이 늘 수 있다. 또한 민감 데이터가 포함된 prefix를 캐시할 때는 벤더의 데이터 보관 정책, Zero Data Retention 적용 여부, 조직의 보안 요구사항을 확인해야 한다.
따라서 캐시는 기능별로 실험해야 한다. 1주일 정도 A/B로 cache hit ratio, 비용, p95 latency, 오류율을 비교한다. 캐시를 켠 버전이 비용을 줄이지 못하면 프롬프트 구조를 다시 보거나 기능에서 제외한다.
실행 체크리스트
- 프롬프트를 고정 prefix와 요청별 변수로 나눈다.
- timestamp, request_id, user_id를 프롬프트 앞부분에 넣지 않는다.
- RAG 검색 결과는 안정적인 기준으로 정렬한다.
- 공통 시스템 프롬프트와 도구 스키마는 코드 모듈로 관리한다.
- OpenAI는 cached_tokens와 cache_write_tokens를 기능별로 저장한다.
- Claude는 cache creation/read 토큰과 TTL 선택을 함께 기록한다.
- 캐시 히트율, 비용, p95 latency를 배포 버전별로 비교한다.
- 민감 데이터가 들어간 prefix는 벤더의 데이터 보관 정책을 확인한 뒤 캐시한다.
- 출처: OpenAI prompt caching 문서, Anthropic prompt caching 문서.