Course Wiki

Search — LLM Zoomcamp Module 1

--- video_url: 'https://www.youtube.com/watch?v=GYgpNKiuCJU&list=PL3MmuxUbc_hLZFNgSad56pDBKK8KO0XIv' code: - label: 'notebook.ipynb' path: 'code/notebook.ipynb' --- # Search

LLM Zoomcamp › Module 1: Agentic RAG › Search

Notes


video_url: “https://www.youtube.com/watch?v=GYgpNKiuCJU&list=PL3MmuxUbc_hLZFNgSad56pDBKK8KO0XIv” code:


# Search

Search basics

At its core, every search engine does the same thing. It takes a query, scores every document for similarity, and returns the top results.

Formally, there is a similarity function:

score = sim(query, document)

For each document in the database, you compute this score. Then you rank all documents by score and return the top N. What makes a search engine different from another search engine is what sim actually computes.

Consider these two questions:

They mean the same thing, but share almost no keywords. “Join” is not “enroll”, “course” is absent, “start date” is not “late”. A text search engine would struggle to match them, because it only sees words.

We’ll see how vector search solves this later. For now, let’s build text search with minsearch.

Indexing with minsearch

We already have the documents list from the previous section. Now let’s index it.

Searching matters because we have around 1100 documents. Sending all of them to the LLM would be expensive and slow. The model would get confused with too much data. Search finds the most relevant documents to send instead.

There are many search libraries you can use - Apache Lucene, Elasticsearch, Solr, and others. But these are somewhat heavy. For example, to run Elasticsearch, you need to start a Docker container.

minsearch is a simple in-memory search engine. It’s lightweight, so it runs anywhere Python runs, including Google Colab where you can’t start a Docker container. It’s a toy implementation, not production ready, but it illustrates how search engines work and it gives good results.

I should add a disclaimer: I wrote this library and I maintain it. It started as a single Python file in the first edition of LLM Zoomcamp. I wanted to show that keyword search isn’t magic. We wrote it together as part of the Build a Search Engine workshop (see the code).

It turned out useful beyond teaching. After two years across many projects, it’s pretty reliable for small datasets.

The concepts in minsearch are the same as in Elasticsearch (which comes from Lucene): text fields, keyword fields, boosting, filtering. I borrowed those terms from Elasticsearch on purpose, since I wanted a lightweight stand-in for it. So what you learn here transfers directly.

We’ll index the question, section, and answer fields as text (they’ll be tokenized and ranked), and the course field as a keyword (for filtering).

The index tokenizes text fields and treats keyword fields as exact strings.

Text fields are the fields you search through. When you type a query, the search engine looks at these fields and tokenizes them. It splits text into words, lowercases them, removes stop words, and ranks the results by relevance. So question, section, and answer are text fields.

Keyword fields are for exact matching. Think of a SQL query like SELECT * FROM index WHERE course = 'data-engineering-zoomcamp'. The results must come from the specified course, no matter what ranking or boosting you do for text fields.

You use keyword fields to restrict the search space to a particular subset. In our case, we have four courses. Say you’re taking the LLM course and ask a question. You don’t w

Key concepts

Sources


DataTalks.Club. Hosted on GitHub Pages. Built with Rustkyll. We use cookies.