Where we left off
Lesson 8 asked "What is the capital of France?" against a document with nothing to do with France, and top-k retrieval still returned its best k chunks anyway, because top-k only ever asks "which of these is most similar," never "is any of these similar enough to be worth using." That gap is exactly what a similarity threshold closes.
A threshold changes the question retrieval answers
Without a threshold, retrieval answers: "of everything I have, here are the k closest matches." With a threshold, it answers a stricter question: "of everything I have, here are the closest matches, but only the ones that clear this bar." If nothing clears the bar, it can correctly return nothing at all, rather than a false top match.
Where does the bar come from? Lesson 3's own experiment already measured a real data point: an unrelated sentence scored roughly 0.50 against a related query on this same embedding model. MIN_SCORE = 0.55 in this lesson is chosen to sit just above that observed "unrelated" baseline, not from a formula, there isn't a universal "good" cosine similarity threshold, it depends on the embedding model and the specific documents, and is usually tuned empirically like this.
The code, piece by piece
above_threshold = [record for record in scored if record["score"] >= min_score]return above_threshold[:k]The threshold filter runs after sorting by score, not instead of it: first find the best matches available, in order, then drop whichever ones don't clear min_score, then take up to k of what's left. Doing it in the other order (filter first, then you'd lose the ranking) would give you an arbitrary subset instead of the best available subset.
Checkpoint
- similarity threshold: a minimum score a retrieved chunk must clear to be used at all, letting retrieval honestly return "nothing relevant" instead of always returning
kresults. - Thresholds are tuned empirically against your own embedding model and documents, not derived from a universal formula.
- Filter after ranking, not before, to make sure a threshold drops the worst matches specifically, not an arbitrary subset.
If anything here still feels unclear, ask before moving to Lesson 15.