Prompt Caching์ โ๋ชจ๋ธ์ ๋ฐ๊พธ๋ฉด ๋นจ๋ผ์ง๋คโ๋ณด๋ค ๋ ๋จผ์ ๋ด์ผ ํ๋ ์ด์ ๋ ๋ฒ์ ๋๋ค. ํนํ ๋ฐ๋ณต ์์ ์ด ๋ง์ ํ์์๋ ํ๋กฌํํธ์ ๊ณตํต ์๋ถ๋ถ(prefix)์ ์ผ๋ง๋ ์์ ์ ์ผ๋ก ์ฌ์ฌ์ฉํ๋๋๊ฐ ์ง์ฐ์๊ฐ๊ณผ ์ ๋ ฅ๋น์ฉ์ ์ง์ ์ํฅ์ ์ค๋๋ค.
OpenAI ๊ณต์ ๊ฐ์ด๋ ๊ธฐ์ค์ผ๋ก ์บ์ฑ์ ์๋์ผ๋ก ๋์ํ์ง๋ง(์กฐ๊ฑด ์ถฉ์กฑ ์), prefix ์ค๊ณยทkey ์ ๋ตยท์ธก์ ๋ฃจํ๋ฅผ ํจ๊ป ์ด์ํด์ผ ์ค์ ์ฑ๋ฅ ์ด๋์ด ์ปค์ง๋๋ค.
์๋ด: ์ด ๋ฌธ์๋ ์์ฑํ AI๋ฅผ ํ์ฉํด ์ด์์ ์์ฑํ๊ณ , ๊ณต๊ฐ๋ ๊ณต์ ์๋ฃ๋ฅผ ๋ฐํ์ผ๋ก ์ฌ๋์ด ๊ฒํ ยท๋ณด์ ํ์ต๋๋ค.
์ด ๊ธ์ ๊ทผ๊ฑฐ ์๋ฃ
- Prompt Caching ๊ณต์ ๊ฐ์ด๋
prompt_cache_keyAPI ๋ ํผ๋ฐ์ค- Responses object (
usage.prompt_tokens_details.cached_tokens) - API Pricing
ํต์ฌ ์์ฝ
- ์บ์ ํํธ๋ ์ ํํ ๊ฐ์ prefix์์๋ง ๋ฐ์ํ๋ค.
- 1024 ํ ํฐ ์ด์ ์์ฒญ๋ถํฐ ์บ์ฑ ํจ๊ณผ๊ฐ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋ํ๋๋ค.
- ํต์ฌ ์ด์์ถ์
prefix ๊ณ ์ ,prompt_cache_key ๋ถ๋ฆฌ,cached_tokens ๊ธฐ๋ฐ ์ธก์ ์ด๋ค. - ํธ๋ํฝ์ด ํ ํค/ํ๋ฆฌํฝ์ค ์กฐํฉ์ผ๋ก ๋ชฐ๋ฆฌ๋ฉด(๊ฐ์ด๋์ ์ฝ 15rpm ์ธ๊ธ) ์บ์ ํจ์จ์ด ๋จ์ด์ง ์ ์๋ค.
flowchart LR A["์์ฒญ ์ ๋ ฅ"] --> B["๊ณ ์ Prefix ์ ๋ ฌ"] B --> C["prompt_cache_key ์ ์ฉ"] C --> D["๋ณด์กด ์ ์ฑ ์ ํ\n(in_memory / 24h)"] D --> E["์บ์ ํํธ ์ธก์ \n(cached_tokens)"] E --> F["ํ ํ๋ฆฟ/ํค ํ๋"] F --> B
์๊ฐํ (Excalidraw)
Agent/OpenAI ๋น์ฆ๋์ค ํ์ฉ/images/openai-biz-15-cache-routing.png
- ์๋ณธ ํธ์ง ํ์ผ:
Agent/OpenAI ๋น์ฆ๋์ค ํ์ฉ/images/openai-biz-15-cache-routing.excalidraw
๐ง ์น ํ ์นํธ์ํธ
- ๊ณ ์ ๊ท์น/์์/ํด์ ์, ์ฌ์ฉ์ ๋ณ๋๊ฐ์ ๋ค
prompt_cache_key๋ ์ํฌํ๋ก์ฐ ๋จ์๋ก ๋ถ๋ฆฌcached_tokens๋ฅผ ์ฃผ๊ฐ ์งํ๋ก ์ ๋ณด๋ฉด ์ต์ ํ๊ฐ ์๋๋ผ ๊ฐ ์ด์- ์บ์ ๋ณด์กด์ ์ฑ ์ ์ฑ๋ฅ๋ฟ ์๋๋ผ ๋ฐ์ดํฐ ์ ์ฑ ๋งฅ๋ฝ๊น์ง ๊ฐ์ด ๋ณธ๋ค
๊ณต์ ๋ฌธ์ ๊ธฐ์ค์ผ๋ก ๊ผญ ์์์ผ ํ 5๊ฐ์ง
1) ์บ์๋ ์๋์ด์ง๋ง, ์ฑ๋ฅ์ ์๋์ด ์๋๋ค
๊ณต์ ๊ฐ์ด๋์ฒ๋ผ Prompt Caching์ ๋ณ๋ ์ถ๊ฐ ๊ณผ๊ธ ์์ด ์๋ ๋์ํฉ๋๋ค. ํ์ง๋ง โ์๋โ์ ์ต์ ํ๊น์ง ์๋์ด๋ผ๋ ๋ป์ด ์๋๋๋ค. prefix๊ฐ ํ๋ค๋ฆฌ๋ฉด ์บ์ ํํธ์จ์ ๋ฐ๋ก ๋จ์ด์ง๋๋ค.
์ฐธ๊ณ :
2) ์บ์ ํํธ๋ ์ ํํ prefix ์ผ์น๊ฐ ์ ์
์๋๊ฐ ์์ฃผ ๋์น๋ ํฌ์ธํธ์ ๋๋ค.
- ๊ฐ์ ์๋ฏธ๋ผ๋ ๋ฌธ์ฅ ์์๊ฐ ๋ค๋ฅด๋ฉด ๋ค๋ฅธ prefix๋ก ์ธ์๋ ์ ์์
- tools/structured output schema/image detail์ด ๋ฌ๋ผ์ง๋ฉด ํํธ์จ ํ๋ฝ
- ์ฌ์ฉ์ ์๋ณ์/๋ ์ง ๊ฐ์ ๋ณ๋๊ฐ์ ์์ ๋๋ฉด ๋งค๋ฒ ๋ฏธ์ค๊ฐ ๋์ด๋จ
์ค๋ฌด ๊ท์น:
- ์(๊ณ ์ ): system rules, output format, tools, schema, ๊ณตํต ์์
- ๋ค(๋ณ๋): user_id, ๋ ์ง, ์์ฒญ payload
3) prompt_cache_key๋ ๋ผ์ฐํ
๋ ๋ฒ
๊ณต์ ๋ฌธ์ ๊ธฐ์ค์ผ๋ก prompt_cache_key๋ prefix hash์ ํจ๊ป ๋ผ์ฐํ
์ ์ํฅ์ ์ฃผ๋ ๋ณ์์
๋๋ค. ๊ฐ์ ์ํฌํ๋ก์ฐ์์ ์ผ๊ด๋ ํค๋ฅผ ์ฐ๋ฉด ์บ์ ํจ์จ์ ๋์ด๊ธฐ ์ข์ต๋๋ค.
๊ถ์ฅ ๋ค์ด๋ฐ:
ops_followup_v1ops_weekly_report_v1ops_helpdesk_v1
์ฐธ๊ณ :
4) ๋ณด์กด ์ ์ฑ ์ ์ด์ ๋ชฉ์ ์ ๋ง์ถฐ ์ ํ
๊ณต์ ๊ฐ์ด๋์์ ๊ธฐ๋ณธ์ in_memory, ํ์ํ๋ฉด 24h ํ์ฅ ๋ณด์กด์ ์ง์ ํ ์ ์์ต๋๋ค.
- ๊ธฐ๋ณธ(
in_memory): ์งง์ ์ฃผ๊ธฐ์ ๋ฐ๋ณต ์์ฒญ์ ์ ๋ฆฌ 24h: ํ๋ฃจ ๋จ์ ๋ฐ๋ณต ์์ฒญ์ด ๋ง์ ๋ ์ ๋ฆฌ
๋จ, ํ๋ก์ ํธ์ ๋ฐ์ดํฐ ์ ์ฑ (์: ZDR ์ด์ฉ ๋งฅ๋ฝ)๊ณผ ํจ๊ป ํ๋จํด์ผ ํฉ๋๋ค.
5) ์ต์ข
ํ๋จ์ cached_tokens๋ก ๋ซ๋๋ค
์บ์ฑ ์ด์์ ์ฒด๊ฐ์ด ์๋๋ผ ์์น๋ก ๋ซ์์ผ ํฉ๋๋ค.
usage.prompt_tokens_details.cached_tokens- p95 latency
- input cost
ํนํ 1024ํ ํฐ ๋ฏธ๋ง ์์ฒญ์ cached_tokens=0์ด ๋์ฌ ์ ์์ผ๋, ์์ฒญ ํฌ๊ธฐ ๋ถํฌ๊น์ง ํจ๊ป ๋ด์ผ ์คํ์ ์ค์ผ ์ ์์ต๋๋ค.
์ฐธ๊ณ :
๋ฐ๋ก ๋ถ์ฌ ์ฐ๋ ์ฝ๋
1) Responses API ๊ธฐ๋ณธ ์์ (Python)
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.1",
input=[
{
"role": "system",
"content": "๋๋ ์ด์ ์๋ํ ๋์ฐ๋ฏธ๋ค. ์ถ๋ ฅ ํ์์ JSON์ผ๋ก ๊ณ ์ ํ๋ค."
},
{
"role": "user",
"content": "์ด๋ฒ ์ฃผ follow-up ๋ฉ์ผ ์ด์์ 3๊ฐ ๋ง๋ค์ด์ค."
}
],
prompt_cache_key="ops_followup_v1",
prompt_cache_retention="in_memory" # ๋๋ "24h"
)
usage = getattr(response, "usage", None)
prompt_details = getattr(usage, "prompt_tokens_details", None)
cached_tokens = getattr(prompt_details, "cached_tokens", 0)
print("cached_tokens:", cached_tokens)2) Prefix ๊ณ ์ ํ ํ๋ฆฟ ํจํด
[System rules - ๊ณ ์ ]
[Output schema - ๊ณ ์ ]
[Tool definitions - ๊ณ ์ ]
[Few-shot examples - ๊ณ ์ ]
[Dynamic block - ๋ณ๋]
- tenant_id:
- user_id:
- date:
- request_payload:3) ์ฃผ๊ฐ ๋น์ฉ/์ง์ฐ ์ ๊ฒ ์ฝ๋ (๊ฐ๋ ์์)
# logs: [{cached_tokens, prompt_tokens, latency_ms, req_count}, ...]
def summarize(logs):
total_prompt = sum(x["prompt_tokens"] for x in logs)
total_cached = sum(x["cached_tokens"] for x in logs)
hit_ratio = (total_cached / total_prompt) if total_prompt else 0
p95_latency = sorted(x["latency_ms"] for x in logs)[int(len(logs) * 0.95) - 1]
return {
"cached_ratio": round(hit_ratio, 4),
"p95_latency_ms": p95_latency,
"requests": sum(x["req_count"] for x in logs),
}๋ฏธ๋ ์ฌ๋ก 3๊ฐ์ง
์ฌ๋ก A) Follow-up ์๋ํ (์ฑ๊ณต)
์ด๊ธฐ์๋ ๊ณ ๊ฐ์ฌ๋ช
/๋ด๋น์๋ช
์ ํ๋กฌํํธ ์๋จ์ ๋ฃ์ด ์บ์๊ฐ ๊ฑฐ์ ์ ๋จน์์ต๋๋ค. ๊ณตํต ๊ท์น/์์๋ฅผ ์์ผ๋ก, ๊ณ ๊ฐ์ฌ ๊ฐ๋ณ๊ฐ์ ๋ค๋ก ์ด๋ํ ๋ค cached_tokens๊ฐ ๋์ ๋๊ฒ ์ฆ๊ฐํ์ต๋๋ค.
์ฌ๋ก B) ์ฃผ๊ฐ ๋ณด๊ณ ์ (์คํจ โ ๋ณต๊ตฌ)
prompt_cache_key๋ฅผ ๋จ์ผ ํค๋ก ๋ชฐ์ ์ฐ๋ค๊ฐ, ํธ๋ํฝ ๋ชฐ๋ฆผ ๊ตฌ๊ฐ์์ ์ง์ฐ ํธ์ฐจ๊ฐ ์ปค์ก์ต๋๋ค. ์ํฌํ๋ก์ฐ๋ณ ํค๋ฅผ ๋ถ๋ฆฌํ๊ณ ํ
ํ๋ฆฟ ๋ฒ์ ์ ๋๋์ ์ง์ฐ ๋ถ์ฐ์ด ์์ ํ๋์ต๋๋ค.
์ฌ๋ก C) ๋ด๋ถ QA ๋ด (ํ์ง ๊ฐ์ )
FAQ ๊ท์น๊ณผ ์ถ๋ ฅ ํฌ๋งท์ด ๋งค๋ฒ ๋ฐ๋์ด ์๋ต ํค์ด ํ๋ค๋ ธ์ต๋๋ค. prefix๋ฅผ ๊ณ ์ ํ๊ณ key๋ฅผ ์ผ๊ด๋๊ฒ ์ด์ฉํ์ ์๋ต ์ผ๊ด์ฑ๊ณผ ๋น์ฉ ์์ธก ๊ฐ๋ฅ์ฑ์ด ํจ๊ป ์ฌ๋ผ๊ฐ์ต๋๋ค.
30๋ถ ๋์ ๋ฃจํด
- 10๋ถ: ํ์ฌ ํ๋กฌํํธ๋ฅผ ๊ณ ์ /๋ณ๋ ๋ธ๋ก์ผ๋ก ๋ถ๋ฆฌ
- 8๋ถ: ์ํฌํ๋ก์ฐ๋ณ
prompt_cache_key๋ค์ด๋ฐ ๊ท์น ํ์ - 7๋ถ: ๋ก๊ทธ์
cached_tokens,prompt_tokens, latency ํ๋ ๊ฐ์ - 5๋ถ: ๋ค์ ์ฃผ ์คํ 1๊ฑด ์์ฝ(ํ ํ๋ฆฟ ์ ๋ ฌ ๋๋ key ๋ถ๋ฆฌ)
์๋ฃ ๊ธฐ์ค:
cached_tokens๋น์จ ์์น- p95 latency ํ๋ฝ
- ์๊ฐ ์ ๋ ฅ๋น์ฉ ์์ธก ์ค์ฐจ ์ถ์
์ ์ฉ ์ฒดํฌ๋ฆฌ์คํธ
- ์์คํ ๊ท์น/์์/ํด ์คํค๋ง๋ฅผ prefix ์์ชฝ์ ๊ณ ์ ํ๋ค
- ์ฌ์ฉ์๋ณ ๋ณ๋๊ฐ์ ๋ค์ชฝ ๋ธ๋ก์ผ๋ก ๋ถ๋ฆฌํ๋ค
- ์ํฌํ๋ก์ฐ๋ณ
prompt_cache_key๋ฅผ ๋ถ๋ฆฌํ๋ค -
prompt_cache_retention์ ์ฑ ์ ์ด์ ๋ชฉ์ ์ ๋ง๊ฒ ์ ํํ๋ค -
cached_tokens, p95, input cost๋ฅผ ์ฃผ๊ฐ ๋ฆฌํฌํธ๋ก ์ถ์ ํ๋ค
