← 모든 글

LLM 비용을 절반으로 줄인 한 가지

cache_control 한 줄과 프롬프트 순서 바꾸기로 월 청구액 47% 줄인 경험담

청구서가 두 배로 나온 날

3월 말, Anthropic 청구서를 열었더니 전월 대비 2.1배였다. 기능을 새로 붙인 게 없었다. 트래픽도 비슷했다. 그런데 토큰 사용량 그래프가 계단식으로 올라가 있었다.

원인을 뒤지다 발견한 건 단순했다. 시스템 프롬프트가 API 호출마다 통째로 전송되고 있었고, 거기에 약 3,200토큰짜리 도메인 컨텍스트 블록이 들어 있었다. 하루 호출 수가 4만 건을 넘는 날부터 입력 토큰이 폭발했다. 캐시가 전혀 없었으니 당연한 결과였다.

cache_control 이 뭔지 알면서도 안 썼던 이유

솔직히 말하면, cache_control 파라미터는 릴리스 노트에서 읽은 적 있었다. “나중에 트래픽 많아지면 쓰지 뭐”라고 넘겼다. 막상 트래픽이 많아지고 나서야 부랴부랴 적용했는데, 걸린 시간은 30분도 안 됐다.

적용 방법은 단순하다. Anthropic Messages API 기준으로, 시스템 프롬프트 블록에 cache_control: {"type": "ephemeral"} 를 붙이면 끝이다. 해당 블록은 최소 1,024토큰 이상이어야 캐시 대상이 된다. 우리 컨텍스트 블록은 3,200토큰이었으니 조건을 충분히 충족했다. 적용 다음 날 입력 토큰 집계를 보니 캐시 히트율이 첫날부터 71%였다. 예상보다 높았다. 같은 세션 내 반복 호출이 많은 구조였기 때문이다.

프롬프트 순서가 비용과 관계있다는 걸 나중에 알았다

캐시 효과를 보고 나서 프롬프트 구조 자체를 다시 들여다봤다. 문제는 순서였다. 우리는 시스템 프롬프트 안에서 ‘정적 컨텍스트’와 ‘요청별 동적 값’을 섞어 쓰고 있었다. 날짜, 유저 ID, 세션 파라미터가 시스템 프롬프트 앞부분에 박혀 있었다.

AnthropicCache는 prefix 단위로 동작한다. 앞부분이 달라지면 캐시 키가 깨진다. 유저 ID가 앞에 있으면 유저마다 캐시가 새로 만들어지는 셈이다. 동적 값을 전부 뒤쪽으로 옮기고, 불변 도메인 컨텍스트를 맨 앞 블록으로 고정했다. 이것만으로 캐시 히트율이 71%에서 84%로 올랐다. 코드 변경은 프롬프트 문자열 조립 순서를 바꾼 것뿐이었고, 실제로 diff는 10줄 이내였다.

숫자로 정리하면

4월 한 달 전체를 비교했다.

  • 3월 입력 토큰: 약 4억 1천만. 4월: 약 2억 2천만. 캐시 write 토큰은 별도 과금되지만 read 단가가 90% 저렴하다. 실제 청구 기준으로는 47% 감소.
  • 캐시 히트가 높은 날은 응답 latency도 평균 210ms 줄었다. 캐시된 prefix는 재처리 없이 넘어가니 당연한 결과다.
  • 추가로 발견한 건 오류율이었다. 긴 시스템 프롬프트를 매번 처음부터 처리할 때보다 캐시 히트 상태에서 rate limit 에 걸리는 빈도가 낮아졌다. 입력 토큰 총량 자체가 줄었으니 같은 TPM 한도 안에서 여유가 생긴 것이다.

비용 이야기만 하면 반쪽이다. 캐시를 쓴다고 품질이 달라지지 않는다는 것도 확인했다. 동일 입력 기준으로 A/B를 돌려봤고, 출력 분포에 유의미한 차이는 없었다.

max_retries 는 처음부터 설정해야 한다

비용 최적화를 하면서 동시에 확인한 게 retry 로직이었다. 우리 코드는 SDK 기본값을 그냥 쓰고 있었다. Anthropic Python SDK 기본 max_retries는 2다. 문제는 retry 시 동일 프롬프트를 그대로 재전송한다는 점인데, 캐시 미스 상황에서 retry가 발생하면 입력 토큰이 두 배로 나간다.

max_retries=2를 유지하되, retry 전에 짧은 지수 백오프를 명시적으로 추가했다. 그리고 anthropic.RateLimitError 를 별도 핸들링해서 retry 루프에서 캐시 워밍 여부를 로깅하도록 바꿨다. 작은 변경이었지만, 일일 retry 발생 건수가 280건에서 60건으로 줄었다. 이것도 결국 토큰 절감이다.

다음 한 가지

이번 달 안에 프롬프트 버전을 git tag로 관리하는 루틴을 만든다. 지금은 프롬프트가 코드 안에 문자열로 박혀 있어서, 캐시 히트율 변화가 프롬프트 변경 때문인지 트래픽 패턴 때문인지 사후에 구분이 안 된다. 다음 회고에 “진짜 했나”를 한 줄 쓸 것이다.


🛒 이 글과 어울리는 추천 상품

위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.