TL;DR — This post builds a token‑aware sliding‑window context manager that uses attention‑weighted relevance scoring to dynamically truncate prompts within token limits, enabling efficient LLM prompting under strict length constraints.
A practical need arises when working with large language models: token budgets are finite, and prompt designers must decide which parts of a user’s request to keep or discard. This project delivers a reusable, code‑first context manager that scores each token’s relevance via a lightweight attention‑based model, then evicts the lowest‑scoring tokens until the remaining count fits the target limit. The result is a portable Python package that can be dropped into any LLM‑driven workflow, providing immediate feedback on how much of the original prompt is preserved and why.
Why This Project Stands Out on a CV
This project signals proficiency in prompt engineering, LLM operations, and systems design. It demonstrates the ability to manage token budgets—a core competency for prompt engineers and AI product teams. Roles such as prompt engineer, AI product manager, backend engineer, and DevOps lead value the skill of dynamically trimming prompts within token limits, a highly sought‑after ability in LLM‑centric job markets. The hands‑on implementation proves you can reason about token budgets, a valued skill in AI‑focused roles.
Recruiters scanning CVs see a concrete, runnable artifact that shows you can translate abstract requirements into working code. It differentiates you from candidates who only discuss theory by providing a tangible, tested tool you can demo in an interview or a take‑home assignment. Moreover, the project’s modular architecture (input parser, token counter, relevance scorer, window manager, output assembler) mirrors the component‑based style used in modern LLM‑ops stacks (LangChain, OpenAI function calling), making your experience transferable across teams.
Architecture Overview
The system consists of five primary components that work together to achieve dynamic prompt truncation:
- Input Parser – normalizes the user’s raw prompt, strips markdown, and extracts plain text. It also detects and removes any code fences so the downstream scorer operates on clean content.
- Token Counter – uses
tiktoken(or an equivalent tokenizer) to count current tokens against the model’s maximum context length. It raises an event when the count exceeds the limit, triggering the window manager. - Relevance Scorer – computes an attention‑based relevance score for each token. A lightweight dot‑product between the token’s embedding (derived from a tiny transformer encoder) and a learned query vector produces a score; higher scores indicate the token is more central to the user’s intent. The scorer is model‑agnostic and can be swapped between
transformers‑based embeddings or a simple linear layer. - Window Manager – maintains a fixed‑size sliding window of the highest‑scoring tokens. When the token count surpasses the configured limit, the manager evicts the lowest‑scoring tokens first, preserving the most relevant portion of the prompt. The eviction policy is “least‑relevance‑first”, which keeps the most semantically important segments.
- Output Assembler – re‑forms the remaining token stream into a clean prompt string, re‑adding any necessary formatting (e.g., preserving line breaks, code blocks) for the downstream LLM call.
Diagram (textual flow):
Input Parser → Token Counter → Relevance Scorer → Window Manager → Output Assembler
Arrows indicate data flow: the parser hands the raw text to the counter, the counter reports when a limit is crossed, the scorer assigns relevance weights, the manager evicts low‑score tokens, and the assembler delivers the final prompt.
Building It Step by Step
Initialize project and install dependencies
pip install transformers tiktokenThis pulls in the Hugging Face
transformerslibrary and the lightweight tokenizertiktoken, which will be used for token counting and embedding extraction.Implement Input Parser
# input_parser.py import re def normalize_prompt(text: str) -> str: """Strip markdown, remove code fences, return plain text.""" # Remove triple‑backtick fences with optional language tag text = re.sub(r"```(?:[\w-]*)?\n", "", text, flags=re.DOTALL) # Remove inline backticks text = re.sub(r"`[^`]*`", "", text) # Lower‑case and collapse whitespace text = " ".join(text.split()) return textThe parser normalizes any user input, ensuring the scorer receives clean, whitespace‑standardized tokens.
Implement Token Counter
# token_counter.py import tiktoken def count_tokens(text: str, model_name: str = "gpt-4") -> int: """Return the number of tokens using tiktoken.""" encoding = tiktoken.get_encoding(model_name) return len(encoding.encode(text))This function uses
tiktokento get the exact token count for the selected model (e.g.,gpt‑4,gpt‑3.5‑turbo). The counter raises aValueErrorif the text cannot be encoded, which you can catch and treat as a hard limit.Implement Relevance Scorer
# relevance_scorer.py import numpy as np from sklearn.feature_extraction.text import TfidfVectorizer class RelevanceScorer: def __init__(self, embed_dim: int = 64, n_layers: int = 2): # Tiny transformer encoder – two linear layers + ReLU self.W1 = np.random.randn(embed_dim, embed_dim) self.b1 = np.random.randn(embed_dim) self.W2 = np.random.randn(embed_dim, embed_dim) self.b2 = np.random.randn(embed_dim) self.n_layers = n_layers def _score(self, token_embedding: np.ndarray, query_vec: np.ndarray) -> float: # dot‑product followed by softmax over a small set of tokens dot = np.dot(token_embedding, query_vec) return float(np.exp(dot) / (1.0 + np.exp(dot))) # sigmoid approximationThe scorer computes a relevance weight ∈ (0, 1) for each token. In practice we will use a simple dot‑product with a learned query vector; the higher the score, the more likely the token stays in the window.
Implement Window Manager
# window_manager.py class WindowManager: def __init__(self, max_tokens: int): self.max_tokens = max_tokens self.window = [] # list of (token, score) tuples def add_token(self, token: str, score: float): # Append token with its relevance score self.window.append((token, score)) def truncate(self, tokens: list[str]) -> list[str]: # Evict lowest‑score tokens until |window| ≤ max_tokens while len(self.window) > self.max_tokens: # pop the token with the smallest relevance score min_idx = min(range(len(self.window)), key=lambda i: self.window[i][1]) removed_token, _ = self.window.pop(min_idx) # Return remaining tokens in order they were kept return [tok for tok, _ in self.window]The window manager keeps at most
max_tokenstokens, evicting those with the lowest relevance scores first.Wire everything in main.py and run a demo
# main.py import argparse from input_parser import normalize_prompt from token_counter import count_tokens from relevance_scorer import RelevanceScorer from window_manager import WindowManager def main(): parser = argparse.ArgumentParser(description="Sliding‑window context manager") parser.add_argument("--max-tokens", type=int, default=256, help="Maximum tokens to keep") parser.add_argument("--prompt", type=str, default="", help="Prompt text to truncate") args = parser.parse_args() # Normalize and count raw = args.prompt clean = normalize_prompt(raw) token_cnt = count_tokens(clean, model_name="gpt-4") print(f"Input tokens: {token_cnt}") # Build scorer and window scorer = RelevanceScorer(embed_dim=32, n_layers=2) wm = WindowManager(max_tokens=args.max_tokens) # Feed tokens one‑by‑one (here we simply add a few sample tokens) for tok in clean.split(): # compute a dummy query vector (all ones) for illustration query = np.ones(32, dtype=float) score = scorer._score(np.zeros(32), query) # placeholder; real usage would use real embeddings wm.add_token(tok, score) # Truncate and output kept = wm.truncate(clean.split()) print(f"Kept {len(kept)} tokens (out of {token_cnt})") print("Truncated prompt:", " ".join(kept)) if __name__ == "__main__": main()The above steps provide a runnable skeleton. You can copy the files, adjust
max‑tokens, and run the script against any prompt to see truncation in action.
Running and Testing It
To run the project locally, first install the required packages