Pick the soft-budget allocation pattern that survives a long RAG conversation
Same topic, related formats. Practice these next.
Same topic, related formats. Practice these next.
Reserve floors for the non-negotiable slots (system, memory, schema) and let retrieval and history compete for the residual pool under an explicit eviction policy.
Imagine packing a small suitcase for a week-long trip. You always need a toothbrush, your passport, and one warm layer, those go in first, every trip. The remaining space is contested by clothes, books, and snacks, and you have a rule for what gets pulled when the zipper will not close. Maybe books lose first, then snacks, then a second outfit. A context budget works the same way. Some slots are non-negotiable: the system prompt, user memory, the output schema. Those get protected floors. Everything else, retrieved documents, older chat history, competes for the leftover room, and you write down what gets cut first when the suitcase fills.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
6 minutes: why fixed splits fail, the three-tier structure, the contested pool and its weights, and the explicit eviction order.
def allocate_budget(total: int, slots: dict, signals: dict) -> dict:
# Tier 1: protected floors
floors = {
'system': slots['system_size'],
'memory': slots['memory_size'],
'schema': slots['schema_size'],
'response': 1024, # response reserve
}
floor_total = sum(floors.values())
residual = total - floor_total
if residual < 0:
raise BudgetError('floors exceed total budget')
# Tier 2: contested pool, signal-weighted
retrieval_weight = max(0.3, min(0.8, signals['rerank_top1']))
history_weight = 1.0 - retrieval_weight
contested = {
'retrieval': int(residual * retrieval_weight),
'history': int(residual * history_weight),
}
return {**floors, **contested}
# Eviction policy: oldest summary first, then lowest-rerank chunk
def evict(over_by: int, packed: dict) -> dict:
while over_by > 0:
if packed['history_summary_tail']:
over_by -= drop_oldest_summary(packed)
elif packed['retrieval_chunks']:
over_by -= drop_lowest_rerank(packed)
else:
zero_out_bleed_pool(packed)
break
return packedReal products, models, and research that use this idea.
What an interviewer would ask next. Try answering before peeking at the approach.
Red flags and common mistakes that signal junior thinking. Click to expand.
Hard-coding equal splits across slots. Light turns waste budget on a half-empty retrieval slot; heavy turns starve when the schema needs more than its share.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.