프롬프트는 독자가 아니라 캐시를 위해 써라
프리픽스 캐싱은 반복되는 토큰을 헐값에 청구한다. 이걸 알고 나면 프롬프트 배치는 더 이상 글쓰기 문제가 아니라 시스템 문제가 된다.
3 분 읽기서울과 나트랑에서 씁니다
요즘 LLM API는 프롬프트 프리픽스의 키-값 상태를 캐시한다. 같은 앞부분 토큰을 두 번 보내면 두 번째 호출은 입력 가격의 대략 10분의 1로 청구되고 눈에 띄게 빨리 돌아온다. 이 사실 하나가 우리가 대량으로 쓰는 모든 프롬프트의 작성 방식을 다시 짜게 만들었다.
규칙
안정적인 건 전부 앞에, 호출마다 바이트까지 똑같이 둔다. 시스템 규칙, 출력 스키마, few-shot 예시, 참조 표. 변하는 건 전부 뒤로 뺀다. 작업 지시, 검색해 온 문서, 사용자 텍스트. 캐시는 처음으로 달라지는 바이트에서 깨지기 때문에, 헤더에 박힌 타임스탬프 하나가 프리픽스 전체를 오염시킨다.
[ system rules ] stable, versioned ─┐
[ output schema ] stable, versioned ├─ cached prefix, ~91% of tokens
[ 12 few-shot examples ] stable, versioned ─┘
[ retrieved context ] volatile ──────────────── paid in full
[ the actual task ] volatile
우리 추출 파이프라인 하나에서 실측한 결과
| 프롬프트 배치 | 프리픽스 재사용 | 1k 호출당 비용 | p50 지연 |
|---|---|---|---|
| 작업 먼저, 규칙 인라인, 헤더에 타임스탬프 | 0% | $31.40 | 4.1 s |
| 안정 프리픽스, 작업은 맨 뒤 | 91% | $6.90 | 1.8 s |
같은 모델, 같은 정확도인데 78% 싸고 두 배 빠르다. 문단 위치만 옮긴 diff 하나로.
운영에 따라오는 것들
- 프리픽스는 API처럼 버전을 매긴다. 프리픽스를 손대는 건 신중한 릴리스다. 편집 한 번이 캐시를 전면 플러시하고 눈에 보이는 비용 급증을 부르기 때문이다. 우리는 프롬프트에 버전 상수를 태그로 달고 스키마 마이그레이션처럼 굴린다.
- 배치 큐는 프리픽스 기준으로 정렬한다. 같은 프리픽스를 공유하는 요청을 붙여서 돌린다. 그래야 캐시가 히트 사이에 밀려나지 않고 따뜻하게 유지된다.
- 히트율은 로그로 남기는 지표다. API가 호출마다 캐시된 토큰 수를 알려주고, 우리는 그걸 그래프로 그린다. 캐시 히트율이 소리 없이 떨어진 덕에, 청구서가 알아채기 전에 실수로 들어간 프롬프트 수정을 두 번 잡았다.
- 프리픽스에서 무작위성은 금지다. 타임스탬프 금지, 요청 ID 금지, 딕셔너리 순서 룰렛 금지. 직렬화는 정규 형식으로, 키는 정렬해서. 빌드 시스템이 결정론적 입력을 원하는 것과 똑같은 이유다.
이 중 어느 것도 품질을 건드리지 않는다. 대부분의 팀이 낭비하는 줄도 모르는 자원에, 순수하게 시스템 위생을 적용한 것뿐이다.
2026년 6월 덧붙임. 이 노트가 빠뜨린 조건이 하나 있다. 캐시 요금은 프리픽스가 최소 토큰 수를 넘겨야 켜지고, 그 바닥 아래에서는 아무리 안정적인 프리픽스라도 캐시가 아예 안 걸린다. 같은 내용이라도 언어마다 토큰 수가 달라서, 번역본은 캐시되는데 영어 원문만 정가를 내는 일이 생긴다. 우리 청구서에서 그걸 찾아냈다.