{ "lesson": "51-literature-retrieval", "title": "Literature Retrieval", "questions": [ { "stage": "pre", "question": "Why does the retrieval client run a BM25 pass and a citation graph pass?", "options": [ "Because the mock APIs require it", "Because the parser fails otherwise", "Because BM25 needs the graph to build its index", "Because lexical hits miss foundational papers with different vocabulary, and graph hits miss papers that share no citation with the seed" ], "correct": 3, "explanation": "Each pass catches what the other misses. Lexical covers shared vocabulary; the graph covers ancestor and descendant papers regardless of vocabulary." }, { "stage": "pre", "question": "Why is the citation graph traversal capped at two hops?", "options": [ "Because the Python recursion limit forbids three hops", "Because beyond two hops the result set tends to drift off topic and overwhelm downstream ranking", "Because BM25 only scores two hops away", "Because the corpus only stores two layers of citations" ], "correct": 1, "explanation": "Two hops is the practical ceiling. Three hops blows up the result set on a connected graph and rarely returns more on topic papers." }, { "stage": "check", "question": "What does idf evaluate to for a term that appears in every document?", "options": [ "Negative infinity", "A large positive value", "Undefined; the BM25 implementation skips it", "A value near zero" ], "correct": 3, "explanation": "When df equals N the numerator and denominator inside the log are close, and the +1 keeps the term non negative but small. The contribution of universally common terms is near zero." }, { "stage": "check", "question": "Which keys does the merge step use to dedup hits from the two passes?", "options": [ "BM25 score bucket", "Stable paper id", "Year and first author", "Title text" ], "correct": 1, "explanation": "Paper id is the stable handle. Title and author are duplicated across versions, year alone is ambiguous." }, { "stage": "check", "question": "What does graph_score return for a paper that is two hops from the seed set?", "options": [ "The BM25 score divided by ten", "0.3 by default", "1.0 by default", "Zero" ], "correct": 1, "explanation": "The default graph score schedule is 1.0 at zero hops, 0.6 at one hop, 0.3 at two hops, and zero beyond that." }, { "stage": "check", "question": "Why is the corpus loaded once into a RetrievalClient instead of refetched per query?", "options": [ "Because the recency score requires it", "Because the BM25 index and citation graph are built once at construction time and reused across queries", "Because the mock APIs are slow on every call", "Because the parser is global" ], "correct": 1, "explanation": "Index construction is the expensive step. Reusing the index amortises that cost across every query the client handles." } ] }