Most old search bars only match keywords, looking for the exact words you type. But people think in ideas, not just words. Today, we’ll build a smart search feature, a Semantic Search Engine. This is the technology behind Google Search and modern RAG pipelines. Let’s get started.
Build a Smart Search with Python
Before we start coding, let’s look at the main idea. How can we help a computer understand that an apple is more like a banana than a car?
Picture a huge 3D map where similar ideas are grouped together. Fruits are in one area, vehicles in another, and programming languages in a different spot.
In data science, this is called vector embedding. We take text, like a headline, and use an AI model to turn it into a list of numbers, a vector. These numbers show where the text sits on our map.
When someone searches, we don’t just look for matching words. Instead, we turn their question into coordinates and find which documents are closest on the map.
Now, let’s start building a smart search feature in Python.
Step 1: Setting Up the Database
First, we need some data to search. In real projects, this might be a SQL database or a CSV file with millions of rows. For now, we’ll use a small list of articles about topics like coding and cooking:
import pandas as pd
# Our "Database" of articles
data = [
{'title': 'Python for Beginners', 'content': 'Learn the basics of Python programming, loops, and functions.'},
{'title': 'Machine Learning 101', 'content': 'An introduction to neural networks and supervised learning.'},
{'title': 'Healthy Cooking Tips', 'content': 'How to cook nutritious meals quickly using fresh ingredients.'},
{'title': 'Best Laptops of 2026', 'content': 'Reviews of the top computing devices for work and gaming.'},
{'title': 'The Future of AI', 'content': 'Discussing Large Language Models and the ethics of artificial intelligence.'},
{'title': 'Yoga for Stress', 'content': 'Simple stretches and breathing exercises to relax.'}
]
df = pd.DataFrame(data)
print("Data loaded successfully!")
print(df.head())Data loaded successfully!
title content
0 Python for Beginners Learn the basics of Python programming, loops,...
1 Machine Learning 101 An introduction to neural networks and supervi...
2 Healthy Cooking Tips How to cook nutritious meals quickly using fre...
3 Best Laptops of 2026 Reviews of the top computing devices for work ...
4 The Future of AI Discussing Large Language Models and the ethic...
Notice that the titles and content are separate. We’ll combine them in the next step, since search engines work better with more context.
Step 2: Generating Embeddings
Now it’s time to use AI. We’ll use a model called all-MiniLM-L6-v2.
This is a Mini model, so it’s fast and works well on a regular laptop. You don’t need a powerful GPU server for this:
from sentence_transformers import SentenceTransformer
import numpy as np
# Load the pre-trained model
# This will download about 80MB the first time you run it
print("Loading model...")
model = SentenceTransformer('all-MiniLM-L6-v2')
# Combine title and content for better context
# We want to search across both the headline and the body text
sentences = df['title'] + ': ' + df['content']
# Generate embeddings
print("Encoding data...")
embeddings = model.encode(sentences.tolist())
print(f"Shape of embeddings: {embeddings.shape}")Encoding data...
Shape of embeddings: (6, 384)
The embeddings.shape output will likely be (6, 384).
- 6: We have 6 documents.
- 384: Each document is now a list of 384 numbers. These numbers are its coordinates on our map.
Step 3: Indexing with FAISS
A list of vectors works for 6 documents, but what if you have 6 million? Checking each one by one would be far too slow.
That’s where FAISS helps. You can think of FAISS as a super-efficient filing cabinet for vectors. It organizes the data so you can find what you need almost instantly:
import faiss
# FAISS works with float32 type
embeddings = np.array(embeddings).astype("float32")
# Create the index
# 384 is the dimension of the vectors from the MiniLM model
index = faiss.IndexFlatL2(384)
# Add our embeddings to the index
index.add(embeddings)
print(f"Total documents in index: {index.ntotal}")Total documents in index: 6
We’re using IndexFlatL2, which measures L2 (Euclidean) distance. The closer two points are, the more similar they are.
Step 4: The Search Function
Now we connect the user to the data. When someone searches, we need to:
- Convert their query into a vector (using the same model).
- Ask FAISS to find the nearest neighbours.
- Return the readable text.
def search(query, k=3):
# 1. Encode the query
query_vector = model.encode([query])
# 2. Search the index
# k is the number of results we want
distances, indices = index.search(np.array(query_vector).astype("float32"), k)
# 3. Format results
results = []
for i in range(k):
idx = indices[0][i]
# FAISS returns -1 if it can't find neighbors (unlikely here)
if idx != -1:
result = {
'title': df.iloc[idx]['title'],
'content': df.iloc[idx]['content'],
'score': float(distances[0][i]) # Lower score = closer distance = better match
}
results.append(result)
return resultsStep 5: Testing
Now, let’s test if our search engine is truly smart or just guessing:
# Test 1: Keyword mismatch
print("\n--- Test Query: 'computer for gaming' ---")
results = search("computer for gaming")
for res in results:
print(f"Found: {res['title']}")
# Test 2: Conceptual search
print("\n--- Test Query: 'how to relax' ---")
results = search("how to relax")
for res in results:
print(f"Found: {res['title']}")
# Test 3: Technical search
print("\n--- Test Query: 'coding tutorial' ---")
results = search("coding tutorial")
for res in results:
print(f"Found: {res['title']}")
--- Test Query: 'computer for gaming' ---
Found: Best Laptops of 2026
Found: Python for Beginners
Found: Machine Learning 101
--- Test Query: 'how to relax' ---
Found: Yoga for Stress
Found: Healthy Cooking Tips
Found: Best Laptops of 2026
--- Test Query: 'coding tutorial' ---
Found: Python for Beginners
Found: Machine Learning 101
Found: The Future of AI
If you run this code, you’ll see it finds the right articles every time. You’ve built a search engine that understands intent, not just words.
Closing Thoughts
That’s how you can build a smart search feature using semantic search.
In the industry, this is the base for modern AI apps. Whether you’re making a RAG chatbot for your PDFs, a Netflix recommendation system, or Amazon’s product search, it all begins with embeddings and vector search.
If you found this article helpful, you can follow me on Instagram for daily AI tips and practical resources. You may also be interested in my latest book, Hands-On GenAI, LLMs & AI Agents, a step-by-step guide to prepare you for careers in today’s AI industry.





