Módulo 3: Features Esenciales para RAG
Cápsula 03: Hybrid Search (Keyword + Semantic)
🎯 Objetivo de la cápsula
Entender POR QUÉ pure semantic search falla en ciertos queries, cómo hybrid search (BM25 + vector) mejora accuracy 15-20%, y cuándo usar cada estrategia.
Al finalizar esta cápsula:
- ✅ Explicarás limitaciones de pure semantic search
- ✅ Entenderás cómo hybrid search combina keyword + semantic
- ✅ Compararás ranking strategies (RRF, weighted fusion)
- ✅ Decidirás cuándo usar hybrid vs pure semantic
Tiempo estimado: 10-12 minutos
🔍 Problema: Pure Semantic Search falla en queries específicos
¿Qué es semantic search?
Semantic search = Buscar por significado (embeddings) en lugar de palabras exactas.
Ejemplo:
Query: "automobile repair"
Embedding: [0.2, 0.5, 0.8, ...]
Top results (semantic):
1. "Car maintenance guide" ✅ (similar meaning)
2. "Vehicle troubleshooting" ✅ (similar meaning)
3. "How to fix your vehicle" ✅ (similar meaning)
Ventaja: Encuentra documentos conceptualmente similares (no solo exact keyword match).
Pero... semantic search falla en queries específicos
Problema 1: Nombres propios
Query: "GPT-4 API documentation"
Embedding: [0.1, 0.7, 0.3, ...]
Pure semantic results:
1. "OpenAI models overview" ⚠️ (menciona GPT-3, Claude)
2. "API integration guide" ⚠️ (general, no GPT-4)
3. "Language model comparison" ⚠️ (GPT-3 vs PaLM)
Expected:
1. "GPT-4 API reference" ← Falta porque "GPT-4" no dominó embedding
Por qué falla: "GPT-4" es nombre propio (token específico), pero embedding captura concepto general "language model API".
Problema 2: IDs, códigos, números exactos
Query: "Invoice #INV-2024-001234"
Pure semantic results:
1. "Invoice management guide" ❌
2. "Billing documentation" ❌
3. "Payment processing" ❌
Expected:
1. Invoice #INV-2024-001234 ← Falta porque embedding no captura ID exacto
Por qué falla: Embeddings no están diseñados para capturar strings exactos (son representaciones semánticas).
Problema 3: Queries con typos o variantes exactas
Query: "PostgreSQL"
Pure semantic results:
1. "Database management" ✅ (general)
2. "SQL tutorial" ✅ (general)
3. "MySQL guide" ⚠️ (diferente DB!)
Falta:
- "PostgreSQL installation" ← Debería ser #1
Por qué falla: Embedding de "PostgreSQL" y "MySQL" son similares (ambos son SQL databases).
🔀 Solución: Hybrid Search (BM25 + Vector)
¿Qué es hybrid search?
Hybrid search = Combinar keyword search (BM25) + semantic search (vector) para obtener best of both worlds.
Keyword search (BM25):
- Encuentra exact keyword matches
- Excelente para nombres propios, IDs, códigos
- Pésimo para sinónimos, conceptos
Semantic search (Vector):
- Encuentra similar concepts
- Excelente para queries conceptuales
- Pésimo para exact matches
Hybrid = Keyword + Semantic:
- Combina resultados de ambos
- Rank usando fusion algorithm (RRF, weighted)
Arquitectura de Hybrid Search
User Query: "GPT-4 API documentation"
│
├─────────────────┬─────────────────┐
↓ ↓ ↓
[Keyword Search] [Semantic Search]
(BM25) (Vector HNSW)
│ │
1. GPT-4 docs 1. OpenAI API guide
2. API reference 2. LLM integration
3. OpenAI guide 3. GPT-3 docs
│ │
└─────────────────┴─────────────────┐
↓
[Fusion Algorithm]
(RRF or Weighted)
↓
Merged Top-10:
1. GPT-4 API docs ✅
2. OpenAI API guide ✅
3. GPT-4 reference ✅
Clave: Keyword captura "GPT-4" exacto, Semantic captura concepto "API documentation".
📊 Benchmark: Pure Semantic vs Hybrid
Escenario: Technical Documentation RAG
Setup:
- Database: 100K technical docs
- Queries: 1000 test queries (mix de conceptual + specific)
- Metric: MRR (Mean Reciprocal Rank) + NDCG@10
Test A: Pure Semantic Search
results = db.query(
query_embedding=embed(query),
k=10
)
Resultados:
- Conceptual queries: 92% accuracy ✅
- Specific queries (names, IDs): 68% accuracy ❌
- Overall: 78% accuracy
Fallos típicos:
- "GPT-4 docs" → Devuelve GPT-3 docs
- "React 18 features" → Devuelve React general
- "Invoice #12345" → No encuentra
Test B: Pure Keyword Search (BM25)
results = bm25_search(query, k=10)
Resultados:
- Specific queries: 95% accuracy ✅
- Conceptual queries: 55% accuracy ❌
- Overall: 72% accuracy
Fallos típicos:
- "automobile repair" → No encuentra "car maintenance" (sinónimo)
- "password reset" → No encuentra "credential recovery" (concepto similar)
Test C: Hybrid Search (BM25 + Vector)
# Keyword results
keyword_results = bm25_search(query, k=20)
# Semantic results
semantic_results = db.query(
query_embedding=embed(query),
k=20
)
# Fusion (RRF)
final_results = reciprocal_rank_fusion(
[keyword_results, semantic_results],
k=10
)
Resultados:
- Conceptual queries: 91% accuracy ✅ (casi igual a pure semantic)
- Specific queries: 94% accuracy ✅ (casi igual a pure keyword)
- Overall: 92% accuracy ✅
Ganancia: 14% improvement vs pure semantic, 20% vs pure keyword.
🔧 Fusion Algorithms
1. Reciprocal Rank Fusion (RRF)
Definición: Asignar score basado en posición (rank) en cada lista.
Fórmula:
RRF_score(doc) = Σ (1 / (k + rank_i))
donde:
- k = constant (típicamente 60)
- rank_i = posición de doc en lista i (1-indexed)
Ejemplo:
Keyword results:
1. Doc A (rank=1)
2. Doc B (rank=2)
3. Doc C (rank=3)
Semantic results:
1. Doc B (rank=1)
2. Doc D (rank=2)
3. Doc A (rank=3)
RRF scores:
Doc A: 1/(60+1) + 1/(60+3) = 0.0164 + 0.0159 = 0.0323
Doc B: 1/(60+2) + 1/(60+1) = 0.0161 + 0.0164 = 0.0325 ← Highest
Doc C: 1/(60+3) + 0 = 0.0159
Doc D: 0 + 1/(60+2) = 0.0161
Final ranking: B, A, D, C
Ventajas:
- ✅ No requiere normalizar scores (solo ranks)
- ✅ Robusto a outliers (un score muy alto no domina)
- ✅ Simple de implementar
Desventajas:
- ❌ No considera magnitude de scores (solo posición)
- ❌ Puede penalizar docs con score alto pero rank bajo
Usado por: Weaviate (default)
2. Weighted Score Fusion
Definición: Combinar scores normalizados con pesos.
Fórmula:
Final_score(doc) = α × keyword_score + (1-α) × semantic_score
donde:
- α = peso para keyword (típicamente 0.3-0.7)
- keyword_score, semantic_score = normalizados [0,1]
Ejemplo:
Keyword results:
Doc A: score=0.9
Doc B: score=0.7
Doc C: score=0.5
Semantic results:
Doc A: score=0.6
Doc B: score=0.9
Doc D: score=0.8
Weighted (α=0.5):
Doc A: 0.5×0.9 + 0.5×0.6 = 0.75
Doc B: 0.5×0.7 + 0.5×0.9 = 0.80 ← Highest
Doc D: 0.5×0 + 0.5×0.8 = 0.40
Doc C: 0.5×0.5 + 0.5×0 = 0.25
Final ranking: B, A, D, C
Ventajas:
- ✅ Considera magnitude de scores
- ✅ Flexible (ajustar α según query type)
- ✅ Intuitivo
Desventajas:
- ❌ Requiere normalizar scores (BM25 y cosine similarity tienen ranges distintos)
- ❌ Sensible a outliers
Usado por: Pinecone (custom), Elasticsearch
RRF vs Weighted: ¿Cuál elegir?
| Criterio | RRF | Weighted |
|---|---|---|
| Simplicidad | ✅ Simple | ⚠️ Requiere normalización |
| Robustez | ✅ Robusto a outliers | ❌ Sensible |
| Flexibilidad | ❌ Fixed (no ajustable) | ✅ Ajustable (α) |
| Performance | ✅ Similar | ✅ Similar |
| Recomendado | Default (Weaviate) | Custom tuning (Pinecone) |
Recomendación: Empezar con RRF (simple, robusto). Ajustar a weighted si necesitas control fino.
🎯 Cuándo usar Hybrid vs Pure Semantic
Decision Tree
┌─────────────────────────────────────────┐
│ ¿Tu query contiene nombres propios, │
│ IDs, códigos, o términos muy │
│ específicos? │
└─────────────────────────────────────────┘
│
┌──────────┴──────────┐
│ │
Sí No
│ │
↓ ↓
┌──────────────┐ ┌─────────────────┐
│ Hybrid Search│ │ Pure Semantic │
│ (BM25 + Vec) │ │ (Vector only) │
└──────────────┘ └─────────────────┘
Ejemplos: Ejemplos:
- "GPT-4 docs" - "car repair"
- "Invoice #123" - "fix bug"
- "React 18" - "improve performance"
- "user_id: abc" - "reduce latency"
Casos de uso: Hybrid Search
1. Technical Documentation
Query: "Kubernetes 1.28 ingress"
→ Hybrid captura "Kubernetes 1.28" exacto + concepto "ingress"
2. E-commerce Product Search
Query: "Nike Air Max red size 10"
→ Hybrid captura "Nike Air Max" exacto + concepto "red shoes"
3. Legal Document Search
Query: "Case #2024-CV-12345"
→ Hybrid captura case number exacto
4. Code Search
Query: "def authenticate_user()"
→ Hybrid captura function name exacto
Casos de uso: Pure Semantic
1. Conceptual Queries
Query: "How to improve database performance?"
→ Semantic captura concepto (optimización, índices, caching)
2. Ambiguous Queries
Query: "fix connection issues"
→ Semantic captura múltiples interpretaciones (network, DB, API)
3. Synonyms Expected
Query: "automobile maintenance"
→ Semantic encuentra "car repair", "vehicle service"
🏭 Hybrid Search en Vector Databases
Weaviate (Hybrid Search nativo)
# Weaviate soporta hybrid search out-of-the-box
results = client.query.get("Document", ["content"])\
.with_hybrid(
query="GPT-4 API documentation",
alpha=0.5 # 0=pure keyword, 1=pure vector
)\
.with_limit(10)\
.do()
# Fusion: RRF (default)
Ventaja: Built-in, no custom code.
Pinecone + Keyword Search (Custom)
# Pinecone no tiene hybrid nativo
# Opción 1: Combinar con Elasticsearch
# 1. Keyword search en Elasticsearch
keyword_results = es.search(
index="docs",
body={"query": {"match": {"content": query}}}
)
# 2. Semantic search en Pinecone
semantic_results = pinecone_index.query(
vector=embed(query),
top_k=20
)
# 3. Fusion manual
final_results = weighted_fusion(keyword_results, semantic_results, alpha=0.5)
Desventaja: Requiere 2 sistemas (Pinecone + ES).
ChromaDB + BM25 (Custom implementation)
# ChromaDB no tiene hybrid nativo
# Implementar BM25 manual
from rank_bm25 import BM25Okapi
# 1. Index documents con BM25
corpus = [doc['content'] for doc in documents]
tokenized_corpus = [doc.split() for doc in corpus]
bm25 = BM25Okapi(tokenized_corpus)
# 2. Keyword search
tokenized_query = query.split()
keyword_scores = bm25.get_scores(tokenized_query)
# 3. Semantic search
semantic_results = collection.query(
query_embeddings=[embed(query)],
n_results=20
)
# 4. Fusion (RRF)
final_results = rrf_fusion(keyword_scores, semantic_results)
Desventaja: Requiere implementación custom.
📊 Impact en Accuracy: Ejemplo real
Escenario: API Documentation RAG
Dataset: 50K API documentation pages (OpenAI, Anthropic, AWS, Azure)
Test queries (100):
- 50 conceptual: "How to handle rate limits?"
- 50 specific: "GPT-4 turbo pricing"
Pure Semantic
Conceptual queries: 94% accuracy
Specific queries: 72% accuracy ← Falla en "GPT-4 turbo"
Overall: 83%
Hybrid (α=0.5)
Conceptual queries: 92% accuracy (similar)
Specific queries: 96% accuracy ← Mejora 24%
Overall: 94%
Ganancia: 11% overall, 24% en specific queries.
✅ Checklist de comprensión
Verifica que entendiste esta cápsula:
-
¿Por qué pure semantic search falla en "GPT-4 API docs"?
- Respuesta: Embedding captura concepto general "API documentation" pero no prioriza nombre exacto "GPT-4". Keyword search captura "GPT-4" exacto.
-
¿Qué es hybrid search?
- Respuesta: Combinar keyword search (BM25) + semantic search (vector) usando fusion algorithm (RRF o weighted).
-
¿Qué es RRF?
- Respuesta: Reciprocal Rank Fusion. Asigna score basado en posición (rank) en cada lista. Formula: 1/(60+rank).
-
¿Cuándo usar hybrid vs pure semantic?
- Respuesta: Hybrid si query tiene nombres propios, IDs, códigos. Pure semantic si query es conceptual/ambiguo.
-
¿Cuál es accuracy improvement típico de hybrid?
- Respuesta: 15-20% overall, 20-30% en specific queries.
Si respondiste 4-5/5 correctamente → ✅ Listo para Cápsula 04 (Multi-tenancy)
🔗 Conexión con RAG
¿Cómo hybrid search mejora tu RAG?
Caso A: Technical Docs Chatbot
Pure semantic:
User: "Show me Kubernetes 1.28 networking changes"
RAG: Devuelve Kubernetes networking general (mix de versiones)
LLM: Response contaminada con info de versiones viejas
Hybrid:
User: "Show me Kubernetes 1.28 networking changes"
RAG: Devuelve docs específicos de v1.28 (keyword match) + networking concepts
LLM: Response precisa y actualizada
Caso B: E-commerce Search
Pure semantic:
User: "Nike Air Jordan 1 Retro High OG"
RAG: Devuelve Nike shoes general (Jordan 1, 3, 4...)
Hybrid:
User: "Nike Air Jordan 1 Retro High OG"
RAG: Devuelve exactamente "Jordan 1 Retro High OG" (keyword match exacto)
🚀 Siguiente paso
Ya conoces las 2 features más críticas: Metadata filtering y Hybrid search. Ahora aprenderás feature #3 para SaaS: Multi-tenancy.
Próxima cápsula: 04 - Multi-tenancy (Aislamiento de datos)
Aprenderás:
- Estrategias de multi-tenancy (collection per tenant, metadata filtering, namespace)
- Security considerations (data leakage prevention)
- Performance trade-offs (scale horizontal vs vertical)
- Cuándo es crítico (SaaS, enterprise RAG)
Clave: Multi-tenancy es esencial para RAG SaaS (aislar datos por cliente).
Tiempo de lectura: 10-12 minutos
Siguiente: 04-multi-tenancy.md