Solving tips
- Retrieval hands you more chunks than you can afford. The prompt has a hard token ceiling, so packing is a budgeting problem, not a ranking one.
- Rank order encodes relevance. Greedily take the best chunks first; a chunk that does not fit is skipped, not truncated, so you never ship half a passage.
- Decide up front what happens when a chunk overflows: stop entirely, or skip it and keep trying smaller later ones. State the choice — an interviewer will ask why.
Retrieval gives you a ranked list of candidate chunks, but the model prompt has a hard token ceiling. You cannot send everything, so you have to choose a subset that fits. This exercise is the packing step that sits between the retriever and the prompt: take the best chunks you can afford, in order, and report how much of the budget you spent.
How the packing works
The chunks arrive already sorted by relevance, best first. You walk them in that order, keeping a running total of the token_count you have committed to. For each chunk you ask a single question: would adding it push the running total past max_tokens?
- If it still fits (
used + token_count <= max_tokens), select it and add its tokens to the running total. - If it does not fit, skip it and keep going. A later chunk may be small enough to slot into the remaining space.
You never truncate a chunk to make it fit and you never reorder — a half-passage is worse than no passage, and rank order is the relevance signal. The separator that glues chunks together is presentation only and does not count against the budget.
Task
Complete assemble_context(chunks, max_tokens, separator="\n\n"):
- Iterate
chunksin the given rank order, trackingused_tokens(start at 0) and a list of selected texts. - For each chunk, select it only if
used_tokens + chunk["token_count"] <= max_tokens; then add itstoken_counttoused_tokens. - If a chunk would overflow, skip it and continue to the next one (the skip-and-continue policy).
- Return
(context, used_tokens)wherecontextis the selected texts joined byseparatorin rank order.
Example
chunks = [
{"text": "alpha", "token_count": 40},
{"text": "bravo", "token_count": 30},
{"text": "charlie", "token_count": 50}, # would overflow, skipped
{"text": "delta", "token_count": 20},
]
assemble_context(chunks, max_tokens=100)
# -> ("alpha\n\nbravo\n\ndelta", 90)
# alpha(40) + bravo(70) fit; charlie(120) overflows and is skipped;
# delta(90) fits in the leftover room.
assemble_context([], max_tokens=100)
# -> ("", 0)
Constraints
- Preserve rank order in the output; do not sort by size or reorder to pack tighter.
- Never truncate a chunk’s text — a chunk is taken whole or not at all.
- The separator does not count against
max_tokens; onlytoken_countvalues do. - Handle an empty chunk list and a budget too small for any chunk by returning
("", 0). - A single chunk larger than
max_tokensis simply never selected.