← 모든 글

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

cache_control 하나로 월 토큰 비용 47% 절감한 경험 메모

문제는 프롬프트가 아니라 반복이었다

처음엔 프롬프트가 길어서 비용이 나온다고 생각했다. 그래서 시스템 프롬프트를 줄이고, 예시를 빼고, 설명을 압축했다. 효과는 미미했다. 비용 그래프는 거의 그대로였다.

막상 로그를 뜯어보니 문제는 다른 곳에 있었다. 같은 시스템 프롬프트가 매 요청마다 그대로 전송되고 있었다. 우리 서비스는 API 호출 한 번에 약 2,800 토큰짜리 시스템 프롬프트를 붙이고 있었는데, 하루 요청이 4만 건을 넘으면서 그게 전부 입력 토큰으로 청구되고 있었다. 계산하면 하루 1억 1천만 토큰 이상이 시스템 프롬프트만으로 나가고 있던 거다.

사용자 메시지 자체는 평균 200~300 토큰 수준이었으니, 전체 입력 토큰의 85% 이상이 매번 동일한 텍스트였다.

cache_control 붙이는 데 30분 걸렸다

Anthropic API 기준으로 cache_control: {"type": "ephemeral"} 를 시스템 프롬프트 블록 끝에 붙이면 그 블록이 캐싱된다. 캐시 히트 시 입력 토큰 요금은 기본 대비 10% 수준으로 떨어진다. 캐시 쓰기는 기본의 125%지만, 한 번 쓰고 수백 번 읽으면 그냥 이득이다.

실제 코드 변경은 이게 전부였다:

messages = [
    {
        "role": "system",
        "content": [
            {
                "type": "text",
                "text": SYSTEM_PROMPT,
                "cache_control": {"type": "ephemeral"}
            }
        ]
    },
    # 이하 user/assistant turns
]

배포하고 다음날 청구 대시보드를 열었을 때, cache_read_input_tokens 비율이 전체 입력의 82%였다. 월 비용은 첫 주 기준으로 직전 4주 평균 대비 47% 줄었다.

한 가지 주의할 점은 캐시 TTL이 5분이라는 것. 트래픽이 드문드문한 시간대엔 캐시가 자주 만료돼서 효과가 줄어든다. 우리는 새벽 트래픽이 거의 없어서 오전 2~6시 구간은 캐시 히트율이 20% 밑으로 떨어졌다. 그 시간대는 어차피 요청 자체가 적으니 전체 비용엔 큰 영향 없었다.

OpenAI 쪽은 별도 파라미터 없이 자동 프롬프트 캐싱이 적용된다. 단, 프롬프트 앞부분부터 동일해야 캐시가 타고, 중간에 동적 내용이 끼면 그 이후는 캐시 미스가 난다. 이 때문에 동적 컨텍스트(유저 설정값, 날짜 등)를 시스템 프롬프트 앞에 붙이는 구조면 효과가 없다. 고정 부분을 최대한 앞으로 빼고 가변 부분을 user 메시지 쪽으로 밀어야 한다.

우리가 처음에 이걸 놓친 이유가 바로 그거였다. 시스템 프롬프트 맨 앞에 현재 날짜: {today} 한 줄을 박아두고 있어서 캐시가 매일 전부 무효화되고 있었다. 그 한 줄을 user 메시지로 옮기고 나서야 캐시 히트가 안정적으로 붙었다.

프롬프트 최적화보다 구조가 먼저다

프롬프트 품질을 올리는 것과 비용을 줄이는 것은 별개 작업이다. 보통은 “프롬프트가 길면 비싸다”는 직관으로 줄이려고 하는데, 막상 해보면 품질 손실이 생기는 시점이 생각보다 빨리 온다. 예시 몇 개 빼면 출력 품질이 눈에 띄게 떨어지는 케이스가 많았다.

캐싱은 그 트레이드오프 없이 비용만 건드린다. 프롬프트 내용은 그대로 두고, 반복 청구되는 구조만 바꾼다.

덤으로 얻은 것이 하나 더 있다. 캐시가 타면 첫 번째 토큰까지 걸리는 시간(TTFT)이 눈에 띄게 줄었다. 우리 p95 기준으로 약 180ms 개선됐다. 비용이랑 레이턴시를 동시에 건드리는 변경은 흔치 않다.

정리하면:

  • 시스템 프롬프트에서 가변 내용 제거 → 앞부분 고정 유지
  • cache_control 혹은 구조적 앞쪽 고정으로 캐시 히트 확보
  • 캐시 히트율 모니터링은 배포 후 24시간 필수

다음 한 가지

캐싱 다음은 출력 토큰이다. 우리 응답 평균 길이가 실제 필요보다 30% 이상 길다는 걸 이미 알고 있다 — 다음 글 전에 max_tokens 상한과 출력 형식 지시어를 실제로 손본다.


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

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