Building AI-Powered Search with Semantic Retrieval
Replace keyword search with intelligent semantic understanding
Building AI-Powered Search with Semantic Retrieval
Replace keyword search with intelligent semantic understanding
Learn to build semantic search systems using embeddings, vector databases, and re-ranking. Covers hybrid search combining BM25 with dense retrieval for production search applications.
AI-Powered Semantic Search
Why Semantic Search?
Traditional keyword search fails when:Architecture Overview
Building with OpenAI Embeddings
python
import openai
import numpy as np
from sklearn.metrics.pairwise import cosine_similaritydef embed_texts(texts):
response = openai.embeddings.create(
model="text-embedding-3-large",
input=texts
)
return [r.embedding for r in response.data]
Index documents
docs = ["Python is a programming language", "Machine learning uses data"]
doc_embeddings = embed_texts(docs)Search
query_embedding = embed_texts(["coding with Python"])[0]
similarities = cosine_similarity([query_embedding], doc_embeddings)[0]
top_idx = np.argsort(similarities)[::-1][:5]
Hybrid Search with BM25 + Dense Retrieval
python
from rank_bm25 import BM25Okapi
from pinecone import Pineconeclass HybridSearch:
def __init__(self, documents):
self.docs = documents
self.bm25 = BM25Okapi([d.split() for d in documents])
self.pc = Pinecone(api_key="...")
self.index = self.pc.Index("docs")
self._index_documents()
def search(self, query, alpha=0.5, top_k=10):
# BM25 scores
bm25_scores = self.bm25.get_scores(query.split())
# Dense retrieval scores
query_vec = embed_texts([query])[0]
dense_results = self.index.query(vector=query_vec, top_k=top_k)
# Combine scores
combined = alpha * normalize(bm25_scores) + (1-alpha) * normalize(dense_scores)
return sorted(range(len(combined)), key=lambda i: combined[i], reverse=True)[:top_k]
Re-ranking with Cross-Encoders
python
from sentence_transformers import CrossEncoderreranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')
def rerank(query, candidates, top_k=5):
pairs = [(query, c) for c in candidates]
scores = reranker.predict(pairs)
ranked = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True)
return [c for c, _ in ranked[:top_k]]
Production Considerations
相关工具
相关教程
Build complex multi-step AI workflows with state management using LangGraph
Chain-of-thought, tree-of-thoughts, self-consistency, and systematic evaluation methods
Deploy Llama 3 with 20x higher throughput than naive serving