A cache keyed by model and content, with batching
FNV-1a is a small hash chosen so the three languages agree without libraries. Use SHA-256 in real code (hashlib in Python, MessageDigest in Java, the Web Crypto API or node:crypto in JavaScript).
AskDocs version 2: an Embedder interface that the rest of the product depends on, a toy embedder behind it, vectors for the whole handbook, retrieval by cosine, and a cache keyed by content and model so nothing is embedded twice.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write retrieve(question, k, min_score) over a dict VECTORS of id to unit vector, with a function embed(text) given. Return (id, score) pairs best first. Use the tiny two-direction table in the answer and print the result for the question 'password help'.
Write content_key(model_name, text) that returns model_name + ":" + sha256 hex of text and print the first 12 characters of the hash for 'Helmets' and for 'helmets'. What does it tell you about cache keys?
Explain it without notes
Why does AskDocs hide the embedding step behind an Embedder interface?
What does the cache key consist of, and why each part?
What changed in retrieve between version 0 and version 2, and what stayed the same?
In the trace, why does the pass-price question retrieve three sources? Is that a problem?
Expected output
hash of 'Helmets': 222ddd49
first run : 2 requests, 6 texts sent, 0 cache hits, 7 vectors returned
same texts again : 0 requests, 0 texts sent, 7 cache hits, 7 vectors returned
one text edited : 1 requests, 1 texts sent, 6 cache hits, 7 vectors returned
model switched : 2 requests, 6 texts sent, 0 cache hits, 7 vectors returned