AI Engineer Portal
Your personal operating system for career transition.
Exercise
Count tokens accurately for prompt budget management
Count Tokens Accurately for Prompt Budget Management
Token counting is a foundational skill in AI engineering. You need it to prevent context window overflow, to estimate request costs before sending them, and to enforce token budgets when assembling prompts with multiple components. The naive approach — counting words or characters — is wrong often enough to cause real problems.
What to build
Implement a PromptBudget class that manages a token budget for assembling multi-component prompts:
-
PromptBudget(total_tokens: int, reserve_output: int)— initialize with a total context window and an output reservation. The available budget istotal_tokens - reserve_output. -
count(text: str) -> int— use a simple approximation:len(text.split())counts words, then multiply by 1.3 to approximate token count (tokens average ~0.77 words for English technical text). Round up. -
fits(text: str) -> bool— returnTrueif the text would fit in the remaining budget. -
consume(label: str, text: str) -> bool— if the text fits, deduct its token count from the budget, record the label and count, and returnTrue. If it does not fit, returnFalsewithout modifying the budget. -
remaining() -> int— return the number of tokens still available. -
summary() -> dict— return a dict of{label: token_count}for all consumed components, plus a"remaining"key. -
fit_chunks(chunks: list[str]) -> list[str]— given a list of chunks in priority order, return as many as fit in the remaining budget (greedy, no splitting).
Why this matters
Context overflow exceptions are a runtime surprise. A PromptBudget that tracks consumption at assembly time gives you the overflow check before the API call, not after. The summary() method gives you the data to log which components are eating your budget.
Constraints
- Use
math.ceilfor rounding up token counts. - Do not use
tiktokenor any external tokenizer — the word-based approximation is sufficient for this exercise. - The budget should be stateful: multiple
consumecalls reduce the remaining budget cumulatively.
Python Refresh / medium / Step 15 of 16
Core runtime habits
Normalize the boundary first, keep return shapes stable, and make the middle of the function boring on purpose.
- - Returns one stable shape across branches
- - Makes failure handling obvious
- - Keeps the core logic readable in under a minute
- - Did I make the input and output shapes explicit?
- - Would a teammate know where validation happens?
- - Did I avoid silent mutation or vague branching?
Practice
Generate a variation
Generate a new exercise variation to deepen understanding or practice a related concept.
Attempt history
Recent submissions
Before you submit, decide what a strong answer should make obvious to the reviewer.
No attempts yet.