Build a semantic search engine that understands meaning
Keyword search looks for the words you typed. Ask it "how do I protect my laptop on public wifi" and it never finds the note about VPNs, because that note says "encrypted tunnel" and "untrusted network" instead. In this mission you build a search that matches on meaning, so it finds that note anyway. Every piece runs on your own laptop with a small model and no graphics card.
- uv, the Python runner used across this site. It fetches Python for you. If you have not got it, Install anything from GitHub safely (Level 0) has the one-line install.
- You can read a little Python. You do not write any from scratch: every file is complete and in the kit. Run a ChatGPT-style AI on your own laptop is a gentle warm-up if this is your first local-AI lesson.
- A few GB of free disk space. Almost all of it is PyTorch, which the embedding model runs on; the model itself is about 90MB, and the project's other packages are small.
- No graphics card, no accounts, no API keys, nothing to pay for. The model runs on your processor.
Why meaning beats keywords, and see it in ten minutes
Keyword search matches letters. Meaning search matches sense. Get the whole thing running first, then take it apart.
Every search box you have ever used, from a text editor to a wiki, works the same way: it looks for the words you typed. Type "wifi" and it finds pages with "wifi" on them. That breaks the moment the page uses different words for the same idea. A note explaining how a VPN keeps you safe on a cafe network might never contain the words "wifi", "laptop" or "protect", so a keyword search for "how do I protect my laptop on public wifi" walks straight past the one note that answers it.
A semantic search fixes that. It turns each passage into a list of numbers that stands for its meaning, does the same to your question, and returns the passages whose meaning sits closest. This mission builds that, end to end, over a folder of plain notes. It is deliberately not a chatbot: there is no model writing answers, no made-up text, nothing to upload. It is the retrieval engine that sits underneath tools like Build your own "chat with my files" app, shown on its own so you can see exactly how it ranks things.
Download the four kit files into a new folder. Save search.py, scale_sqlite.py and requirements.txt in the folder itself, and notes.md inside a sub-folder called
corpus. Then set it up and run the headline comparison:Windowscd $HOME\Documents mkdir semantic-search; cd semantic-search # put search.py, scale_sqlite.py and requirements.txt here, and notes.md in a corpus\ sub-folder uv venv --python 3.13 uv pip install -r requirements.txt uv run search.py build uv run search.py compare "how do I protect my laptop on public wifi"Mac / Linuxcd ~/Documents mkdir semantic-search && cd semantic-search # put search.py, scale_sqlite.py and requirements.txt here, and notes.md in a corpus/ sub-folder uv venv --python 3.13 uv pip install -r requirements.txt uv run search.py build uv run search.py compare "how do I protect my laptop on public wifi"buildcuts the notes into chunks and turns each one into numbers (the first run downloads the 90MB model, so give it a minute).comparethen runs the same question two ways, keyword first, meaning second:OutputKEYWORD "how do I protect my laptop on public wifi" 1. 1.601 notes.md #7 ## Why a laptop feels slow Most of the time the disk is the bottleneck, not the processor.... 2. 0.000 notes.md #1 # Field notes: staying private and keeping your computer working FICTIONAL SAMPLE DOCUMENT... 3. 0.000 notes.md #3 ## Password managers A password manager invents a long random secret for every account and... MEANING "how do I protect my laptop on public wifi" 1. 0.425 notes.md #2 ## Tunnelling your traffic on an untrusted network A virtual private network routes everyt... 2. 0.139 notes.md #3 ## Password managers A password manager invents a long random secret for every account and... 3. 0.097 notes.md #1 # Field notes: staying private and keeping your computer working FICTIONAL SAMPLE DOCUMENT...That is the whole point of the lesson in one screen. Keyword search put the note titled "Why a laptop feels slow" on top, because it contains the word "laptop", and then scored 0.000 for everything else: it could not see the VPN note at all. Meaning search put the VPN note ("Tunnelling your traffic on an untrusted network") first, even though that note never says wifi, laptop or protect. The rest of the lesson takes this apart so you can tune it and point it at your own notes.
TipThe scores in the two blocks are not on the same scale and should not be compared with each other. Keyword scores (BM25) have no fixed ceiling; meaning scores (cosine) run from about -1 to 1. Each column ranks within itself. Step 5 reads both properly.
notes.md #2 (the tunnelling note) first, and the KEYWORD block scores it nowhere.If it breaks'uv' is not recognised + 2 more
'uv' is not recognised
winget install --id astral-sh.uv -e (Windows) or curl -LsSf https://astral.sh/uv/install.sh | sh (Mac or Linux), then open a new terminal. Full walkthrough in Install anything from GitHub.'No .md or .txt files in ...corpus'
notes.md is in the wrong place. It must be inside a corpus sub-folder of the project, not next to search.py. Make the folder and move it there.