Site

Tokens — Context Windows and Cost

Tutorial 4.0  •  AI / Learn

4.0 What This Teaches

This tutorial explains how LLMs measure and meter text. It covers:

4.1 What a Token Is

LLMs do not work with individual characters or whole words. They work with tokens - fragments produced by a tokenizer that was trained alongside the model. A token averages roughly 0.75 words in English prose, but the exact mapping depends on the word and the model. Some approximate examples:
TextApproximate tokens
"Hello"1
"Hello world"2
"anthropic"1
"Hello, how are you?"5
"def add(a, b):"7 (code tokens tend to be shorter)
Tokenization is not an exact science from the user's perspective. Different models use different tokenizers, and punctuation, whitespace, and rare words all affect the count. The numbers above are illustrative, not guaranteed.

4.2 Why Tokens Matter

Tokens affect your work in three concrete ways:

4.3 The Context Window

The context window is the total token budget for a single API call: every token in your system prompt, every message in the conversation history, the current user message, and the model's reply all count against it.
ModelMax input tokensDefault max output
claude-haiku-4-5-20251001200,0008,192
claude-sonnet-4-6200,0008,192
claude-opus-4-7200,0008,192
200K tokens is roughly 150,000 words - enough for an entire novel. For most coding tasks you will never approach this limit. However, long conversation histories grow token counts fast; see section 4.6. You can raise max_tokens above 8,192 for models that support extended output, but the default is sufficient for nearly all code generation tasks. Check the Anthropic documentation for the per-model ceiling.

4.4 The usage Field

Every response object includes a usage field with the actual token counts for that call. Reading it is the most reliable way to track cost.
# token_usage.py - print token counts after every API call.
import anthropic

client = anthropic.Anthropic()

def ask(prompt: str) -> str:
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=256,
        messages=[{"role": "user", "content": prompt}]
    )
    print(f"  input tokens : {response.usage.input_tokens}")
    print(f"  output tokens: {response.usage.output_tokens}")
    print(f"  stop reason  : {response.stop_reason}")
    return response.content[0].text

result = ask("Write a Python function that reverses a string.")
print(result)
response.usage.input_tokens counts every token the model read, including your prompt. response.usage.output_tokens counts every token the model generated.

4.5 Estimating Token Count Before a Call

Before sending a large request you may want to estimate whether it fits in the context window or how much it will cost. A rough rule: divide the character count by 4.
# estimate_tokens.py - rough pre-call token estimate.
import anthropic

def estimate_tokens(text: str) -> int:
    # Rough rule: ~4 characters per token for English text.
    return len(text) // 4

system_prompt = "You are a helpful Python tutor."
user_message  = "Explain how Python's list comprehension works with a detailed example."

total_text    = system_prompt + user_message
estimate      = estimate_tokens(total_text)
print(f"Estimated input tokens: {estimate}")

client   = anthropic.Anthropic()
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=256,
    system=system_prompt,
    messages=[{"role": "user", "content": user_message}]
)
print(f"Actual input tokens   : {response.usage.input_tokens}")
The estimate is intentionally approximate. Code, JSON, and non-English text tokenize differently from English prose. Use it for rough budget planning, not for precise billing predictions.

4.6 What Counts as Input Tokens

Every token the model reads on a call counts as input. In a multi-turn conversation that means:
# conversation_cost.py - show how history grows input tokens.
import anthropic

client   = anthropic.Anthropic()
messages = []

def turn(user_text: str) -> str:
    messages.append({"role": "user", "content": user_text})
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=128,
        messages=messages
    )
    reply = response.content[0].text
    messages.append({"role": "assistant", "content": reply})
    print(f"  input tokens this turn: {response.usage.input_tokens}")
    return reply

turn("What is a Python list?")
turn("How do I append to one?")
turn("What about removing duplicates?")
Watch the input token count grow with each turn even though each new user message is short. The entire history is re-sent on every call.

4.7 Exercise

Exercise Write a script that sends the same prompt - "Write a Python function that computes the Fibonacci sequence" - three times, each time with a different max_tokens value: 32, 128, and 512. After each call, print the stop_reason. Observe when the stop reason is "max_tokens" versus "end_turn". Note which max_tokens value is just barely enough to complete the function.

4.8 Common Mistakes

Setting max_tokens too low for code generation

Code is verbose. A function with a docstring, type hints, and a few lines of logic can easily require 150-300 tokens. Setting max_tokens=64 for a code request almost always produces truncated output. Start with at least 512 for code tasks and adjust downward only after measuring actual usage.

Forgetting that the full conversation history counts as input tokens

Each turn in a multi-turn conversation re-sends all prior messages. A 10-turn conversation where each turn averages 200 tokens accumulates roughly 2,000 input tokens by the last turn - even if you only typed a short question. Long histories add up and raise both latency and cost.

Confusing max_tokens with the context window limit

max_tokens caps the model's output. The context window caps the total of input plus output. You can hit the context window limit even with a small max_tokens if your input is very large. The two limits are independent constraints.

4.9 Key Terms

TermMeaning
tokenThe basic unit an LLM reads and generates; roughly 0.75 words on average
context windowThe total token budget (input + output) for a single API call
max_tokensParameter that caps how many tokens the model may generate in its reply
input_tokensToken count of everything the model read: system prompt + all messages
output_tokensToken count of the text the model generated
stop_reason"end_turn" means the model finished; "max_tokens" means it hit the cap
cost per tokenThe per-token price charged for input and output; check Anthropic pricing page for current rates