Context window, token, 청구액을 실제로 재보면
40턴 대화는 자기 길이의 22배에 달하는 input token 비용을 냅니다. caching은 68% 줄이고, 잘못 둔 timestamp는 20%를 더합니다.
이 페이지에서
여기 40턴짜리 지원 대화가 있고, 턴마다 비용을 계산했습니다. 특별한 내용은 없습니다. 개발자가 API에 대해 묻고, assistant가 한두 문단으로 답합니다. 전체 대화는 텍스트 5,090 token, 대략 여덟 페이지 분량입니다.
| 턴 | prompt token | 새 텍스트 | output | 이 턴의 비용 | 누적 합계 |
|---|---|---|---|---|---|
| 1 | 213 | 18 | 183 | $0.002622 | $0.002622 |
| 5 | 892 | 14 | 123 | $0.003260 | $0.014354 |
| 10 | 1,656 | 19 | 114 | $0.004680 | $0.035530 |
| 20 | 2,868 | 18 | 103 | $0.006972 | $0.094426 |
| 30 | 3,941 | 20 | 99 | $0.009070 | $0.174170 |
| 40 | 4,947 | 17 | 142 | $0.011598 | $0.274386 |
두 번째와 세 번째 열을 함께 보세요. 40턴에서 사용자는 17 token을 입력했고, 4,947 token에 대해 과금되었습니다. 질문이 첫 질문보다 어려웠던 것도 아닙니다. 오히려 더 짧았습니다. 달라진 것은 요청이 전체 대화를 다시, 마흔 번째로, 함께 들고 갔다는 점입니다.
이 40번의 호출 전체에서 과금된 총 input token은 112,617개입니다. 대화 자체의 길이는 5,090 token입니다. 여러분은 그것을 스물두 번 넘게 지불했습니다.
이 장은 왜 그런 일이 생기는지, 각 provider의 invoice에서는 그것을 무엇이라고 부르는지, 그리고 과금되는 다섯 가지 항목 중 무엇을 제어할 수 있는지에 관한 이야기입니다.
세부 정보 보기
이 장이 Part II에서 가져오는 것.
- **Chapter 7**에서는 tokenizer를 만들었습니다. 여기서도 단위는 token입니다. 같은 단위이고, 이제 가격이 붙었습니다.
- **Chapter 9**에서는 self-attention과 그 비용을 점근 표기법 상자에서 유도했습니다. 그 비용 때문에 애초에 한계가 존재하며, 여기서는 다시 설명하지 않고 연결합니다.
- **Chapter 13**에서는 prefill과 decode를 측정하고 KV cache가 차지하는 용량을 계산했습니다. 위 표의 input과 output 열이 실제로 구매하는 것은 바로 그 두 단계입니다.
나머지는 모두 TypeScript입니다. 이것은 원격 호출의 회계이지, model에 대한 수학이 아니기 때문입니다.
window는 memory가 아닙니다
섹션 링크: window는 memory가 아닙니다이 업계에서 가장 비싼 오해는 model이 대화를 기억한다고 생각하는 것입니다.
그렇지 않습니다. Chapter 13의 메커니즘이 그 이유를 정확히 말해줍니다. 생성 중 transformer의 상태는 KV cache입니다. sequence의 모든 token에 대해 계산된 key와 value입니다. 이 cache는 한 요청이 지속되는 동안만 살아 있습니다. 요청이 끝나면 그것을 들고 있던 프로세스는 다른 사람을 처리해도 되고, cache는 사라집니다. 반대편에는 사용자별 저장소도, session도 없습니다.
그래서 다음 요청은 model이 알아야 할 모든 것을 들고 도착해야 하며, model은 새 token 하나를 내보내기 전에 전체 prompt에 대해 forward pass를 실행해 그 상태를 다시 만듭니다. Chapter 15는 prompt를 "전체 상태"라고 불렀습니다. 물리적인 이유는 이것입니다. prompt가 완전한 상태인 이유는 호출 이후에 살아남는 것이 아무것도 없기 때문입니다.
context window는 그 prompt와 답변을 합친 최대 길이입니다. 이것은 얼마나 많은 상태를 다시 만들 수 있는지에 대한 상한이지, 요청 사이에 무언가를 담아 두는 컨테이너가 아닙니다. 이것을 "model의 memory"라고 부르면 인과관계의 방향을 거꾸로 보게 됩니다. 여러분은 memory를 채우는 것이 아니라, memory 하나를 다시 세우는 비용을 내고 있습니다.
스물두 배는 여기서 나옵니다. 번째 턴은 이전 개 턴을 모두 들고 가므로, 턴짜리 대화 전체의 input 합계는 커지는 수열의 합이 되고, 이는 이차식입니다.
여기서 는 system prompt이고 는 번째 턴의 history입니다. 40턴에 걸쳐 측정된 누적 input을 에 맞추면 가 나오며, 이는 40턴에서 113,645 token을 예측합니다. 실제 측정값은 112,617입니다. 지배적인 것은 이차항이고, 선형항은 사용자가 실제로 입력한 것입니다.
이 장에서 가져가야 할 문장은 이것입니다. 청구액은 마지막 질문이 아니라 대화 길이의 제곱에 따라 커집니다. 같은 40개 질문을 history 없이 물었다면 비용은 $0.066036입니다. history를 유지하면 $0.274386입니다. history가 청구액을 4.2배로 만들었고, 계속 곱해질 것입니다. 배율 자체가 대화 길이이기 때문입니다.
애초에 한계가 있는 이유
섹션 링크: 애초에 한계가 있는 이유window가 유한한 데에는 같은 방향으로 작용하는 두 가지 이유가 있습니다. 첫째는 Chapter 9의 이유입니다. attention은 모든 token을 다른 모든 token과 비교하므로, 그 layer의 작업량은 sequence 길이의 제곱으로 늘어납니다. 둘째는 memory입니다. KV cache는 sequence 길이에 대해 선형으로 늘어나며, Chapter 13에서 그 산술을 했습니다. 긴 sequence에서는 이것이 weights보다 더 큽니다.
두 한계 모두 공격받아 왔지만, 둘 중 어느 것도 사라지지는 않았습니다. FlashAttention1은 계산을 재구성해 high-bandwidth memory에 훨씬 덜 읽고 쓰게 만들며, 점근 비용을 바꾸지 않고도 긴 sequence를 실용적으로 만듭니다. Position Interpolation2과 YaRN3은 재훈련 대신 Chapter 9의 positional encoding을 rescale해 훈련된 model의 usable window를 확장합니다. 이들이 함께 작용했기 때문에 window는 5년 만에 2K에서 1M으로 갔습니다.
그들이 하지 않은 일은 긴 context를 공짜로 만드는 것이었습니다. 천장은 높였고 기울기는 완만하게 만들었습니다. 그러나 기울기는 여전히 있고, 이 장 뒷부분의 가격 tier가 측정하는 것이 바로 그것입니다.
두 개가 아니라 다섯 개의 bucket
섹션 링크: 두 개가 아니라 다섯 개의 bucket인터넷의 거의 모든 비용 계산기는 API 호출을 input token 수 곱하기 input 가격에 output token 수 곱하기 output 가격을 더한 것으로 모델링합니다. 2023년에는 맞았습니다. 이제는 양방향으로 청구액을 두 배 이상 틀리게 만들 수 있는 방식으로 틀렸습니다.
과금 가능한 token 범주는 다섯 가지입니다.
| bucket | 의미 | input 대비 일반적인 가격 |
|---|---|---|
| uncached input | model이 새로 처리해야 했던 prompt token | 1× |
| cache read | 저장된 prefix에서 제공된 prompt token | 0.1× |
| cache write | 이 호출에서 cache에 저장된 prompt token | 1.25×~2× |
| output | model이 생성해 여러분에게 보낸 token | 5×~6× |
| reasoning | model이 생성했지만 여러분에게 보내지 않은 token | output 요율 |
이 다섯 중 세 가지는 2년 전에는 별도 항목으로 존재하지 않았고, 사람들이 틀리는 것은 두 cache 항목입니다. cache write는 일반 input보다 더 비싸지, 더 싸지 않기 때문입니다. 나중에 할인된 가격으로 다시 읽기 위해 무언가를 저장하는 premium을 내는 셈이고, 그 거래가 유리한지는 전적으로 그것을 몇 번 읽느냐에 달려 있습니다.
reasoning bucket은 Chapter 12의 내용에 가격이 붙은 것이며, 분명히 말할 가치가 있는 세부 사항을 하나 포함합니다. Google 문서는 가격이 "API에서 summary만 output되더라도 model이 생성해야 하는 전체 thought token을 기준으로 한다"고 말합니다.4 여러분은 전송받지 못하는 token에도 과금됩니다. 내용을 셀 수도, 검사할 수도, 검증할 수도 없는 유일한 bucket입니다.
같은 호출, 세 가지 방언
섹션 링크: 같은 호출, 세 가지 방언이제 이것이 곱셈 문제가 아니라 정규화 문제인 이유입니다. 각 provider는 이 bucket들을 서로 다른 이름으로 보고하며, 여기 함정이 있습니다. 그중 두 곳은 같은 단어를 서로 다른 양에 사용합니다.
한 호출을 봅시다. cache에서 읽은 4,837 token, 새로 처리한 110 token, 눈에 보이는 output token 142개, reasoning token 300개입니다.
// OpenAI-compatible
{ "usage": { "prompt_tokens": 4947,
"prompt_tokens_details": { "cached_tokens": 4837 },
"completion_tokens": 442,
"completion_tokens_details": { "reasoning_tokens": 300 } } }
// Anthropic
{ "usage": { "input_tokens": 110,
"cache_read_input_tokens": 4837,
"cache_creation_input_tokens": 0,
"output_tokens": 442 } }
// Gemini
{ "usageMetadata": { "promptTokenCount": 4947,
"cachedContentTokenCount": 4837,
"candidatesTokenCount": 142,
"thoughtsTokenCount": 300 } }prompt_tokens: 4947와 input_tokens: 110를 보세요. 두 field 모두 같은 prompt의 input token 수입니다. OpenAI의 값은 cached token을 포함합니다. Anthropic의 값은 그것을 제외합니다. 문서에는 항등식 total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens가 명시되어 있습니다.5 Anthropic의 input_tokens는 "마지막 cache breakpoint 이후의 token"을 뜻합니다.
output도 보세요. OpenAI와 Anthropic은 둘 다 442를 보고하는데, 여기에는 이미 300개의 reasoning token이 들어 있습니다. Gemini는 142를 보고하고 300을 별도 field에 둡니다. Chapter 12는 같은 작업을 세는 두 방식 사이의 비호환성을 지적했습니다. 여기서는 그것이 비용으로 드러납니다.
normalizer는 서른 줄이고, 선택 사항이 아닙니다.
export interface Usage {
promptTokens?: number; // input, NOT cached
cachedInputTokens?: number; // read from cache
cacheWriteTokens?: number; // written to cache on this call
completionTokens?: number; // output
reasoningTokens?: number; // billed apart from output (Gemini only)
}
const num = (v: unknown) => (typeof v === "number" && isFinite(v) ? v : 0);
export const fromOpenAI = (raw: any): Usage => {
const u = raw.usage ?? {}, d = u.prompt_tokens_details ?? {};
const cached = num(d.cached_tokens), write = num(d.cache_write_tokens);
return {
promptTokens: Math.max(0, num(u.prompt_tokens) - cached - write),
cachedInputTokens: cached,
cacheWriteTokens: write,
completionTokens: num(u.completion_tokens), // reasoning already inside
reasoningTokens: 0,
};
};
export const fromAnthropic = (raw: any): Usage => {
const u = raw.usage ?? {};
return {
promptTokens: num(u.input_tokens), // already excludes cache
cachedInputTokens: num(u.cache_read_input_tokens),
cacheWriteTokens: num(u.cache_creation_input_tokens),
completionTokens: num(u.output_tokens),
reasoningTokens: 0,
};
};
export const fromGemini = (raw: any): Usage => {
const m = raw.usageMetadata ?? {}, cached = num(m.cachedContentTokenCount);
return {
promptTokens: Math.max(0, num(m.promptTokenCount) - cached),
cachedInputTokens: cached,
cacheWriteTokens: 0,
completionTokens: num(m.candidatesTokenCount), // EXCLUDES thinking
reasoningTokens: num(m.thoughtsTokenCount), // billed at output rate
};
};위 세 payload를 세 reader에 통과시키면 셋 모두 같은 Usage를 만들고, 따라서 같은 숫자인 $0.006491을 냅니다. 이 일치가 이 layer를 쓰는 이유 전체입니다.
틀리면 같은 호출에서 비용이 이렇게 달라집니다.
| 실수 | 계산된 비용 | 오류 |
|---|---|---|
cached_tokens를 prompt_tokens에 추가되는 것으로 취급 | $0.016165 | 2.49× — prompt를 두 번 청구합니다 |
| cache read를 0.1×가 아니라 무료로 취급 | $0.005524 | 0.85× — 15%를 떠안습니다 |
candidatesTokenCount를 읽고 thoughtsTokenCount를 무시 | $0.002891 | 호출의 55%가 사라집니다 |
세 번째가 위험합니다. 좋은 소식처럼 보이는 방향으로 조용히 실패하기 때문입니다. dashboard에는 reasoning model이 실제 비용의 절반도 안 드는 것처럼 보이고, 어디에서도 error가 나지 않습니다.
비용 계산하기
섹션 링크: 비용 계산하기bucket이 정규화되면 비용 함수는 짧습니다. 유일하게 직관적이지 않은 부분은 tier lookup이고, 다음 절에서 설명합니다.
export interface Tier { maxPromptTokens: number | null; price: number }
export interface Pricing {
input: Tier[]; output: Tier[];
cachedInput?: Tier[]; cacheWrite?: Tier[]; reasoning?: Tier[];
}
const tierPrice = (tiers: Tier[] | undefined, contextSize: number, fallback?: Tier[]) => {
const table = tiers ?? fallback;
if (!table?.length) return 0;
const sorted = [...table].sort(
(a, b) => (a.maxPromptTokens ?? Infinity) - (b.maxPromptTokens ?? Infinity));
for (const t of sorted)
if (t.maxPromptTokens === null || contextSize <= t.maxPromptTokens) return t.price;
return sorted[sorted.length - 1].price;
};
export function computeCost(pricing: Pricing, usage: Usage): number {
const fresh = usage.promptTokens ?? 0;
const read = usage.cachedInputTokens ?? 0;
const write = usage.cacheWriteTokens ?? 0;
const out = usage.completionTokens ?? 0;
const think = usage.reasoningTokens ?? 0;
const contextSize = fresh + read + write; // the tier depends on the WHOLE prompt
return fresh * tierPrice(pricing.input, contextSize)
+ read * tierPrice(pricing.cachedInput, contextSize, pricing.input)
+ write * tierPrice(pricing.cacheWrite, contextSize, pricing.input)
+ out * tierPrice(pricing.output, contextSize)
+ think * tierPrice(pricing.reasoning, contextSize, pricing.output);
}여기에는 주장할 만한 설계 결정이 두 가지 있습니다. fallback, 즉 cache 가격은 input으로, reasoning은 output으로 되돌리는 것은 누락된 table이 무엇을 뜻하는지 encoding합니다. Gemini의 reasoning token은 output 요율로 청구되므로 reasoning 가격이 없다는 것은 0이 아니라 output 가격이라는 뜻입니다. 그리고 contextSize는 fresh bucket만이 아니라 세 input bucket을 모두 더합니다. tier는 prompt가 얼마나 긴지로 선택되지, 그중 얼마를 full price로 청구받았는지로 선택되지 않기 때문입니다.
prompt caching, 그리고 쓰는 비용
섹션 링크: prompt caching, 그리고 쓰는 비용prompt cache는 prompt의 prefix에 대해 model이 계산한 상태를 저장해, 나중에 같은 prefix를 가진 요청이 그것을 다시 계산하지 않도록 합니다. "prefix"라는 단어에서 네 가지 속성이 나오고, 네 가지 모두 사람들을 놀라게 합니다.
set이 아니라 prefix입니다
섹션 링크: set이 아니라 prefix입니다cache는 렌더링된 prompt의 시작부터 앞으로 맞춰 보고, 달라지는 첫 byte에서 멈춥니다. 나중에 다른 순서로 나타나는 내용에는 부분 점수가 없습니다. OpenAI는 단호하게 말합니다. "cache reuse requires the entire rendered prefix to match."6
최소 길이가 있습니다
섹션 링크: 최소 길이가 있습니다그보다 짧으면 아무것도 cache되지 않고 error도 반환되지 않습니다. OpenAI에서는 GPT-5.6 이후 model의 최소값이 1,024 token이고, 더 오래된 model은 2,048입니다. Anthropic에서는 model에 따라 512에서 4,096까지입니다. Claude Sonnet 4.5는 1,024, Claude Haiku 4.5는 4,096입니다. 두 cache field가 모두 0으로 돌아오면 보통 이 때문입니다.
쓰기는 읽기보다, 그리고 caching하지 않는 것보다 비쌉니다
섹션 링크: 쓰기는 읽기보다, 그리고 caching하지 않는 것보다 비쌉니다OpenAI와 Anthropic에서 cache write는 수명이 짧은 cache의 경우 uncached input 요율의 1.25×이고, Anthropic의 1시간 cache는 2×입니다. read는 0.1×입니다. Google은 write에는 요금을 부과하지 않지만 storage를 임대합니다. Gemini 2.5 Pro에서 시간당 100만 token당 $4.50입니다.
만료되고, 한 machine에 삽니다
섹션 링크: 만료되고, 한 machine에 삽니다Anthropic의 기본 entry는 5분 동안 살며 hit가 날 때마다 무료로 refresh됩니다. OpenAI의 것은 마지막 write 또는 reuse 이후 최소 30분입니다. 또한 OpenAI는 cached state가 개별 machine에 산다고 언급합니다. 따라서 요청이 해당 entry를 들고 있는 machine으로 routing되어야 hit가 납니다. 이것이 prompt_cache_key가 영향을 주는 지점이지만, 보장하지는 않습니다.
break-even은 머릿속에 넣어둘 수 있을 만큼 작고, OpenAI 문서가 그 산술을 해 줍니다. prefix를 한 번 쓰고 한 번 재사용하면 일반 input 비용의 1.35×가 들며, uncached로 두 번 처리하는 2×와 비교됩니다. 10개 요청에서는 write 한 번과 read 아홉 번이 2.15×이고, 10×와 비교됩니다. 한 번의 재사용이 write 비용을 갚습니다. Anthropic도 같은 지점에 도달합니다. 5분 cache는 read 한 번, 1시간 cache는 두 번입니다.
이제 caching을 켜고 prefix가 안정적인 상태로 40턴 대화를 다시 봅시다.
| uncached input | cache read | cache write | total | |
|---|---|---|---|---|
| cache 없음 | 112,617 | — | — | $0.274386 |
| caching | 2,887 | 104,783 | 4,947 | $0.088250 |
68% 저렴해졌고, 이 표의 세 숫자는 주의 깊게 볼 가치가 있습니다.
cache는 6턴이 되어서야 작동합니다. prompt가 그때까지 1,024 token에 도달하지 않으므로, 처음 다섯 턴은 이전과 정확히 똑같이 과금됩니다. 그리고 여섯 번째 턴은 cache를 채우는 턴이라 1.25\u00d7 write premium이 붙어 더 나쁘게 청구됩니다. 첫 read는 7턴에 옵니다. 표의 2,887 uncached token은 그 산술입니다. 여섯 턴이 아니라 다섯 턴 분량입니다. caching은 긴 prompt에 대한 할인이고, 짧은 대화는 아무것도 얻지 못합니다.
write premium은 $0.002474로, cached bill의 2.8%입니다. 모든 턴이 새 tail을 쓰고, 이를 40번 반복하지만, 전체 write premium은 read가 절약한 것에 비하면 반올림 오차입니다. write charge를 정확히 이해해야 그것에 대해 걱정을 멈출 수 있습니다.
112,617개 중 2,887 token만 full input price로 청구되었습니다. 작동하는 cache의 형태는 이렇습니다. 거의 모든 것이 read입니다.
prompt의 순서가 이 모든 일이 일어날지를 결정합니다
섹션 링크: prompt의 순서가 이 모든 일이 일어날지를 결정합니다실제로 돈이 드는 실패는 이것이고, 한 줄짜리 bug입니다.
호출마다 바뀌는 무언가를 prompt 앞쪽에 두세요. timestamp, request id, 사용자 이름, "today is" 줄, 방금 retrieval한 document 같은 것 말입니다. 그러면 prefix가 첫 byte부터 달라집니다. 아무것도 match되지 않습니다. 모든 호출이 miss입니다. 그리고 모든 호출이 새로운 prefix를 제시하므로, 모든 호출이 write도 합니다.
같은 대화, 같은 40턴, caching enabled, system prompt 맨 위에 호출별 timestamp가 있는 경우입니다.
| total | 대비 | |
|---|---|---|
| caching 전혀 없음 | $0.274386 | — |
| caching, stable prefix | $0.088250 | −67.8% |
| caching, volatile prefix | $0.329251 | +20.0% |
prompt caching을 켰더니 대화가 켜지 않았을 때보다 20% 더 비싸졌습니다. 109,730 token에 1.25× write premium을 냈고, read는 0이었습니다. error도, warning도 없고, 기능은 켜져 있습니다.
그래서 규칙은 이것이며, 한 줄로 된 prompt caching의 전부입니다. 안정적인 content는 앞에, 변하는 content는 뒤에. system instruction, tool definition, reference material을 먼저 두고, timestamp, user identity, current question을 마지막에 두세요. Anthropic은 계층을 명시합니다. cache는 tools → system → messages를 따르며, 어떤 level에서든 변경이 생기면 그 level과 그 뒤의 모든 것이 무효화됩니다. 그래서 tool description 하나만 수정해도 전체 cache가 무효화됩니다.5
사람들이 자주 걸려 넘어지는 결과가 두 가지 있습니다. 어떤 tool이 enabled되어 있는지 바꾸면 tool definition이 바뀌므로, 일부 사용자에게 tool을 추가하는 feature flag는 cache를 둘로 나눕니다. 그리고 Anthropic에서는 web search나 citation을 토글하면 system prompt가 수정되어, 여러분이 자신의 텍스트 한 줄도 건드리지 않아도 system cache와 message cache가 무효화됩니다.
history를 잘라내는 것은 해결책이 아닙니다
섹션 링크: history를 잘라내는 것은 해결책이 아닙니다이차적으로 커지는 청구액에 대한 뻔한 반응은 전체 history를 보내지 않는 것입니다. 마지막 열두 message만 유지하고 나머지는 버리는 식입니다. 비용은 줄어듭니다. 그리고 보통은 잘못된 선택입니다. 측정값이 그 이유를 말합니다.
| 전략 | total | full history + cache 대비 |
|---|---|---|
| full history, no cache | $0.274386 | +211% |
| full history, caching | $0.088250 | — |
| last 12 messages, no cache | $0.118712 | +35% |
| last 12 messages, caching on | $0.122546 | +39% |
12-message window로 truncation하면 모든 것을 uncached로 보내는 것보다 57% 저렴합니다. 모두가 하는 비교이고, 이 기법이 인기 있는 이유입니다. 하지만 작동하는 cache로 모든 것을 보내는 것보다는 39% 더 비쌉니다. 그리고 truncation과 함께 caching을 켜면 더 좋아지는 대신 약간 더 나빠집니다.
메커니즘은 다시 prefix입니다. sliding window는 매 턴 가장 오래된 message를 떨어뜨리므로 prompt는 더 이상 지난번과 같은 지점에서 시작하지 않고, 매 턴 새로운 prefix를 제시합니다. OpenAI의 guidance는 이를 정확히 말합니다. "summarisation, compaction, or context truncation can change the prefix and reset cache reuse."6 40턴이 되면 windowed prompt는 813 token으로, 1,024-token minimum보다 작아져 아예 cache될 수 없습니다.
그리고 돈은 비용의 싼 절반입니다. 버린 것은 사용자가 2턴에서 줬고 model이 40턴에서 필요로 한 instruction입니다. truncation은 눈에 보이는 청구액을 눈에 보이지 않는 실패와 맞바꿉니다. 제대로 하려면 compaction, window 밖에 유지되는 structured note, 필요할 때 history retrieval이 필요하며, 이는 Chapter 24의 주제입니다.
tier를 넘으면 전체 요청의 가격이 다시 매겨집니다
섹션 링크: tier를 넘으면 전체 요청의 가격이 다시 매겨집니다긴 context가 더 비싼 것은 단지 더 길기 때문만이 아닙니다. threshold를 지나면 token당 더 비싸지고, 그 threshold는 전체 prompt에 소급 적용됩니다.
gpt-5.6-terra에 대한 OpenAI model page는 한 문장으로 말합니다. "Prompts with >272K input tokens are priced at 2x input and 1.5x output for the full request."7 초과분만이 아닙니다. 전체입니다.
prompt 271,999 + 500 output -> $0.5500
prompt 272,000 + 500 output -> $0.5500
prompt 272,001 + 500 output -> $1.0970token 하나, 55센트입니다. service가 크기를 제어할 수 없는 retrieved document로 prompt를 만든다면, 여러분의 비용 model에는 팀 누구도 적어두지 않은 경계에 절벽이 있습니다.
Google pricing도 200,000-token threshold로 같은 방식입니다. Gemini 2.5 Pro는 200K 이하 prompt에서 input token 100만 개당 $1.25이고, 그 이상에서는 $2.50입니다. output은 $10.00에서 $15.00으로 갑니다.8 Anthropic은 반대 방향으로 갔습니다. 2026년 9월 6일 기준 문서는 Claude 4.6 이후가 전체 100만 token window를 standard pricing에 포함한다고 말합니다. 따라서 "900k-token request is billed at the same per-token rate as a 9k-token request."9 이전 model은 surcharge를 유지했습니다.
그래서 price는 숫자가 아닙니다. price는 prompt 길이를 key로 하는 tier table이며, 비용 함수의 Tier[]가 그 일을 합니다. 그리고 computeCost가 각 bucket을 따로 보지 않고 전체 prompt로 tier를 선택하는 이유이기도 합니다.
prefill, decode, 그리고 output이 input보다 여섯 배 비싼 이유
섹션 링크: prefill, decode, 그리고 output이 input보다 여섯 배 비싼 이유다섯 bucket은 Chapter 13의 두 단계에 대응하고, 이 대응을 보면 가격 비율이 더 이상 임의적으로 보이지 않습니다.
Input token은 prefill입니다. 전체 prompt가 한 번의 pass로 model을 통과하며 병렬 처리됩니다. 큰 matrix multiplication이고 compute-bound입니다. token당 비용은 낮으며, 이 단계가 time to first token을 결정합니다. 4,947-token prompt는 첫 단어가 나타나기 전에 4,947 token의 prefill을 해야 합니다.
Output token은 decode입니다. token은 하나씩 생성되며, 각각은 전체 KV cache를 읽는 full forward pass입니다. GPU는 계산보다 memory를 기다리는 시간이 많습니다. 이 단계가 tokens per second를 결정하고, 한 response 안에서는 병렬화할 수 없으며, 그래서 여기서 가격을 매긴 model에서 output은 input의 약 여섯 배입니다. 100만 token당 $2.00에 비해 $12.00입니다.
세 가지 결과가 바로 따라옵니다. cache read는 prefill 작업을 대체하므로 latency와 비용을 동시에 삽니다. 같은 할인이 더 낮은 청구액과 첫 token까지의 더 짧은 대기로 나타납니다. reasoning token은 보이지 않는 decode입니다. 그래서 reasoning model은 몇 초 동안 아무것도 stream하지 않다가 빠르게 답합니다. Chapter 12가 interface상의 결과를 경고했고, 이것은 invoice상의 결과입니다. 그리고 stream을 abort해도 generation은 멈추지 않습니다. Chapter 14는 cancellation을 만들고 가격은 이 장에 남겨두었습니다. 가격은 full output count입니다. 누군가 듣고 있든 아니든 token은 생성되고 과금되기 때문입니다. 아무도 보관하지 않는 답변도 마찬가지입니다. 40턴 답변을 다섯 번 regenerate하면 화면에 남은 하나에 대해 $0.057990를 냅니다.
보내기 전에 token 세기
섹션 링크: 보내기 전에 token 세기Chapter 7의 tokenizer는 Python이었고 거기에 머물렀습니다. budgeting은 request를 만드는 server에서 일어나므로 여기에서 해야 하며, 가능한 정확도 수준은 정확히 세 가지입니다.
Level one: 로컬에서 셉니다. js-tiktoken는 Python tiktoken와 같은 BPE merge table을 함께 제공하므로, network call 없이 OpenAI encoding에 대해 byte-for-byte 동일한 count를 얻습니다.
import { getEncoding } from "js-tiktoken";
const enc = getEncoding("o200k_base");
const PER_MESSAGE = 4; // role and delimiters added by the chat template
const PER_REPLY = 3; // priming for the assistant turn
export function promptTokens(messages: { role: string; content: string }[]) {
return messages.reduce(
(sum, m) => sum + enc.encode(m.content).length + PER_MESSAGE, PER_REPLY);
}두 constant가 중요하고, local count가 drift하는 곳도 여기입니다. tokenized되는 것은 여러분의 text가 아닙니다. Chapter 11의 chat template이 먼저 모든 message를 role marker로 감싸고, 그것들도 여러분이 비용을 내는 token입니다. message당 4개, reply priming에 3개라는 값은 OpenAI chat model에 대한 전통적인 근사입니다. 위 대화의 81개 message 전체에서 324 token, 길이의 6.4%가 됩니다. 여기의 count는 Chapter 7의 Python tiktoken와 81개 string 전체를 대조했고 동일했습니다.
Level two: provider에게 묻습니다. Anthropic은 /v1/messages/count_tokens를, Google은 count_tokens를 제공합니다. 둘 다 실제 호출과 같은 request shape을 받아 무료로 input token count를 반환합니다. 로컬에서 셀 수 없을 때 사용하세요. Anthropic은 tokenizer를 공개하지 않으므로 로컬에서 셀 수 없습니다. Anthropic 문서는 자신이 무엇을 제공하는지 조심스럽게 설명합니다. count는 "estimate"이며, "system optimizations"를 위해 Anthropic이 자동으로 추가한 token을 포함할 수 있고, 그것들은 "you are not billed"라고 말합니다.10
Level three: response의 usage를 읽습니다. 그것이 진실이고, 돈을 쓴 뒤에 도착합니다. 그래서 앞의 두 level이 존재합니다. 청구하기 위해서가 아니라, 요청을 보낼지 결정하기 위해서입니다.
아무도 보여주지 않지만 여러분이 비용을 내는 것들
섹션 링크: 아무도 보여주지 않지만 여러분이 비용을 내는 것들line item으로 나타나지 않는 네 가지 line item입니다.
system prompt, 모든 호출마다 지불됩니다. 위 prompt는 template overhead를 포함해 192 token입니다. 40번 호출하면 7,680 token입니다. 한 번 작성한 8줄이 이 대화 전체 bill의 5.6%입니다. 또한 안정적이고 맨 앞에 있기 때문에 가능한 최고의 cache candidate이기도 합니다.
Tool definition. 모든 tool의 name, description, JSON schema가 매 요청마다 나가고, provider는 그 위에 scaffolding을 추가합니다. Anthropic은 숫자를 공개합니다. tool을 enabled하는 것만으로도 Claude Sonnet 4.5에서 tool_choice가 auto로 설정된 경우 hidden system prompt가 496 token 추가되고, any나 named tool이 있으면 588 token이 추가됩니다.9 이는 여러분의 schema 이전입니다. Chapter 18은 catalogue를 만들고, Chapter 24는 그것이 무엇을 먹는지 측정합니다.
버리는 것까지 포함한 모든 generation. 다섯 번 regeneration하면 비용은 다섯 배입니다. chat에는 하나만 보입니다.
보여주지 않는 thought. summary만 반환되더라도 billing은 전체 thought token을 기준으로 하며, 여러분의 어떤 accounting도 그 숫자를 audit할 수 없습니다.
200K token을 가진 것과 그것을 쓰는 것은 다릅니다
섹션 링크: 200K token을 가진 것과 그것을 쓰는 것은 다릅니다마지막으로 하나의 warning을 남깁니다. 자연스러운 다음 생각이지만, 답은 뻔하지 않습니다.
100만 token window가 100만 개의 usable token을 뜻하지는 않습니다. retrieval accuracy는 위치에 따라 저하됩니다. Liu et al.은 model이 긴 input의 시작과 끝에서는 정보를 안정적으로 찾지만, 중간에서는 훨씬 덜 안정적이라고 밝혔습니다.11 더 큰 window는 더 많이 보낼 수 있는 능력을 사는 것이지, 읽힐 확실성을 사는 것이 아닙니다.
이 현상은 이 course에서 한 번 측정됩니다. 같은 853-token prompt의 9개 위치에서 retrieval rate를 잰 것이며, agent가 무엇을 하는지를 바꾸는 Chapter 24에 속합니다. 여기서 인용하는 이유는 여러분이 무엇을 사야 하는지를 바꾸기 때문입니다. 가장 싼 token은 보내지 않은 token입니다.
다음으로 이어지는 곳
섹션 링크: 다음으로 이어지는 곳이제 호출하기 전에 얼마가 들지 예측하고, 이후에 실제 얼마가 들었는지 읽고, 둘의 차이를 구분할 수 있습니다. 이것은 요청에 관한 거의 모든 것을 다룹니다. 아직 건드리지 않은 부분, 즉 knob만 빼고요.
Chapter 17은 sampling입니다. temperature, top-p, top-k, penalty, 그리고 여러분에게 없는 determinism을 다룹니다. 이 장은 현장에서 가장 널리 퍼진 오류, 즉 temperature가 creativity dial이라는 믿음을 해체하는 것에서 시작합니다. 그렇지 않습니다. temperature는 Chapter 4의 logit을 softmax 전에 나누며, 그것을 올린다고 model이 imaginative해지는 것이 아니라 model 자신이 더 나쁘게 score한 token의 probability를 올립니다. 거기서부터 greedy decoding이 sampling보다 측정 가능하게 더 나쁜 text를 만드는 이유, top-k와 top-p가 서로 반대 모양의 distribution에서 실패하는 이유, 그리고 장을 끝내는 experiment로 이어집니다. temperature 0에서 동일한 forward pass를 20번 실행하면 model이 단독으로 실행될 때 bit-for-bit 동일하게 돌아오지만, 같은 prompt를 다른 사람의 요청과 함께 batch에 넣으면 logit의 97%가 움직입니다.
모두 일치하지는 않습니다. 이유는 Chapter 2의 floating-point 상자에서 시작됩니다.
Sources and method
섹션 링크: Sources and method이 장의 모든 price, threshold, multiplier는 provider 자체 page에서 2026년 9월 6일에 읽은 것이며, 바뀔 것이기 때문에 그 날짜와 함께 적었습니다. 숫자보다 중요한 것은 method입니다. bucket, prefix rule, tier arithmetic은 2년 동안 안정적이었지만, 그 안의 모든 수치는 움직였습니다.
Stanford CS336 lecture 2, Resource accounting은 이 material에 가장 가까운 academic treatment이며 다음으로 읽기 좋은 자료입니다. 이 장이 inference 쪽에서 하는 것과 같은 산술을 training 쪽에서 합니다. 여기의 token count는 js-tiktoken 1.0.21을 사용해 o200k_base 및 cl100k_base encoding으로, 5,090 token짜리 40-turn conversation에 대해 산출했습니다. per-message template overhead는 전통적인 four-plus-three approximation이며 포함된 곳마다 명시했습니다. cache, tier, truncation figure는 측정된 token count에 documented pricing rule을 적용한 것이며 live API response를 관찰한 것이 아닙니다. 이 장을 만들기 위해 유료 호출은 하지 않았고, 그것이 latency claim은 qualitative이지만 cost claim은 그렇지 않은 정직한 이유이기도 합니다.
-
Dao, T., Fu, D. Y., Ermon, S., Rudra, A. and Ré, C. FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness. arXiv:2205.14135 (2022). 점근 비용을 바꾸지 않고 ceiling이 이동한 이유입니다. ↩
-
Chen, S., Wong, S., Chen, L. and Tian, Y. Extending Context Window of Large Language Models via Positional Interpolation. arXiv:2306.15595 (2023). ↩
-
Peng, B., Quesnelle, J., Fan, H. and Shippole, E. YaRN: Efficient Context Window Extension of Large Language Models. arXiv:2309.00071 (2023). ↩
-
Google, Thinking,
ai.google.dev/gemini-api/docs/thinking, 및 Token counting,ai.google.dev/gemini-api/docs/tokens, 둘 다 accessed 2026-09-06. "Pricing is based on the full thought tokens the model needs to generate, despite only the summary being output from the API." usage object는total_input_tokens,total_output_tokens,total_thought_tokens,total_cached_tokens,total_tool_use_tokens,total_tokens를 보고합니다. 여섯 bucket이며, thought와 tool use는 output count 밖에 있습니다. 같은 quantity의 earlier field name은 generateContent surface에서 여전히 반환되는thoughtsTokenCount이며, 세 번째 pageai.google.dev/gemini-api/docs/generate-content/thinking에 documented되어 있습니다. ↩ -
Anthropic, Prompt caching,
docs.anthropic.com/en/docs/build-with-claude/prompt-caching, accessed 2026-09-06.tools→system→messagesinvalidation hierarchy와 그 table; model별 minimum cacheable length; identitytotal_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens; hit마다 무료로 refresh되는 5-minute default lifetime의 출처입니다. ↩ ↩2 -
OpenAI, Prompt caching,
platform.openai.com/docs/guides/prompt-caching, accessed 2026-09-06. 출처: entire-rendered-prefix rule; minimum cacheable prefix(GPT-5.6 이후 visible input token 1,024개, 이전 model 2,048개); 1.25× write 및 0.1× read multiplier, GPT-5.5 이전에는 write charge가 없었다는 점; 30-minute lifetime; request당 four-writes 및 fifty-breakpoint limit; machine-affinity note와prompt_cache_key; 1.35×, 2.15×, 10× break-even worked example; summarisation, compaction 또는 truncation이 cache reuse를 reset한다는 진술. ↩ ↩2 -
OpenAI, Pricing (
platform.openai.com/docs/pricing) 및gpt-5.6-terramodel page, 둘 다 accessed 2026-09-06.gpt-5.6-terra, standard service tier, 100만 token당: input $2.00, cached input $0.20, cache writes $2.50, output $12.00; long context input $4.00, cached $0.40, writes $5.00, output $18.00; "prompts with >272K input tokens are priced at 2x input and 1.5x output for the full request"; context window 1,050,000 token, maximum input token 922,000개. 같은 table에는gpt-6-astra가 $10.00/$1.00/$12.50/$50.00,gpt-5.6-luna가 $0.20/$0.02/$0.25/$1.20로 listed되어 있습니다. 이 장의 모든 worked cost는gpt-5.6-terrastandard short-context rate를 사용합니다. ↩ -
Google, Gemini Developer API pricing,
ai.google.dev/gemini-api/docs/pricing, accessed 2026-09-06. Gemini 2.5 Pro, 100만 token당: 200K 이하 prompt의 input $1.25, 그 이상 $2.50; output $10.00 및 $15.00, 두 경우 모두 "including thinking tokens"라고 labelled됨; context caching $0.125 및 $0.25, 여기에 시간당 100만 token당 $4.50의 storage charge. Gemini 3.1 Pro Preview는 같은 200K threshold에서 input $2.00/$4.00, output $12.00/$18.00을 사용합니다. ↩ -
Anthropic, Pricing,
docs.anthropic.com/en/docs/about-claude/pricing, accessed 2026-09-06. 100만 token당, base input / 5-minute cache write / 1-hour cache write / cache read / output: Claude Sonnet 4.5 $3 / $3.75 / $6 / $0.30 / $15; Claude Haiku 4.5 $1 / $1.25 / $2 / $0.10 / $5; Claude Opus 5 $5 / $6.25 / $10 / $0.50 / $25. Multiplier: 5-minute write는 1.25×, 1-hour write는 2×, read는 0.1×. 또한 long-context statement("Claude 4.6 and later models... include the full 1M token context window at standard pricing"), tool-use system prompt token count(Claude Sonnet 4.5에서tool_choice가auto또는none이면 496 token,any또는 named tool이면 588 token), Claude 4.7 이후가 "approximately 30 % more tokens for the same text"를 만드는 newer tokenizer를 사용한다는 note의 출처입니다. ↩ ↩2 ↩3 -
Anthropic, Token counting,
docs.anthropic.com/en/docs/build-with-claude/token-counting, accessed 2026-09-06./v1/messages/count_tokensendpoint는 message와 같은 input을 받고 input token count를 반환합니다. 문서는 count가 estimate이며, Anthropic이 system optimisation을 위해 추가하는 token을 포함할 수 있고, 그것들은 billed되지 않는다고 말합니다. ↩ -
Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F. and Liang, P. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (2023). 여기서 인용하고, Chapter 24에서 측정합니다. ↩