Семантичний пошук знаходить документи за значенням, а не лише за ключовими словами. Замість точного співпадіння термінів, він використовує ембединги для представлення запитів та документів як векторів, потім знаходить схожі вектори. Це дозволяє "знайти документи про машинне навчання" матчити "туторіал зі штучного інтелекту" навіть без спільних слів.
Де це використовується
Семантичний пошук забезпечує сучасний information retrieval:
- Корпоративний пошук: Внутрішні документи, вікі, Slack повідомлення
- E-commerce: Пошук товарів поза keyword matching
- Підтримка: Пошук схожих тікетів, матчинг FAQ
- Юридична сфера: Судова практика та схожість документів
- Медицина: Пошук медичної літератури
- Пошук коду: Пошук схожих code snippets
Продукти: Google Search, Elasticsearch з векторами, Algolia, Pinecone, Weaviate.
Типові дані
| Аспект | Типові значення |
|---|---|
| Корпус документів | 10K-100M документів |
| Розмірність ембедингу | 384-1536 |
| Затримка запиту | 10-200 мс |
| Розмір індексу | GB-TB |
| Recall@10 ціль | 85%-95% |
Джерела даних: - Текстові документи (PDF, HTML, markdown) - Каталоги товарів з описами - Support тікети та розмови - Репозиторії коду - Структуровані дані з текстовими полями
Що ви робите на практиці
- Визначте scope - Що шукають користувачі? Що має матчитися?
- Оберіть embedding модель - Баланс якості, швидкості та вартості
- Preprocessing документів - Очистка, чанкінг, підготовка тексту
- Згенеруйте ембединги - Batch обробка корпусу документів
- Побудуйте індекс - Оберіть vector database, налаштуйте параметри
- Реалізуйте query pipeline - Обробка запиту, пошук, пост-обробка
- Додайте гібридний пошук - Комбінація семантичного з keyword
- Оцініть та тюньте - Виміряйте релевантність, налаштуйте параметри
- Моніторте продакшн - Відстежуйте latency, релевантність, використання
Спочатку бейзлайн
Почніть з BM25 keyword пошуку перед ембедингами:
from elasticsearch import Elasticsearch
es = Elasticsearch()
# BM25 бейзлайн
response = es.search(
index="documents",
body={
"query": {
"match": {
"content": user_query
}
}
}
)
Чому keyword бейзлайн: - Швидкий та добре зрозумілий - Добре працює для exact term запитів - Встановлює floor релевантності - Ідентифікує де семантичний додає цінність
Переходьте до семантичного коли: - Користувачі використовують різноманітну лексику - Потрібен synonym та concept matching - Самі keywords пропускають релевантні результати
Моделі ембедингів
| Модель | Розмірності | Якість | Швидкість | Вартість |
|---|---|---|---|---|
| OpenAI text-embedding-3-small | 1536 | Добра | Fast API | $$$ |
| OpenAI text-embedding-3-large | 3072 | Найкраща | Fast API | $$$$ |
| Cohere embed-v3 | 1024 | Добра | Fast API | $$$ |
| sentence-transformers (all-MiniLM) | 384 | Добра | Дуже швидка | Безкоштовно |
| GTE, BGE, E5 | 768-1024 | Добра | Швидка | Безкоштовно |
Критерії вибору: - Якість: Наскільки добре захоплює семантичну схожість? - Швидкість: Latency для real-time запитів - Вартість: API costs vs self-hosting - Приватність: Чи можуть дані покинути вашу інфраструктуру?
Приклад з sentence-transformers:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
# Encode документів (batch)
doc_embeddings = model.encode(documents, batch_size=32)
# Encode запиту (single)
query_embedding = model.encode(query)
# Схожість
from sklearn.metrics.pairwise import cosine_similarity
similarities = cosine_similarity([query_embedding], doc_embeddings)[0]
Архітектура векторного пошуку
Компоненти:
Документи → Чанкінг → Ембединг → Векторний індекс
↓
Запит → Query Embedding → ANN Search → Top-K → Реранкінг → Результати
Векторні бази даних:
| База даних | Тип | Масштабування | Примітки |
|---|---|---|---|
| Pinecone | Managed | Авто | Легко, production-ready |
| Weaviate | Self-hosted/cloud | Manual | Хороший гібридний пошук |
| Qdrant | Self-hosted/cloud | Manual | Швидкий, feature-rich |
| Milvus | Self-hosted | Складне | Високий масштаб |
| pgvector | PostgreSQL extension | З PG | Добре для меншого масштабу |
Типи індексів: - HNSW: Найкраща якість, більше пам'яті - IVF: Хороший баланс, налаштовуваний - Flat: Exact search, повільний для великих корпусів
Гібридний пошук
Комбінуйте семантичний та keyword пошук для найкращих результатів:
def hybrid_search(query, alpha=0.7):
"""Комбінація BM25 та vector search."""
# Keyword пошук
bm25_results = keyword_search(query)
bm25_scores = normalize(bm25_results)
# Семантичний пошук
query_embedding = embed(query)
vector_results = vector_search(query_embedding)
vector_scores = normalize(vector_results)
# Комбінування з reciprocal rank fusion
combined = reciprocal_rank_fusion(
[bm25_results, vector_results],
weights=[1-alpha, alpha]
)
return combined
def reciprocal_rank_fusion(result_lists, weights=None, k=60):
"""Злиття ranked lists з RRF."""
scores = defaultdict(float)
for i, results in enumerate(result_lists):
weight = weights[i] if weights else 1
for rank, doc_id in enumerate(results):
scores[doc_id] += weight * (1 / (k + rank + 1))
return sorted(scores.items(), key=lambda x: -x[1])
Коли використовувати гібрид: - Назви товарів та специфічні терміни (keyword допомагає) - Концептуальні запити (семантичний допомагає) - Змішані типи запитів у продакшні
Оцінка та метрики
| Метрика | Що вимірює | Як обчислити |
|---|---|---|
| Recall@k | Чи релевантні docs у топ k? | Частка релевантних у результатах |
| Precision@k | Чи топ k результати релевантні? | Частка результатів що релевантні |
| MRR | Позиція першого релевантного | 1/rank першого релевантного |
| NDCG | Якість ranked релевантності | DCG нормалізований по ідеалу |
Процес оцінки: 1. Створіть тестовий набір (100-500 запитів з мітками релевантності) 2. Запустіть запити через систему 3. Обчисліть метрики при k=5, 10, 20 4. Порівняйте з бейзлайнами 5. Аналізуйте failure cases
Інструменти: - BEIR benchmark для порівняння ембедингів - MTEB leaderboard для вибору моделі - Кастомна оцінка на ваших даних
Режими відмов та чеклист налагодження
- [ ] Якість ембедингів: Модель не захоплює доменну семантику
- [ ] Проблеми чанкінгу: Релевантна інфо розділена між чанками
- [ ] Query-document mismatch: Запити сформульовані інакше ніж документи
- [ ] Застарілий індекс: Нові документи не індексовані
- [ ] Сплески latency: Індекс не оптимізований
- [ ] Проблеми recall: Top-k замалий, неправильні параметри індексу
- [ ] Keyword залежність: Exact terms пропущені семантичним
Чеклист для продакшну
Перед деплоєм: - [ ] Embedding модель протестована на доменних даних - [ ] Стратегія чанкінгу валідована - [ ] Параметри індексу тюньнуті (ef, m для HNSW) - [ ] Баланс гібридного пошуку калібрований - [ ] Latency протестована при очікуваному навантаженні - [ ] Фолбек для помилок пошуку
Після деплою: - [ ] Query latency моніториться (p50, p99) - [ ] Relevance feedback збирається - [ ] Свіжість індексу підтримується - [ ] No-result запити аналізуються - [ ] Версія embedding моделі відстежується
Масштабування: - [ ] Batch генерація ембедингів - [ ] Кешування query ембедингів для повторюваних запитів - [ ] Шардінг індексу для великих корпусів - [ ] Реплікація для high availability
Реранкінг
Two-stage архітектура для якості:
def search_with_reranking(query, top_k=10, rerank_k=100):
"""Швидкий ретривал потім точний реранкінг."""
# Етап 1: Швидкий vector search
candidates = vector_search(query, k=rerank_k)
# Етап 2: Cross-encoder реранкінг
pairs = [(query, doc.text) for doc in candidates]
rerank_scores = cross_encoder.predict(pairs)
# Комбінувати та сортувати
reranked = sorted(
zip(candidates, rerank_scores),
key=lambda x: -x[1]
)[:top_k]
return reranked
Моделі реранкінгу: - Cross-encoders (точніші, повільніші) - Cohere Rerank API - BGE Reranker - Кастомні fine-tuned моделі
Інструменти та стек
| Категорія | Інструменти |
|---|---|
| Embedding моделі | OpenAI, Cohere, sentence-transformers |
| Векторні бази | Pinecone, Weaviate, Qdrant, pgvector |
| Гібридний пошук | Elasticsearch 8+, Weaviate |
| Реранкери | Cohere Rerank, cross-encoders |
| Оцінка | BEIR, кастомні метрики |
Приклад міні-кейсу
Сценарій: Підприємство потребує пошук серед 500K внутрішніх документів (Confluence, Google Docs, Slack).
Підхід: 1. Бейзлайн: Elasticsearch BM25 - Recall@10: 0.62 2. Чанкінг: 400 токенів з overlap, зберегти заголовки 3. Ембединги: OpenAI text-embedding-3-small 4. Індекс: Pinecone з metadata фільтрами 5. Гібрид: 70% семантичний, 30% BM25 6. Реранкінг: Cohere Rerank на топ 50
Результати: - Recall@10: 0.62 → 0.84 (+35%) - Query latency: 180ms (в межах SLA) - Задоволеність користувачів: +40% в опитуваннях
Ключові рішення: - Metadata фільтри критичні для access control - Гібридний пошук краще обробляв назви товарів - Реранкінг вартий latency cost для складних запитів
Пов'язані сторінки
- Індекс: ML Field Guide
- Learning to Rank
- Системи RAG
- Класифікація тексту в масштабі
Додаткове читання
Спробуйте наживо
Дослідіть пов'язану модель на практиці: відкрийте Word Embeddings Explorer - NLP Vector Space Visualization і змінюйте параметри під час роботи. Усе лишається у вашому браузері.
▶ Відкрити симуляцію Word Embeddings Explorer - NLP Vector Space Visualization