You are given a corpus of ten short documents and a search query. Build the search path end to end: embed the corpus, embed the query, score every document against the query, and print the top three results with their scores.
This is the same shape as a production search engine. The difference at scale is where the document vectors live (a vector database instead of a Python list) and how you find the nearest ones (an index instead of a full scan). The logic here is the logic that runs underneath both.
The query never says "password" or "locked," yet the account-recovery documents should surface at the top. The exact scores vary, but the ranking should look like this.
The corpus is embedded in one call before the query, which is what "embed once" means in practice: in a real system you would do this at index time and store the vectors, not on every search. Scoring is the same cosine comparison from the earlier exercises, applied across the whole corpus and then sorted to pull out the top three.
A search engine that always returns its closest match will confidently surface nonsense when nothing is actually relevant. Add a similarity threshold: if even the best match scores below it, return no result instead. This is the abstention behavior that keeps a system honest when the corpus has no answer.
threshold, return None; otherwise return the matched document.The on-topic query returns the account document; the off-topic one falls below the threshold and abstains.
The threshold turns similarity into a decision: above it, the match is trustworthy enough to return; below it, the honest answer is nothing. Without this gate, the off-topic pizza query would still return its nearest (irrelevant) document, which is how search systems end up giving confident wrong answers. Picking the threshold is empirical, you tune it on real queries, but the abstention pattern is what separates a usable search engine from one that always answers.