openai prompt caching — 적용 조건과 안 될 때
OpenAI API의 prompt caching(프롬프트 캐싱)은 따로 켤 필요 없이 기본으로 동작하고, 요청의 앞부분이 이전 요청과 글자 하나까지 같고 1,024토큰 이상일 때만 걸립니다. GPT-5.6 이후 모델은 캐시에 쓸 때 입력 단가의 1.25배, 읽을 때 0.1배로 청구되고 마지막 사용 후 최소 30분 유지됩니다. 걸렸는지는 응답의 usage.input_tokens_details.cached_tokens로 확인합니다. 안 걸린다면 앞쪽에 바뀌는 값이 있는지, 그리고 고정 부분 뒤에 브레이크포인트를 두었는지부터 보세요. 아래는 2026년 10월 7일 공식 문서와 openai 파이썬 SDK 3.26.0 기준입니다.
1. openai prompt caching 동작 방식 — 앞부분이 같아야 한다
모델은 입력 토큰을 처리하면서 중간 계산 결과(KV 상태)를 만듭니다. 프롬프트 캐싱은 이 계산 결과를 앞부분(prefix) 단위로 저장해 두었다가, 다음 요청의 앞부분이 똑같으면 다시 계산하지 않고 가져다 씁니다. 그래서 비용과 응답 시작 시간이 함께 줄어듭니다.
여기서 "앞부분"은 내가 보낸 텍스트만이 아닙니다. 공식 문서 기준으로 도구 정의, developer 메시지, 이전 대화, 이미지·문서까지 모델에 들어가는 내용 전체가 하나의 앞부분입니다. 중간에 하나라도 바뀌면 그 지점부터 뒤는 캐시와 맞지 않습니다. 요청 설정 중에도 앞부분을 바꾸는 것이 있습니다.
| 설정 | 바뀌면 캐시가 깨지는 이유 |
|---|---|
model | 모델이 다르면 가중치와 캐시가 다르다 |
tools | 도구 이름·설명·스키마·순서가 앞부분에 들어간다 |
parallel_tool_calls | 병렬 호출 관련 지시가 바뀐다 |
text.format | 구조화 출력 스키마와 형식 지시가 들어간다 |
reasoning.effort · text.verbosity | 모델 쪽 지시문이 달라진다 |
context_management | 압축(compaction)이 앞선 대화를 줄인 내용으로 바꾼다 |
그래서 원칙은 하나입니다. 안 바뀌는 것(지시문·참고 자료·도구 정의)은 앞에, 바뀌는 것(사용자 질문·시각·사용자별 정보)은 뒤에 둡니다. 도구를 요청마다 빼고 넣지 말고, 못 부르게 하려면 정의는 그대로 둔 채 tool_choice: "none"이나 allowed_tools로 막으라고 문서가 권합니다.
2. GPT-5.6 전과 후 — 모델별로 규칙이 다르다
2026년 10월 현재 OpenAI 프롬프트 캐싱은 GPT-5.6 이후 모델과 그 이전 모델의 규칙이 다릅니다. 예전 글에서 본 "1,024토큰 넘으면 자동, 쓰기는 무료" 같은 설명은 이전 모델 기준이라, 지금 쓰는 모델이 어느 쪽인지 먼저 봐야 합니다.
| 항목 | GPT-5.6 이후 | 이전 모델 (GPT-5.5 등) |
|---|---|---|
| 최소 길이 | 보이는 입력 1,024토큰 | 요청 설정(도구·이미지·스키마 등)에 따라 다름 |
| 캐시 지점(브레이크포인트) | 자동(implicit) + 직접 지정(explicit) 가능 | 자동만. 일정 토큰 간격으로 잡힘 |
| 읽기 요금 | 입력 단가의 0.1배 (GPT-6.1 Sol은 0.05배) | 모델별 캐시 단가 |
| 쓰기 요금 | 입력 단가의 1.25배 | 추가 요금 없음 |
| 유지 시간 설정 | prompt_cache_options.ttl ("30m"만) | prompt_cache_retention ("in_memory"·"24h") |
prompt_cache_key | 선택. 고객별로 따로 집계할 때 | 적중률을 올리려면 고정 키 권장 |
cached_tokens 값 | 브레이크포인트까지 정확한 수 | 128의 배수로 내림 |
모델별 정확한 단가는 chatgpt api 요금 글의 요금표와 공식 가격 페이지에서 확인하세요. 이 글은 GPT-5.6 이후 모델을 중심으로 설명합니다.
3. openai prompt caching python 예제 — 브레이크포인트 직접 두기
고객센터 봇처럼 긴 규정 문서는 그대로이고 질문만 바뀌는 경우를 예로 듭니다. 규정 문서 끝에 prompt_cache_breakpoint를 달아 "여기까지 캐시해 달라"고 표시하고, prompt_cache_options의 mode를 "explicit"로 둡니다. 패키지는 pip install openai, API 키는 OPENAI_API_KEY 환경 변수에서 읽습니다(키가 없다면 chatgpt api key 발급부터 하세요).
from pathlib import Path
from openai import OpenAI
client = OpenAI()
policy = Path("support-policy.txt").read_text(encoding="utf-8") # 1,024토큰 이상인 규정 문서
def ask(question):
return client.responses.create(
model="gpt-5.6-terra",
prompt_cache_options={"mode": "explicit"}, # 내가 표시한 지점만 캐시
input=[
{
"role": "developer",
"content": [{
"type": "input_text",
"text": policy,
# 여기까지가 매번 같은 앞부분
"prompt_cache_breakpoint": {"mode": "explicit"},
}],
},
{"role": "user", "content": question}, # 매번 바뀌는 부분
],
)
for q in ["환불은 며칠 안에 되나요?", "배송지는 어떻게 바꾸나요?"]:
r = ask(q)
d = r.usage.input_tokens_details
print(r.usage.input_tokens, d.cached_tokens, d.cache_write_tokens)
SDK 3.26.0으로 실제 요청 본문을 가로채 보면 위 코드는 키 이름과 위치가 그대로 나갑니다. 첫 요청은 규정 문서를 캐시에 쓰므로 cache_write_tokens가 차고, 같은 문서로 보낸 두 번째 요청부터 cached_tokens가 찹니다. 규정 문서가 2,000토큰, 질문이 100토큰이라면 출력은 이런 모양입니다(숫자는 설명용 예시이고, 실제 값은 내 문서 길이에 따라 다릅니다).
2100 0 2000 # 1회째: 2,000토큰을 캐시에 씀
2100 2000 0 # 2회째: 2,000토큰을 캐시에서 읽음
알아 둘 규칙이 몇 가지 있습니다.
- explicit 모드인데 브레이크포인트가 하나도 없으면 캐싱을 아예 안 합니다. 캐시 쓰기도 생기지 않습니다.
- 브레이크포인트 뒤의 내용(위의 질문)은 캐시 쓰기 요금 없이 일반 입력 단가로 청구됩니다. 다시 쓸 일 없는 내용을 캐시에 쓰느라 1.25배를 내지 않게 하는 게 explicit 모드의 장점입니다.
- 한 요청에서 캐시 쓰기는 최대 4곳입니다. implicit 모드에서 자동 지점이 하나를 쓰므로 직접 지정할 수 있는 곳은 3개가 남습니다.
- 최상위
instructions에는 브레이크포인트를 넣을 수 없습니다. 위 예제처럼 developer 메시지의input_text블록에 넣습니다. - Chat Completions API도 SDK 3.26.0에
prompt_cache_options가 있고,{"type": "text"}콘텐츠 파트에prompt_cache_breakpoint를 달 수 있습니다.
4. 캐시 적중 확인과 비용 계산
캐시가 걸렸는지는 응답의 usage에서 봅니다. API마다 필드 이름이 다릅니다.
| API | 캐시에서 읽은 토큰 | 캐시에 쓴 토큰 |
|---|---|---|
| Responses | usage.input_tokens_details.cached_tokens | usage.input_tokens_details.cache_write_tokens |
| Chat Completions | usage.prompt_tokens_details.cached_tokens | usage.prompt_tokens_details.cache_write_tokens |
입력 비용은 공식 가이드의 계산식을 그대로 쓰면 됩니다. 일반 입력은 1배, 캐시 읽기는 0.1배, 캐시 쓰기는 1.25배로 가중해 더합니다.
def calculate_input_cost(usage, input_price_per_million,
cache_input_multiplier=0.1, cache_write_multiplier=1.25):
input_tokens = usage.input_tokens
cached_tokens = usage.input_tokens_details.cached_tokens
cache_write_tokens = usage.input_tokens_details.cache_write_tokens
ordinary_input_tokens = input_tokens - cached_tokens - cache_write_tokens
weighted_input_tokens = (
ordinary_input_tokens
+ cached_tokens * cache_input_multiplier
+ cache_write_tokens * cache_write_multiplier
)
return weighted_input_tokens * input_price_per_million / 1_000_000
위 예제(규정 2,000토큰 + 질문 100토큰)를 gpt-5.6-terra(표준 입력 100만 토큰당 $2.00, 2026년 10월 7일 요금표)로 10번 보낸다고 하고 이 함수로 계산해 봤습니다.
| 방식 | 계산 | 입력 비용 (10회) |
|---|---|---|
| 캐시 없음 | 2,100 × 10 | $0.0420 |
| 규정 뒤 브레이크포인트 (explicit) | 1회째 2,000×1.25 + 100 이후 9회 2,000×0.1 + 100 | $0.0106 (약 75% 절감) |
| 질문까지 매번 캐시에 씀 (아래 6-③) | 2,100×1.25 × 10 | $0.0525 (오히려 25% 더 비쌈) |
세 번째 줄이 이 글에서 가장 중요한 부분입니다. 캐시 쓰기가 유료가 된 GPT-5.6 이후로는 캐시 지점을 잘못 잡으면 캐싱이 비용을 늘립니다. 그래서 cached_tokens만 보지 말고 cache_write_tokens가 매번 차는지도 같이 봐야 합니다.
공식 가이드는 짧은 고정 부분을 쓸모 있는 지시·예시로 늘려 최소 길이를 넘기는 쪽이 더 쌀 수 있다고 계산해 둡니다. 읽기 0.1배·쓰기 1.25배 기준으로 10번 재사용하면 원래 221토큰 이상인 앞부분은 1,024토큰으로 늘리는 게 이득입니다. 다만 늘린 내용 때문에 답이 달라지지 않는지는 따로 확인해야 합니다.
5. openai prompt caching ttl — 얼마나 유지되나
GPT-5.6 이후는 prompt_cache_options.ttl로 정하는데, 지원하는 값은 "30m" 하나이고 그게 기본값입니다. 캐시는 마지막으로 쓰거나 읽은 뒤 최소 30분 살아 있고, OpenAI가 더 오래 둘 수도 있습니다. 다시 읽으면 수명이 연장되는데, 이때 캐시 쓰기 요금은 다시 붙지 않습니다.
이전 모델은 prompt_cache_retention을 씁니다.
"in_memory"— 쓰지 않은 채로 보통 5분에서 10분, 길어야 1시간"24h"— 보통 30분 안팎, 최대 24시간까지 유지.gpt-5.5·gpt-5.5-pro는 이 값만 지원- 둘 다 되는 모델에서 값을 안 주면, Zero Data Retention을 켠 조직은
in_memory, 안 켠 조직은24h가 기본
SDK 3.26.0 코드에는 prompt_cache_retention이 Deprecated, prompt_cache_options.ttl을 쓰라고 적혀 있습니다. GPT-5.6 이후로 옮긴다면 이 값을 ttl로 바꾸세요. 참고로 SDK는 ttl에 "1h" 같은 값을 넣어도 막지 않고 그대로 보냅니다. 지원 값인지는 서버가 판단하니 문서에 있는 값만 쓰는 게 안전합니다. 캐시를 직접 지우는 방법은 없고, 시간이 지나면 만료됩니다.
6. openai prompt caching not working — 안 될 때 확인할 것
cached_tokens가 계속 0이거나 기대보다 작다면 아래 순서로 봅니다.
① 앞부분이 최소 길이보다 짧다
GPT-5.6 이후는 1,024토큰입니다. OpenAI가 내부적으로 붙이는 숨은 시스템 내용은 이 숫자에 들어가지 않으니, 내가 보낸 고정 부분만으로 넘어야 합니다. 모델을 바꿨다면 최소 길이도 다시 확인하세요. 이전 모델은 도구·이미지·스키마에 따라 기준이 달라집니다.
② 앞쪽에 매번 바뀌는 값이 있다
developer 메시지 맨 앞의 현재 시각, 요청 ID, 사용자 이름 하나 때문에 그 뒤 전체가 캐시와 어긋납니다. 이런 값은 뒤쪽 메시지로 옮깁니다. 대화형 앱이라면 이전 대화를 요약하거나 고쳐 쓰지 말고 새 메시지를 뒤에 붙이기만 해야 앞부분이 유지됩니다.
③ 자동(implicit) 모드라 질문까지 한 덩어리로 캐시됐다
GPT-5.6 이후의 자동 모드는 캐시 지점을 가장 마지막 user 메시지 끝에 둡니다. 고정 규정 + 매번 다른 질문 구조라면, 첫 요청은 질문까지 포함해 캐시에 쓰고 다음 요청은 질문이 달라 그 캐시와 맞지 않습니다. 고정 부분 끝에는 따로 저장된 지점이 없으니 공유하는 앞부분도 못 씁니다. 공식 문서가 "공유하는 앞부분이 곧 캐시된 앞부분은 아니다"라는 함정으로 따로 적어 둔 경우로, 이전 모델에서 옮겨 왔을 때 특히 자주 생긴다고 합니다. 해결은 3절처럼 고정 부분 끝에 prompt_cache_breakpoint를 다는 것입니다.
④ explicit 모드로 바꿨더니 이전 캐시를 못 쓴다
explicit 모드는 내가 표시한 지점에서만 캐시를 찾습니다. 앞 요청이 자동 모드로 캐시한 지점과 겹치는 표시가 없으면 못 읽습니다. 또 같은 메시지 뒤에 내용을 덧붙여 늘리면 예전 끝 지점이 메시지 한가운데가 되어 재사용이 안 됩니다. 덧붙이지 말고 새 메시지로 추가하세요. 처음 이어진 developer 메시지 묶음 뒤에 나오는 developer 메시지도 자동으로는 검색 지점이 안 되니, 재사용하려면 브레이크포인트를 답니다.
⑤ 도구·설정이 요청마다 다르다
1절 표의 설정이 바뀌었는지 봅니다. 특히 도구 목록을 요청마다 다르게 만들거나 순서를 바꾸는 코드가 흔한 원인입니다.
⑥ 시간이 지났다 / 요청이 몰렸다
30분(이전 모델 in_memory는 5분에서 10분) 넘게 쉬면 만료됩니다. 이전 모델은 같은 앞부분 요청이 분당 15건을 넘으면 다른 서버로 넘쳐 캐시가 있는 서버에 못 갈 수 있어, 공식 문서가 고정 prompt_cache_key를 쓰고 트래픽이 많으면 키를 여러 개로 나누라고 권합니다. GPT-5.6 이후는 라우팅을 OpenAI가 알아서 하므로 키가 적중률에 필요하지 않고, 고객별로 캐시 사용량을 따로 집계하고 싶을 때만 씁니다(다른 사용자의 캐시 적중 여부를 떠보는 것도 막아 줍니다).
원인을 모르겠으면 캐시 진단을 켠다
GPT-5.6 이후 모델의 Responses API에는 두 요청을 비교해 캐시가 왜 안 맞았는지 알려 주는 진단이 있습니다. 앞 요청의 응답 id를 prompt_cache_options.comparison_response_id에 넣으면, 응답의 prompt_cache_diagnostics에 결과가 옵니다.
first = ask("환불은 며칠 안에 되나요?")
second = client.responses.create(
model="gpt-5.6-terra",
input=[...], # 비교할 요청
prompt_cache_options={"comparison_response_id": first.id},
)
diag = second.prompt_cache_diagnostics
if diag is not None and diag.type == "cache_miss":
print(diag.reason, diag.cache_missed_tokens) # 예: tools_changed 2000
reason에는 model_changed, tools_changed, text_format_changed, reasoning_effort_changed, verbosity_changed, context_compacted, input_changed(시각·요청 ID가 들어갔거나 이전 메시지를 고친 경우) 같은 값이 옵니다. 진단을 켜도 캐시 동작 자체는 바뀌지 않습니다. 전체 적중률은 OpenAI 대시보드의 Prompt Caching 화면에서 봅니다.
자주 묻는 질문 (FAQ)
Q. 캐시가 걸리면 같은 질문에 같은 답이 나오나요?
아닙니다. 캐시는 입력 처리 결과를 재사용할 뿐이고 답은 매번 새로 생성합니다. 공식 문서도 같은 요청이 같은 출력을 보장하지 않는다고 적어 둡니다.
Q. 캐시된 토큰은 속도 제한(TPM)에서 빠지나요?
빠지지 않습니다. 캐시된 입력 토큰도 분당 토큰 한도에 그대로 들어갑니다. 한도에 걸려 429가 난다면 openai api 429 에러 글에서 원인을 가려 보세요.
Q. 구조화 출력 스키마나 도구 정의도 캐시되나요?
됩니다. 둘 다 앞부분에 들어가기 때문에 요청마다 같게 유지하면 캐시되고, 조금이라도 바꾸면 그 지점부터 깨집니다. 스키마 쓰는 법은 chatgpt api json 출력, 도구 정의는 openai function calling 예제 글에 있습니다.
Q. 클로드·제미나이 캐싱과 뭐가 다른가요?
"같은 앞부분을 싸게 재사용한다"는 원리는 같고, 켜는 방식이 다릅니다. 클로드는 요청에 cache_control을 직접 넣어야 하고(프롬프트 캐싱 클로드), 제미나이는 자동 캐싱과 캐시를 따로 만들어 쓰는 방식이 나뉩니다(gemini 컨텍스트 캐싱). OpenAI는 기본으로 켜져 있고, GPT-5.6 이후부터 브레이크포인트로 위치를 고를 수 있습니다.
마무리
정리하면 openai prompt caching은 기본으로 켜져 있지만, 고정 부분을 앞에 두고 1,024토큰을 넘겨야 걸립니다. GPT-5.6 이후로는 캐시 쓰기가 1.25배 유료라서, 고정 부분 끝에 prompt_cache_breakpoint를 달아 다시 쓸 부분만 캐시에 쓰게 하는 게 핵심입니다. 확인은 cached_tokens와 cache_write_tokens를 같이 보고, 원인을 모르겠으면 comparison_response_id로 진단을 받아 보세요.
📚 참고 출처 (2026년 10월 7일 확인 · openai 파이썬 SDK 3.26.0)
· Prompt caching — OpenAI API
· Prompt cache diagnostics — OpenAI API
· Pricing — OpenAI API
· Create a model response — OpenAI API Reference

COMMENTS